Merge from Chromium at DEPS revision r190564
This commit was generated by merge_to_master.py.
Change-Id: Icadecbce29854b8fa25fd335b2c1949b5ca5d170
diff --git a/ppapi/shared_impl/DEPS b/ppapi/shared_impl/DEPS
index 823b983..9f93141 100644
--- a/ppapi/shared_impl/DEPS
+++ b/ppapi/shared_impl/DEPS
@@ -14,4 +14,7 @@
"-ppapi/cpp",
"-ppapi/proxy",
+
+ # For testing purpose.
+ "+ppapi/proxy/ppapi_proxy_test.h",
]
diff --git a/ppapi/shared_impl/api_id.h b/ppapi/shared_impl/api_id.h
index 360b8cb..00706bf 100644
--- a/ppapi/shared_impl/api_id.h
+++ b/ppapi/shared_impl/api_id.h
@@ -24,7 +24,6 @@
API_ID_PPB_FILE_IO,
API_ID_PPB_FILE_REF,
API_ID_PPB_FILE_SYSTEM,
- API_ID_PPB_FLASH,
API_ID_PPB_FLASH_DEVICE_ID,
API_ID_PPB_FLASH_FONTFILE,
API_ID_PPB_FLASH_MENU,
diff --git a/ppapi/shared_impl/array_var.cc b/ppapi/shared_impl/array_var.cc
new file mode 100644
index 0000000..def1bb5
--- /dev/null
+++ b/ppapi/shared_impl/array_var.cc
@@ -0,0 +1,83 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/array_var.h"
+
+#include <limits>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+ArrayVar::ArrayVar() {
+}
+
+ArrayVar::~ArrayVar() {
+}
+
+// static
+ArrayVar* ArrayVar::FromPPVar(const PP_Var& var) {
+ if (var.type != PP_VARTYPE_ARRAY)
+ return NULL;
+
+ scoped_refptr<Var> var_object(
+ PpapiGlobals::Get()->GetVarTracker()->GetVar(var));
+ if (!var_object.get())
+ return NULL;
+ return var_object->AsArrayVar();
+}
+
+ArrayVar* ArrayVar::AsArrayVar() {
+ return this;
+}
+
+PP_VarType ArrayVar::GetType() const {
+ return PP_VARTYPE_ARRAY;
+}
+
+PP_Var ArrayVar::Get(uint32_t index) const {
+ if (index >= elements_.size())
+ return PP_MakeUndefined();
+
+ const PP_Var& element = elements_[index].get();
+ if (PpapiGlobals::Get()->GetVarTracker()->AddRefVar(element))
+ return element;
+ else
+ return PP_MakeUndefined();
+}
+
+PP_Bool ArrayVar::Set(uint32_t index, const PP_Var& value) {
+ if (index == std::numeric_limits<uint32_t>::max())
+ return PP_FALSE;
+
+ if (index >= elements_.size()) {
+ // Insert ScopedPPVars of type PP_VARTYPE_UNDEFINED to reach the new size
+ // (index + 1).
+ elements_.resize(index + 1);
+ }
+
+ elements_[index] = value;
+ return PP_TRUE;
+}
+
+uint32_t ArrayVar::GetLength() const {
+ if (elements_.size() > std::numeric_limits<uint32_t>::max()) {
+ CHECK(false);
+ return 0;
+ }
+
+ return static_cast<uint32_t>(elements_.size());
+}
+
+PP_Bool ArrayVar::SetLength(uint32_t length) {
+ // If |length| is larger than the current size, ScopedPPVars of type
+ // PP_VARTYPE_UNDEFINED will be inserted to reach the new length.
+ elements_.resize(length);
+ return PP_TRUE;
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/array_var.h b/ppapi/shared_impl/array_var.h
new file mode 100644
index 0000000..1214d87
--- /dev/null
+++ b/ppapi/shared_impl/array_var.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_SHARED_IMPL_ARRAY_VAR_H_
+#define PPAPI_SHARED_IMPL_ARRAY_VAR_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+
+class PPAPI_SHARED_EXPORT ArrayVar : public Var {
+ public:
+ typedef std::vector<ScopedPPVar> ElementVector;
+
+ ArrayVar();
+
+ // Helper function that converts a PP_Var to an ArrayVar. This will return
+ // NULL if the PP_Var is not of type PP_VARTYPE_ARRAY or the array cannot be
+ // found from the var tracker.
+ static ArrayVar* FromPPVar(const PP_Var& var);
+
+ // Var overrides.
+ virtual ArrayVar* AsArrayVar() OVERRIDE;
+ virtual PP_VarType GetType() const OVERRIDE;
+
+ // The returned PP_Var has had a ref added on behalf of the caller.
+ PP_Var Get(uint32_t index) const;
+ PP_Bool Set(uint32_t index, const PP_Var& value);
+ uint32_t GetLength() const;
+ PP_Bool SetLength(uint32_t length);
+
+ const ElementVector& elements() const {
+ return elements_;
+ }
+
+ ElementVector& elements() {
+ return elements_;
+ }
+
+ protected:
+ virtual ~ArrayVar();
+
+ private:
+ ElementVector elements_;
+
+ DISALLOW_COPY_AND_ASSIGN(ArrayVar);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_ARRAY_VAR_H_
diff --git a/ppapi/shared_impl/array_writer.cc b/ppapi/shared_impl/array_writer.cc
index 957ff77..26ee1bd 100644
--- a/ppapi/shared_impl/array_writer.cc
+++ b/ppapi/shared_impl/array_writer.cc
@@ -9,6 +9,8 @@
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
namespace ppapi {
@@ -76,4 +78,52 @@
return true;
}
+bool ArrayWriter::StoreVarVector(
+ const std::vector< scoped_refptr<Var> >& input) {
+ // Always call the alloc function, even on 0 array size.
+ void* dest = pp_array_output_.GetDataBuffer(
+ pp_array_output_.user_data,
+ static_cast<uint32_t>(input.size()),
+ sizeof(PP_Var));
+
+ // Regardless of success, we clear the output to prevent future calls on
+ // this same output object.
+ Reset();
+
+ if (input.empty())
+ return true; // Allow plugin to return NULL on 0 elements.
+ if (!dest)
+ return false;
+
+ // Convert to PP_Vars.
+ PP_Var* dest_vars = static_cast<PP_Var*>(dest);
+ for (size_t i = 0; i < input.size(); i++)
+ dest_vars[i] = input[i]->GetPPVar();
+ return true;
+}
+
+bool ArrayWriter::StoreVarVector(const std::vector<PP_Var>& input) {
+ // Always call the alloc function, even on 0 array size.
+ void* dest = pp_array_output_.GetDataBuffer(
+ pp_array_output_.user_data,
+ static_cast<uint32_t>(input.size()),
+ sizeof(PP_Var));
+
+ // Regardless of success, we clear the output to prevent future calls on
+ // this same output object.
+ Reset();
+
+ if (input.empty())
+ return true; // Allow plugin to return NULL on 0 elements.
+ if (!dest) {
+ // Free the vars.
+ for (size_t i = 0; i < input.size(); i++)
+ PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(input[i]);
+ return false;
+ }
+
+ std::copy(input.begin(), input.end(), static_cast<PP_Var*>(dest));
+ return true;
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/array_writer.h b/ppapi/shared_impl/array_writer.h
index cabd0af..7e6c349 100644
--- a/ppapi/shared_impl/array_writer.h
+++ b/ppapi/shared_impl/array_writer.h
@@ -18,6 +18,7 @@
namespace ppapi {
class Resource;
+class Var;
// Holds a PP_ArrayWriter and provides helper functions for writing arrays
// to it. It also handles 0-initialization of the raw C struct and attempts
@@ -38,7 +39,8 @@
// Sets the array output back to its is_null() state.
void Reset();
- // Copies the given vector of data to the plugin output array.
+ // StoreArray() and StoreVector() copy the given array/vector of data to the
+ // plugin output array.
//
// Returns true on success, false if the plugin reported allocation failure.
// In either case, the object will become is_null() immediately after the
@@ -48,27 +50,35 @@
// want to transfer a reference only on success. Likewise, if you have a
// structure of PP_Vars or a struct that contains a PP_Resource, we need to
// make sure that the right thing happens with the ref on success and failure.
- template<typename T>
- bool StoreVector(const std::vector<T>& input) {
+ template <typename T>
+ bool StoreArray(const T* input, uint32_t count) {
// Always call the alloc function, even on 0 array size.
void* dest = pp_array_output_.GetDataBuffer(
pp_array_output_.user_data,
- static_cast<uint32_t>(input.size()),
+ count,
sizeof(T));
// Regardless of success, we clear the output to prevent future calls on
// this same output object.
Reset();
- if (input.empty())
+ if (count == 0)
return true; // Allow plugin to return NULL on 0 elements.
if (!dest)
return false;
- memcpy(dest, &input[0], sizeof(T) * input.size());
+ if (input)
+ memcpy(dest, input, sizeof(T) * count);
return true;
}
+ // Copies the given array/vector of data to the plugin output array. See
+ // comment of StoreArray() for detail.
+ template<typename T>
+ bool StoreVector(const std::vector<T>& input) {
+ return StoreArray(input.size() ? &input[0] : NULL, input.size());
+ }
+
// Stores the given vector of resources as PP_Resources to the output vector,
// adding one reference to each.
//
@@ -80,13 +90,25 @@
// Note: potentially this could be a template in case you have a vector of
// FileRef objects, for example. However, this saves code since there's only
// one instantiation and is sufficient for now.
- bool StoreResourceVector(
- const std::vector< scoped_refptr<Resource> >& input);
+ bool StoreResourceVector(const std::vector< scoped_refptr<Resource> >& input);
- // Like the above version but takes an array of AddRed'ed PP_Resources. On
+ // Like the above version but takes an array of AddRef'ed PP_Resources. On
// storage failure, this will release each resource.
bool StoreResourceVector(const std::vector<PP_Resource>& input);
+ // Stores the given vector of vars as PP_Vars to the output vector,
+ // adding one reference to each.
+ //
+ // On failure this returns false, nothing will be copied, and the var
+ // refcounts will be unchanged. In either case, the object will become
+ // is_null() immediately after the call since one output function should only
+ // be issued once.
+ bool StoreVarVector(const std::vector< scoped_refptr<Var> >& input);
+
+ // Like the above version but takes an array of AddRef'ed PP_Vars. On
+ // storage failure, this will release each var.
+ bool StoreVarVector(const std::vector<PP_Var>& input);
+
private:
PP_ArrayOutput pp_array_output_;
diff --git a/ppapi/shared_impl/dictionary_var.cc b/ppapi/shared_impl/dictionary_var.cc
new file mode 100644
index 0000000..f7af7d9
--- /dev/null
+++ b/ppapi/shared_impl/dictionary_var.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/dictionary_var.h"
+
+#include "base/memory/ref_counted.h"
+#include "base/string_util.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+DictionaryVar::DictionaryVar() {
+}
+
+DictionaryVar::~DictionaryVar() {
+}
+
+// static
+DictionaryVar* DictionaryVar::FromPPVar(const PP_Var& var) {
+ if (var.type != PP_VARTYPE_DICTIONARY)
+ return NULL;
+
+ scoped_refptr<Var> var_object(
+ PpapiGlobals::Get()->GetVarTracker()->GetVar(var));
+ if (!var_object.get())
+ return NULL;
+ return var_object->AsDictionaryVar();
+}
+
+DictionaryVar* DictionaryVar::AsDictionaryVar() {
+ return this;
+}
+
+PP_VarType DictionaryVar::GetType() const {
+ return PP_VARTYPE_DICTIONARY;
+}
+
+PP_Var DictionaryVar::Get(const PP_Var& key) const {
+ StringVar* string_var = StringVar::FromPPVar(key);
+ if (!string_var)
+ return PP_MakeUndefined();
+
+ KeyValueMap::const_iterator iter = key_value_map_.find(string_var->value());
+ if (iter != key_value_map_.end()) {
+ if (PpapiGlobals::Get()->GetVarTracker()->AddRefVar(iter->second.get()))
+ return iter->second.get();
+ else
+ return PP_MakeUndefined();
+ } else {
+ return PP_MakeUndefined();
+ }
+}
+
+PP_Bool DictionaryVar::Set(const PP_Var& key, const PP_Var& value) {
+ StringVar* string_var = StringVar::FromPPVar(key);
+ if (!string_var)
+ return PP_FALSE;
+
+ key_value_map_[string_var->value()] = value;
+ return PP_TRUE;
+}
+
+void DictionaryVar::Delete(const PP_Var& key) {
+ StringVar* string_var = StringVar::FromPPVar(key);
+ if (!string_var)
+ return;
+
+ key_value_map_.erase(string_var->value());
+}
+
+PP_Bool DictionaryVar::HasKey(const PP_Var& key) const {
+ StringVar* string_var = StringVar::FromPPVar(key);
+ if (!string_var)
+ return PP_FALSE;
+
+ bool result =
+ key_value_map_.find(string_var->value()) != key_value_map_.end();
+ return PP_FromBool(result);
+}
+
+PP_Var DictionaryVar::GetKeys() const {
+ scoped_refptr<ArrayVar> array_var(new ArrayVar());
+ array_var->elements().reserve(key_value_map_.size());
+
+ for (KeyValueMap::const_iterator iter = key_value_map_.begin();
+ iter != key_value_map_.end(); ++iter) {
+ array_var->elements().push_back(
+ ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(iter->first)));
+ }
+ return array_var->GetPPVar();
+}
+
+bool DictionaryVar::SetWithStringKey(const std::string& utf8_key,
+ const PP_Var& value) {
+ if (!IsStringUTF8(utf8_key))
+ return false;
+
+ key_value_map_[utf8_key] = value;
+ return true;
+}
+
+void DictionaryVar::DeleteWithStringKey(const std::string& utf8_key) {
+ key_value_map_.erase(utf8_key);
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/dictionary_var.h b/ppapi/shared_impl/dictionary_var.h
new file mode 100644
index 0000000..cdc63bd
--- /dev/null
+++ b/ppapi/shared_impl/dictionary_var.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_SHARED_IMPL_DICTIONARY_VAR_H_
+#define PPAPI_SHARED_IMPL_DICTIONARY_VAR_H_
+
+#include <map>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+
+class PPAPI_SHARED_EXPORT DictionaryVar : public Var {
+ public:
+ typedef std::map<std::string, ScopedPPVar> KeyValueMap;
+
+ DictionaryVar();
+
+ // Helper function that converts a PP_Var to a DictionaryVar. This will
+ // return NULL if the PP_Var is not of type PP_VARTYPE_DICTIONARY or the
+ // dictionary cannot be found from the var tracker.
+ static DictionaryVar* FromPPVar(const PP_Var& var);
+
+ // Var overrides.
+ virtual DictionaryVar* AsDictionaryVar() OVERRIDE;
+ virtual PP_VarType GetType() const OVERRIDE;
+
+ // The returned PP_Var has had a ref added on behalf of the caller.
+ PP_Var Get(const PP_Var& key) const;
+ PP_Bool Set(const PP_Var& key, const PP_Var& value);
+ void Delete(const PP_Var& key);
+ PP_Bool HasKey(const PP_Var& key) const;
+ // The returned PP_Var has had a ref added on behalf of the caller.
+ PP_Var GetKeys() const;
+
+ // Returns false and keeps the dictionary unchanged if |key| is not a valid
+ // UTF-8 string.
+ bool SetWithStringKey(const std::string& utf8_key, const PP_Var& value);
+ void DeleteWithStringKey(const std::string& utf8_key);
+
+ const KeyValueMap& key_value_map() const {
+ return key_value_map_;
+ }
+
+ protected:
+ virtual ~DictionaryVar();
+
+ private:
+ KeyValueMap key_value_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(DictionaryVar);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_DICTIONARY_VAR_H_
diff --git a/ppapi/shared_impl/dir_contents.h b/ppapi/shared_impl/dir_contents.h
index 98c29f3..4d895b5 100644
--- a/ppapi/shared_impl/dir_contents.h
+++ b/ppapi/shared_impl/dir_contents.h
@@ -8,12 +8,12 @@
#include <vector>
-#include "base/file_path.h"
+#include "base/files/file_path.h"
namespace ppapi {
struct DirEntry {
- FilePath name;
+ base::FilePath name;
bool is_dir;
};
diff --git a/ppapi/shared_impl/file_io_state_manager.cc b/ppapi/shared_impl/file_io_state_manager.cc
new file mode 100644
index 0000000..9c9b6ea
--- /dev/null
+++ b/ppapi/shared_impl/file_io_state_manager.cc
@@ -0,0 +1,56 @@
+// 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/shared_impl/file_io_state_manager.h"
+
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+
+namespace ppapi {
+
+FileIOStateManager::FileIOStateManager()
+ : num_pending_ops_(0),
+ pending_op_(OPERATION_NONE),
+ file_open_(false) {
+}
+
+FileIOStateManager::~FileIOStateManager() {
+}
+
+void FileIOStateManager::SetOpenSucceed() {
+ file_open_ = true;
+}
+
+int32_t FileIOStateManager::CheckOperationState(OperationType new_op,
+ bool should_be_open) {
+ if (should_be_open) {
+ if (!file_open_)
+ return PP_ERROR_FAILED;
+ } else {
+ if (file_open_)
+ return PP_ERROR_FAILED;
+ }
+
+ if (pending_op_ != OPERATION_NONE &&
+ (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE))
+ return PP_ERROR_INPROGRESS;
+
+ return PP_OK;
+}
+
+void FileIOStateManager::SetPendingOperation(OperationType new_op) {
+ DCHECK(pending_op_ == OPERATION_NONE ||
+ (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == new_op));
+ pending_op_ = new_op;
+ num_pending_ops_++;
+}
+
+void FileIOStateManager::SetOperationFinished() {
+ DCHECK_GT(num_pending_ops_, 0);
+ if (--num_pending_ops_ == 0)
+ pending_op_ = OPERATION_NONE;
+}
+
+} // namespace ppapi
+
diff --git a/ppapi/shared_impl/file_io_state_manager.h b/ppapi/shared_impl/file_io_state_manager.h
new file mode 100644
index 0000000..7b5f926
--- /dev/null
+++ b/ppapi/shared_impl/file_io_state_manager.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_
+#define PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace ppapi {
+
+// FileIOStateManager is a helper class that maintains the state of operations.
+// For example, some operations are mutually exclusive, meaning that an
+// operation could be rejected because of the current pending operation. Also,
+// most of the operations only work when the file has been opened.
+class PPAPI_SHARED_EXPORT FileIOStateManager {
+ public:
+ FileIOStateManager();
+ ~FileIOStateManager();
+
+ enum OperationType {
+ // There is no pending operation right now.
+ OPERATION_NONE,
+
+ // If there are pending reads, any other kind of async operation is not
+ // allowed.
+ OPERATION_READ,
+
+ // If there are pending writes, any other kind of async operation is not
+ // allowed.
+ OPERATION_WRITE,
+
+ // If there is a pending operation that is neither read nor write, no
+ // further async operation is allowed.
+ OPERATION_EXCLUSIVE
+ };
+
+ OperationType get_pending_operation() const { return pending_op_; }
+
+ void SetOpenSucceed();
+
+ // Called at the beginning of each operation. It is responsible to make sure
+ // that state is correct. For example, some operations are only valid after
+ // the file is opened, or operations might need to run exclusively.
+ //
+ // It returns |PP_OK| on success, or |PP_ERROR_...| for various reasons.
+ int32_t CheckOperationState(OperationType new_op, bool should_be_open);
+
+ // Marks the state of current operations as started or finished.
+ void SetPendingOperation(OperationType op);
+ void SetOperationFinished();
+
+ private:
+ int num_pending_ops_;
+ OperationType pending_op_;
+
+ // Set to true when the file has been successfully opened.
+ bool file_open_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileIOStateManager);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_FILE_IO_STATE_MANAGER_H_
+
diff --git a/ppapi/shared_impl/file_path.cc b/ppapi/shared_impl/file_path.cc
index 1208b08..d05b1b3 100644
--- a/ppapi/shared_impl/file_path.cc
+++ b/ppapi/shared_impl/file_path.cc
@@ -4,48 +4,17 @@
#include "ppapi/shared_impl/file_path.h"
-#include <string>
-
-#if defined(OS_WIN)
-#include "base/utf_string_conversions.h"
-#endif
-
namespace ppapi {
-namespace {
-
-FilePath GetFilePathFromUTF8(const std::string& utf8_path) {
-#if defined(OS_WIN)
- return FilePath(UTF8ToUTF16(utf8_path));
-#else
- return FilePath(utf8_path);
-#endif
-}
-
-} // namespace
-
PepperFilePath::PepperFilePath()
: domain_(DOMAIN_INVALID),
path_() {
}
-PepperFilePath::PepperFilePath(Domain domain, const FilePath& path)
+PepperFilePath::PepperFilePath(Domain domain, const base::FilePath& path)
: domain_(domain),
path_(path) {
// TODO(viettrungluu): Should we DCHECK() some things here?
}
-// static
-PepperFilePath PepperFilePath::MakeAbsolute(const FilePath& path) {
- return PepperFilePath(DOMAIN_ABSOLUTE, path);
-}
-
-// static
-PepperFilePath PepperFilePath::MakeModuleLocal(const std::string& name,
- const char* utf8_path) {
- FilePath full_path = GetFilePathFromUTF8(name).Append(
- GetFilePathFromUTF8(utf8_path));
- return PepperFilePath(DOMAIN_MODULE_LOCAL, full_path);
-}
-
} // namespace ppapi
diff --git a/ppapi/shared_impl/file_path.h b/ppapi/shared_impl/file_path.h
index bcec9f8..7027e81 100644
--- a/ppapi/shared_impl/file_path.h
+++ b/ppapi/shared_impl/file_path.h
@@ -5,9 +5,7 @@
#ifndef PPAPI_SHARED_IMPL_FILE_PATH_H_
#define PPAPI_SHARED_IMPL_FILE_PATH_H_
-#include <string>
-
-#include "base/file_path.h"
+#include "base/files/file_path.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
namespace ppapi {
@@ -28,18 +26,14 @@
};
PepperFilePath();
- PepperFilePath(Domain d, const FilePath& p);
-
- static PepperFilePath MakeAbsolute(const FilePath& path);
- static PepperFilePath MakeModuleLocal(const std::string& name,
- const char* utf8_path);
+ PepperFilePath(Domain d, const base::FilePath& p);
Domain domain() const { return domain_; }
- const FilePath& path() const { return path_; }
+ const base::FilePath& path() const { return path_; }
private:
Domain domain_;
- FilePath path_;
+ base::FilePath path_;
};
} // namespace ppapi
diff --git a/ppapi/shared_impl/file_type_conversion.cc b/ppapi/shared_impl/file_type_conversion.cc
index a9bd435..5185daa 100644
--- a/ppapi/shared_impl/file_type_conversion.cc
+++ b/ppapi/shared_impl/file_type_conversion.cc
@@ -26,6 +26,8 @@
return PP_ERROR_NOSPACE;
case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY:
return PP_ERROR_FAILED;
+ case base::PLATFORM_FILE_ERROR_NOT_A_FILE:
+ return PP_ERROR_NOTAFILE;
default:
return PP_ERROR_FAILED;
}
diff --git a/ppapi/shared_impl/host_resource.h b/ppapi/shared_impl/host_resource.h
index c98d2d6..3645edc 100644
--- a/ppapi/shared_impl/host_resource.h
+++ b/ppapi/shared_impl/host_resource.h
@@ -15,7 +15,10 @@
// The point is to prevent mistakes where the wrong resource value is sent.
// Resource values are remapped in the plugin so that it can talk to multiple
// hosts. If all values were PP_Resource, it would be easy to forget to do
-// this tranformation.
+// this transformation.
+//
+// To get the corresponding plugin PP_Resource for a HostResource, use
+// PluginResourceTracker::PluginResourceForHostResource().
//
// All HostResources respresent IDs valid in the host.
class PPAPI_SHARED_EXPORT HostResource {
diff --git a/ppapi/shared_impl/ppapi_globals.cc b/ppapi/shared_impl/ppapi_globals.cc
index 270d7e8..be10d4c 100644
--- a/ppapi/shared_impl/ppapi_globals.cc
+++ b/ppapi/shared_impl/ppapi_globals.cc
@@ -26,7 +26,7 @@
main_loop_proxy_ = base::MessageLoopProxy::current();
}
-PpapiGlobals::PpapiGlobals(ForTest) {
+PpapiGlobals::PpapiGlobals(PerThreadForTest) {
DCHECK(!ppapi_globals_);
main_loop_proxy_ = base::MessageLoopProxy::current();
}
diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h
index b03d35c..84b90e7 100644
--- a/ppapi/shared_impl/ppapi_globals.h
+++ b/ppapi/shared_impl/ppapi_globals.h
@@ -10,9 +10,9 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_local.h" // For testing purposes only.
-#include "ppapi/c/dev/ppb_console_dev.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
+#include "ppapi/c/ppb_console.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
@@ -43,8 +43,8 @@
// purposes. This avoids setting the global static ppapi_globals_. For unit
// tests that use this feature, the "test" PpapiGlobals should be constructed
// using this method. See SetPpapiGlobalsOnThreadForTest for more information.
- struct ForTest {};
- explicit PpapiGlobals(ForTest);
+ struct PerThreadForTest {};
+ explicit PpapiGlobals(PerThreadForTest);
virtual ~PpapiGlobals();
@@ -64,7 +64,7 @@
// the same process, e.g. for having 1 thread emulate the "host" and 1 thread
// emulate the "plugin".
//
- // PpapiGlobals object must have been constructed using the "ForTest"
+ // PpapiGlobals object must have been constructed using the "PerThreadForTest"
// parameter.
static void SetPpapiGlobalsOnThreadForTest(PpapiGlobals* ptr);
@@ -79,7 +79,7 @@
// Logs the given string to the JS console. If "source" is empty, the name of
// the current module will be used, if it can be determined.
virtual void LogWithSource(PP_Instance instance,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
const std::string& source,
const std::string& value) = 0;
@@ -92,7 +92,7 @@
// Note that in the plugin process, the module parameter is ignored since
// there is only one possible one.
virtual void BroadcastLogWithSource(PP_Module module,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
const std::string& source,
const std::string& value) = 0;
diff --git a/ppapi/shared_impl/ppapi_preferences.cc b/ppapi/shared_impl/ppapi_preferences.cc
index c7bb0cb..a3ac413 100644
--- a/ppapi/shared_impl/ppapi_preferences.cc
+++ b/ppapi/shared_impl/ppapi_preferences.cc
@@ -11,7 +11,8 @@
default_fixed_font_size(0),
number_of_cpu_cores(0),
is_3d_supported(true),
- is_stage3d_supported(false) {
+ is_stage3d_supported(false),
+ is_stage3d_baseline_supported(false) {
}
Preferences::Preferences(const webkit_glue::WebPreferences& prefs)
@@ -24,10 +25,12 @@
number_of_cpu_cores(prefs.number_of_cpu_cores),
is_3d_supported(prefs.flash_3d_enabled),
is_stage3d_supported(prefs.flash_stage3d_enabled),
+ is_stage3d_baseline_supported(prefs.flash_stage3d_baseline_enabled),
// This determines both if webgl is supported (experimental_webgl_enabled)
- // and if it runs in hardware (accelerated_plugins_enabled)
+ // and if it runs in hardware
+ // (accelerated_compositing_for_plugins_enabled)
is_webgl_supported(prefs.experimental_webgl_enabled &&
- prefs.accelerated_plugins_enabled) {
+ prefs.accelerated_compositing_for_plugins_enabled) {
}
Preferences::~Preferences() {
diff --git a/ppapi/shared_impl/ppapi_preferences.h b/ppapi/shared_impl/ppapi_preferences.h
index b098f55..dad7c0c 100644
--- a/ppapi/shared_impl/ppapi_preferences.h
+++ b/ppapi/shared_impl/ppapi_preferences.h
@@ -29,6 +29,7 @@
int number_of_cpu_cores;
bool is_3d_supported;
bool is_stage3d_supported;
+ bool is_stage3d_baseline_supported;
bool is_webgl_supported;
};
diff --git a/ppapi/shared_impl/ppb_device_ref_shared.h b/ppapi/shared_impl/ppb_device_ref_shared.h
index 895baa5..9ea367e 100644
--- a/ppapi/shared_impl/ppb_device_ref_shared.h
+++ b/ppapi/shared_impl/ppb_device_ref_shared.h
@@ -21,6 +21,12 @@
struct PPAPI_SHARED_EXPORT DeviceRefData {
DeviceRefData();
+ bool operator==(const DeviceRefData& other) const {
+ return type == other.type &&
+ name == other.name &&
+ id == other.id;
+ }
+
PP_DeviceType_Dev type;
std::string name;
std::string id;
diff --git a/ppapi/shared_impl/ppb_file_io_shared.cc b/ppapi/shared_impl/ppb_file_io_shared.cc
deleted file mode 100644
index b60e174..0000000
--- a/ppapi/shared_impl/ppb_file_io_shared.cc
+++ /dev/null
@@ -1,219 +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/shared_impl/ppb_file_io_shared.h"
-
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/file_type_conversion.h"
-#include "ppapi/shared_impl/time_conversion.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_file_ref_api.h"
-
-namespace ppapi {
-
-using thunk::EnterResourceNoLock;
-using thunk::PPB_FileIO_API;
-using thunk::PPB_FileRef_API;
-
-PPB_FileIO_Shared::CallbackEntry::CallbackEntry()
- : read_buffer(NULL),
- info(NULL) {
-}
-
-PPB_FileIO_Shared::CallbackEntry::CallbackEntry(const CallbackEntry& entry)
- : callback(entry.callback),
- read_buffer(entry.read_buffer),
- info(entry.info) {
-}
-
-PPB_FileIO_Shared::CallbackEntry::~CallbackEntry() {
-}
-
-PPB_FileIO_Shared::PPB_FileIO_Shared(PP_Instance instance)
- : Resource(OBJECT_IS_IMPL, instance),
- file_system_type_(PP_FILESYSTEMTYPE_INVALID),
- file_open_(false),
- pending_op_(OPERATION_NONE) {
-}
-
-PPB_FileIO_Shared::PPB_FileIO_Shared(const HostResource& host_resource)
- : Resource(OBJECT_IS_PROXY, host_resource),
- file_system_type_(PP_FILESYSTEMTYPE_INVALID),
- file_open_(false),
- pending_op_(OPERATION_NONE) {
-}
-
-PPB_FileIO_Shared::~PPB_FileIO_Shared() {
-}
-
-thunk::PPB_FileIO_API* PPB_FileIO_Shared::AsPPB_FileIO_API() {
- return this;
-}
-
-int32_t PPB_FileIO_Shared::Open(PP_Resource file_ref,
- int32_t open_flags,
- scoped_refptr<TrackedCallback> callback) {
- EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true);
- if (enter.failed())
- return PP_ERROR_BADRESOURCE;
-
- int32_t rv = CommonCallValidation(false, OPERATION_EXCLUSIVE);
- if (rv != PP_OK)
- return rv;
-
- PP_FileSystemType type = enter.object()->GetFileSystemType();
- if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
- type != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
- type != PP_FILESYSTEMTYPE_EXTERNAL)
- return PP_ERROR_FAILED;
- file_system_type_ = type;
-
- return OpenValidated(file_ref, enter.object(), open_flags, callback);
-}
-
-int32_t PPB_FileIO_Shared::Query(PP_FileInfo* info,
- scoped_refptr<TrackedCallback> callback) {
- int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
- if (rv != PP_OK)
- return rv;
- if (!info)
- return PP_ERROR_BADARGUMENT;
- return QueryValidated(info, callback);
-}
-
-int32_t PPB_FileIO_Shared::Touch(PP_Time last_access_time,
- PP_Time last_modified_time,
- scoped_refptr<TrackedCallback> callback) {
- int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
- if (rv != PP_OK)
- return rv;
- return TouchValidated(last_access_time, last_modified_time, callback);
-}
-
-int32_t PPB_FileIO_Shared::Read(int64_t offset,
- char* buffer,
- int32_t bytes_to_read,
- scoped_refptr<TrackedCallback> callback) {
- int32_t rv = CommonCallValidation(true, OPERATION_READ);
- if (rv != PP_OK)
- return rv;
- return ReadValidated(offset, buffer, bytes_to_read, callback);
-}
-
-int32_t PPB_FileIO_Shared::Write(int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- scoped_refptr<TrackedCallback> callback) {
- int32_t rv = CommonCallValidation(true, OPERATION_WRITE);
- if (rv != PP_OK)
- return rv;
- return WriteValidated(offset, buffer, bytes_to_write, callback);
-}
-
-int32_t PPB_FileIO_Shared::SetLength(int64_t length,
- scoped_refptr<TrackedCallback> callback) {
- int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
- if (rv != PP_OK)
- return rv;
- return SetLengthValidated(length, callback);
-}
-
-int32_t PPB_FileIO_Shared::Flush(scoped_refptr<TrackedCallback> callback) {
- int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
- if (rv != PP_OK)
- return rv;
- return FlushValidated(callback);
-}
-
-void PPB_FileIO_Shared::ExecuteGeneralCallback(int32_t pp_error) {
- RunAndRemoveFirstPendingCallback(pp_error);
-}
-
-void PPB_FileIO_Shared::ExecuteOpenFileCallback(int32_t pp_error) {
- if (pp_error == PP_OK)
- file_open_ = true;
- ExecuteGeneralCallback(pp_error);
-}
-
-void PPB_FileIO_Shared::ExecuteQueryCallback(int32_t pp_error,
- const PP_FileInfo& info) {
- if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty() ||
- !callbacks_.front().info) {
- NOTREACHED();
- return;
- }
- *callbacks_.front().info = info;
- RunAndRemoveFirstPendingCallback(pp_error);
-}
-
-void PPB_FileIO_Shared::ExecuteReadCallback(int32_t pp_error,
- const char* data) {
- if (pending_op_ != OPERATION_READ || callbacks_.empty()) {
- NOTREACHED();
- return;
- }
-
- // The result code contains the number of bytes if it's positive.
- if (pp_error > 0) {
- char* read_buffer = callbacks_.front().read_buffer;
- DCHECK(data);
- DCHECK(read_buffer);
- memcpy(read_buffer, data, pp_error);
- }
- RunAndRemoveFirstPendingCallback(pp_error);
-}
-
-int32_t PPB_FileIO_Shared::CommonCallValidation(bool should_be_open,
- OperationType new_op) {
- // Only asynchronous operation is supported.
- if (should_be_open) {
- if (!file_open_)
- return PP_ERROR_FAILED;
- } else {
- if (file_open_)
- return PP_ERROR_FAILED;
- }
-
- if (pending_op_ != OPERATION_NONE &&
- (pending_op_ != new_op || pending_op_ == OPERATION_EXCLUSIVE)) {
- return PP_ERROR_INPROGRESS;
- }
-
- return PP_OK;
-}
-
-void PPB_FileIO_Shared::RegisterCallback(
- OperationType op,
- scoped_refptr<TrackedCallback> callback,
- char* read_buffer,
- PP_FileInfo* info) {
- DCHECK(pending_op_ == OPERATION_NONE ||
- (pending_op_ != OPERATION_EXCLUSIVE && pending_op_ == op));
-
- CallbackEntry entry;
- entry.callback = callback;
- entry.read_buffer = read_buffer;
- entry.info = info;
- callbacks_.push_back(entry);
-
- pending_op_ = op;
-}
-
-void PPB_FileIO_Shared::RunAndRemoveFirstPendingCallback(int32_t result) {
- DCHECK(!callbacks_.empty());
-
- CallbackEntry front = callbacks_.front();
- callbacks_.pop_front();
- if (callbacks_.empty())
- pending_op_ = OPERATION_NONE;
-
- front.callback->Run(result);
-}
-
-} // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_file_io_shared.h b/ppapi/shared_impl/ppb_file_io_shared.h
deleted file mode 100644
index a062497..0000000
--- a/ppapi/shared_impl/ppb_file_io_shared.h
+++ /dev/null
@@ -1,156 +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.
-
-#ifndef PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_
-#define PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_
-
-#include <deque>
-
-#include "base/compiler_specific.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_file_io_api.h"
-
-namespace ppapi {
-
-namespace thunk {
-class PPB_FileRef_API;
-}
-
-class PPAPI_SHARED_EXPORT PPB_FileIO_Shared : public Resource,
- public thunk::PPB_FileIO_API {
- public:
- PPB_FileIO_Shared(PP_Instance instance);
- PPB_FileIO_Shared(const HostResource& host_resource);
- ~PPB_FileIO_Shared();
-
- // Resource overrides.
- virtual thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE;
-
- // PPB_FileIO_API implementation.
- virtual int32_t Open(PP_Resource file_ref,
- int32_t open_flags,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t Query(PP_FileInfo* info,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t Touch(PP_Time last_access_time,
- PP_Time last_modified_time,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t Read(int64_t offset,
- char* buffer,
- int32_t bytes_to_read,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t Write(int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t SetLength(int64_t length,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE;
-
- // Callback handler for different types of operations.
- void ExecuteGeneralCallback(int32_t pp_error);
- void ExecuteOpenFileCallback(int32_t pp_error);
- void ExecuteQueryCallback(int32_t pp_error, const PP_FileInfo& info);
- void ExecuteReadCallback(int32_t pp_error, const char* data);
-
- protected:
- struct CallbackEntry {
- CallbackEntry();
- CallbackEntry(const CallbackEntry& entry);
- ~CallbackEntry();
-
- scoped_refptr<TrackedCallback> callback;
-
- // Pointer back to the caller's read buffer; only used by |Read()|, NULL
- // for non-read operations. Not owned.
- char* read_buffer;
-
- // Pointer back to the caller's PP_FileInfo structure for Query operations.
- // NULL for non-query operations. Not owned.
- PP_FileInfo* info;
- };
-
- enum OperationType {
- // There is no pending operation right now.
- OPERATION_NONE,
-
- // If there are pending reads, any other kind of async operation is not
- // allowed.
- OPERATION_READ,
-
- // If there are pending writes, any other kind of async operation is not
- // allowed.
- OPERATION_WRITE,
-
- // If there is a pending operation that is neither read nor write, no
- // further async operation is allowed.
- OPERATION_EXCLUSIVE
- };
-
- // Validated versions of the FileIO API. Subclasses in the proxy and impl
- // implement these so the common error checking stays here.
- virtual int32_t OpenValidated(PP_Resource file_ref_resource,
- thunk::PPB_FileRef_API* file_ref_api,
- int32_t open_flags,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t QueryValidated(PP_FileInfo* info,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t TouchValidated(PP_Time last_access_time,
- PP_Time last_modified_time,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t ReadValidated(int64_t offset,
- char* buffer,
- int32_t bytes_to_read,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t WriteValidated(int64_t offset,
- const char* buffer,
- int32_t bytes_to_write,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t SetLengthValidated(
- int64_t length,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t FlushValidated(scoped_refptr<TrackedCallback> callback) = 0;
-
- // Called for every "Validated" function.
- //
- // This verifies that the callback is valid and that no callback is already
- // pending, or it is a read(write) request and currently the pending
- // operations are reads(writes).
- //
- // Returns |PP_OK| to indicate that everything is valid or |PP_ERROR_...| if
- // the call should be aborted and that code returned to the plugin.
- int32_t CommonCallValidation(bool should_be_open, OperationType new_op);
-
- // Sets up a pending callback. This should only be called once it is certain
- // that |PP_OK_COMPLETIONPENDING| will be returned.
- //
- // |read_buffer| is only used by read operations, |info| is used only by
- // query operations.
- void RegisterCallback(OperationType op,
- scoped_refptr<TrackedCallback> callback,
- char* read_buffer,
- PP_FileInfo* info);
-
- // Pops the oldest callback from the queue and runs it.
- void RunAndRemoveFirstPendingCallback(int32_t result);
-
- // The file system type specified in the Open() call. This will be
- // PP_FILESYSTEMTYPE_INVALID before open was called. This value does not
- // indicate that the open command actually succeeded.
- PP_FileSystemType file_system_type_;
-
- // Set to true when the file has been successfully opened.
- bool file_open_;
-
- std::deque<CallbackEntry> callbacks_;
- OperationType pending_op_;
-
- DISALLOW_COPY_AND_ASSIGN(PPB_FileIO_Shared);
-};
-
-} // namespace ppapi
-
-#endif // PPAPI_SHARED_IMPL_PPB_FILE_IO_SHARED_H_
diff --git a/ppapi/shared_impl/ppb_flash_shared.cc b/ppapi/shared_impl/ppb_flash_shared.cc
deleted file mode 100644
index c310e0e..0000000
--- a/ppapi/shared_impl/ppb_flash_shared.cc
+++ /dev/null
@@ -1,23 +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/shared_impl/ppb_flash_shared.h"
-
-namespace ppapi {
-
-PPB_Flash_Shared::PPB_Flash_Shared() {
-}
-
-PPB_Flash_Shared::~PPB_Flash_Shared() {
-}
-
-void PPB_Flash_Shared::FreeDirContents(PP_Instance instance,
- PP_DirContents_Dev* contents) {
- for (int32_t i = 0; i < contents->count; ++i)
- delete[] contents->entries[i].name;
- delete[] contents->entries;
- delete contents;
-}
-
-} // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_flash_shared.h b/ppapi/shared_impl/ppb_flash_shared.h
deleted file mode 100644
index 29f8973..0000000
--- a/ppapi/shared_impl/ppb_flash_shared.h
+++ /dev/null
@@ -1,30 +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.
-
-#ifndef PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_
-#define PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/thunk/ppb_flash_api.h"
-
-namespace ppapi {
-
-class PPAPI_SHARED_EXPORT PPB_Flash_Shared : public thunk::PPB_Flash_API {
- public:
- PPB_Flash_Shared();
- virtual ~PPB_Flash_Shared();
-
- // Shared implementation of PPB_Flash_API.
- virtual void FreeDirContents(PP_Instance instance,
- PP_DirContents_Dev* contents) OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PPB_Flash_Shared);
-};
-
-} // namespace ppapi
-
-#endif // PPAPI_SHARED_IMPL_PPB_FLASH_SHARED_H_
diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.cc b/ppapi/shared_impl/ppb_graphics_3d_shared.cc
index 0278c42..e2d0154 100644
--- a/ppapi/shared_impl/ppb_graphics_3d_shared.cc
+++ b/ppapi/shared_impl/ppb_graphics_3d_shared.cc
@@ -60,6 +60,8 @@
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.");
// Already a pending SwapBuffers that hasn't returned yet.
return PP_ERROR_INPROGRESS;
}
diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.h b/ppapi/shared_impl/ppb_graphics_3d_shared.h
index b6185f8..96bc6bb 100644
--- a/ppapi/shared_impl/ppb_graphics_3d_shared.h
+++ b/ppapi/shared_impl/ppb_graphics_3d_shared.h
@@ -99,6 +99,10 @@
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_instance_shared.cc b/ppapi/shared_impl/ppb_instance_shared.cc
index dd46bec..18033fc 100644
--- a/ppapi/shared_impl/ppb_instance_shared.cc
+++ b/ppapi/shared_impl/ppb_instance_shared.cc
@@ -6,6 +6,8 @@
#include <string>
+#include "base/debug/trace_event.h"
+#include "base/threading/platform_thread.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/shared_impl/ppapi_globals.h"
@@ -23,13 +25,13 @@
}
void PPB_Instance_Shared::Log(PP_Instance instance,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
PP_Var value) {
LogWithSource(instance, level, PP_MakeUndefined(), value);
}
void PPB_Instance_Shared::LogWithSource(PP_Instance instance,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
PP_Var source,
PP_Var value) {
// The source defaults to empty if it's not a string. The PpapiGlobals
diff --git a/ppapi/shared_impl/ppb_instance_shared.h b/ppapi/shared_impl/ppb_instance_shared.h
index a1845d3..61ca56d 100644
--- a/ppapi/shared_impl/ppb_instance_shared.h
+++ b/ppapi/shared_impl/ppb_instance_shared.h
@@ -19,10 +19,10 @@
// Implementation of some shared PPB_Instance_FunctionAPI functions.
virtual void Log(PP_Instance instance,
- PP_LogLevel_Dev log_level,
+ PP_LogLevel log_level,
PP_Var value) OVERRIDE;
virtual void LogWithSource(PP_Instance instance,
- PP_LogLevel_Dev log_level,
+ PP_LogLevel log_level,
PP_Var source,
PP_Var value) OVERRIDE;
diff --git a/ppapi/shared_impl/ppb_trace_event_impl.cc b/ppapi/shared_impl/ppb_trace_event_impl.cc
new file mode 100644
index 0000000..439bbd4
--- /dev/null
+++ b/ppapi/shared_impl/ppb_trace_event_impl.cc
@@ -0,0 +1,74 @@
+// 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/shared_impl/ppb_trace_event_impl.h"
+
+#include "base/debug/trace_event.h"
+#include "ppapi/thunk/thunk.h"
+
+
+namespace ppapi {
+
+// PPB_Trace_Event_Dev is a shared implementation because Trace Events can be
+// sent from either the plugin process or renderer process depending on whether
+// the plugin is in- or out-of-process. Also, for NaCl plugins these functions
+// will be executed from untrusted code and handled appropriately by tracing
+// functionality in the IRT.
+
+// static
+void* TraceEventImpl::GetCategoryEnabled(const char* category_name) {
+ // This casting is here because all mem_t return types in Pepper are void* and
+ // non-const. All mem_t parameters are const void* so there is no way to
+ // return a pointer type to the caller without some const_cast. The pointer
+ // type the tracing system works with is normally unsigned char*.
+ return const_cast<void*>(static_cast<const void*>(
+ base::debug::TraceLog::GetInstance()->GetCategoryEnabled(category_name)));
+}
+
+// static
+void TraceEventImpl::AddTraceEvent(int8_t phase,
+ const void* category_enabled,
+ const char* name,
+ uint64_t id,
+ uint32_t num_args,
+ const char* arg_names[],
+ const uint8_t arg_types[],
+ const uint64_t arg_values[],
+ uint8_t flags) {
+ base::debug::TraceLog::GetInstance()->AddTraceEvent(phase,
+ static_cast<const unsigned char*>(category_enabled), name, id, num_args,
+ arg_names, arg_types,
+ // This cast is necessary for LP64 systems, where uint64_t is defined as
+ // an unsigned long int, but trace_event internals are hermetic and
+ // accepts an |unsigned long long*|. The pointer types are compatible but
+ // the compiler throws an error without an explicit cast.
+ reinterpret_cast<const unsigned long long*>(arg_values), flags);
+}
+
+// static
+void TraceEventImpl::SetThreadName(const char* thread_name) {
+ base::PlatformThread::SetName(thread_name);
+}
+
+namespace {
+
+const PPB_Trace_Event_Dev g_ppb_trace_event_thunk = {
+ &TraceEventImpl::GetCategoryEnabled,
+ &TraceEventImpl::AddTraceEvent,
+ &TraceEventImpl::SetThreadName,
+};
+
+} // namespace ppapi
+
+} // namespace
+
+namespace ppapi {
+namespace thunk {
+
+const PPB_Trace_Event_Dev_0_1* GetPPB_Trace_Event_Dev_0_1_Thunk() {
+ return &g_ppb_trace_event_thunk;
+}
+
+} // namespace thunk
+} // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_trace_event_impl.h b/ppapi/shared_impl/ppb_trace_event_impl.h
new file mode 100644
index 0000000..21a77ac
--- /dev/null
+++ b/ppapi/shared_impl/ppb_trace_event_impl.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_PPB_TRACE_EVENT_IMPL_H_
+#define PPAPI_SHARED_IMPL_PPB_TRACE_EVENT_IMPL_H_
+
+#include "ppapi/c/dev/ppb_trace_event_dev.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace ppapi {
+
+// Contains the implementation of the PPB_Trace_Event_Dev functions. Since these
+// functions are to be run from whatever plugin process/thread in which they
+// originated, the implementation lives in shared_impl.
+//
+class PPAPI_SHARED_EXPORT TraceEventImpl {
+ public:
+ static void* GetCategoryEnabled(const char* category_name);
+ static void AddTraceEvent(int8_t phase,
+ const void* category_enabled,
+ const char* name,
+ uint64_t id,
+ uint32_t num_args,
+ const char* arg_names[],
+ const uint8_t arg_types[],
+ const uint64_t arg_values[],
+ uint8_t flags);
+ static void SetThreadName(const char* thread_name);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_PPB_TRACE_EVENT_IMPL_H_
diff --git a/ppapi/shared_impl/ppb_url_util_shared.cc b/ppapi/shared_impl/ppb_url_util_shared.cc
index f473530..7788f4a 100644
--- a/ppapi/shared_impl/ppb_url_util_shared.cc
+++ b/ppapi/shared_impl/ppb_url_util_shared.cc
@@ -6,6 +6,7 @@
#include "googleurl/src/gurl.h"
#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/shared_impl/var_tracker.h"
@@ -45,6 +46,7 @@
// static
PP_Var PPB_URLUtil_Shared::Canonicalize(PP_Var url,
PP_URLComponents_Dev* components) {
+ ProxyAutoLock lock;
StringVar* url_string = StringVar::FromPPVar(url);
if (!url_string)
return PP_MakeNull();
@@ -56,6 +58,7 @@
PP_Var base_url,
PP_Var relative,
PP_URLComponents_Dev* components) {
+ ProxyAutoLock lock;
StringVar* base_url_string = StringVar::FromPPVar(base_url);
StringVar* relative_string = StringVar::FromPPVar(relative);
if (!base_url_string || !relative_string)
@@ -70,6 +73,7 @@
// static
PP_Bool PPB_URLUtil_Shared::IsSameSecurityOrigin(PP_Var url_a, PP_Var url_b) {
+ ProxyAutoLock lock;
StringVar* url_a_string = StringVar::FromPPVar(url_a);
StringVar* url_b_string = StringVar::FromPPVar(url_b);
if (!url_a_string || !url_b_string)
diff --git a/ppapi/shared_impl/ppb_var_shared.cc b/ppapi/shared_impl/ppb_var_shared.cc
index 107058a..702a89a 100644
--- a/ppapi/shared_impl/ppb_var_shared.cc
+++ b/ppapi/shared_impl/ppb_var_shared.cc
@@ -24,17 +24,17 @@
// PPB_Var methods -------------------------------------------------------------
void AddRefVar(PP_Var var) {
- ppapi::ProxyAutoLock lock;
+ ProxyAutoLock lock;
PpapiGlobals::Get()->GetVarTracker()->AddRefVar(var);
}
void ReleaseVar(PP_Var var) {
- ppapi::ProxyAutoLock lock;
+ ProxyAutoLock lock;
PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var);
}
PP_Var VarFromUtf8(const char* data, uint32_t len) {
- ppapi::ProxyAutoLock lock;
+ ProxyAutoLock lock;
return StringVar::StringToPPVar(data, len);
}
@@ -43,7 +43,7 @@
}
const char* VarToUtf8(PP_Var var, uint32_t* len) {
- ppapi::ProxyAutoLock lock;
+ ProxyAutoLock lock;
StringVar* str = StringVar::FromPPVar(var);
if (str) {
*len = static_cast<uint32_t>(str->value().size());
@@ -71,11 +71,13 @@
// PPB_VarArrayBuffer methods --------------------------------------------------
PP_Var CreateArrayBufferVar(uint32_t size_in_bytes) {
+ ProxyAutoLock lock;
return PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
size_in_bytes);
}
PP_Bool ByteLength(PP_Var array, uint32_t* byte_length) {
+ ProxyAutoLock lock;
ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array);
if (!buffer)
return PP_FALSE;
@@ -84,6 +86,7 @@
}
void* Map(PP_Var array) {
+ ProxyAutoLock lock;
ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array);
if (!buffer)
return NULL;
@@ -91,6 +94,7 @@
}
void Unmap(PP_Var array) {
+ ProxyAutoLock lock;
ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array);
if (buffer)
buffer->Unmap();
diff --git a/ppapi/shared_impl/ppb_video_capture_shared.cc b/ppapi/shared_impl/ppb_video_capture_shared.cc
deleted file mode 100644
index 2a51b95..0000000
--- a/ppapi/shared_impl/ppb_video_capture_shared.cc
+++ /dev/null
@@ -1,187 +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/shared_impl/ppb_video_capture_shared.h"
-
-#include "base/logging.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/ppb_device_ref_shared.h"
-#include "ppapi/shared_impl/ppb_resource_array_shared.h"
-
-namespace ppapi {
-
-PPB_VideoCapture_Shared::PPB_VideoCapture_Shared(PP_Instance instance)
- : Resource(OBJECT_IS_IMPL, instance),
- open_state_(BEFORE_OPEN),
- status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
- devices_(NULL),
- resource_object_type_(OBJECT_IS_IMPL) {
-}
-
-PPB_VideoCapture_Shared::PPB_VideoCapture_Shared(
- const HostResource& host_resource)
- : Resource(OBJECT_IS_PROXY, host_resource),
- open_state_(BEFORE_OPEN),
- status_(PP_VIDEO_CAPTURE_STATUS_STOPPED),
- devices_(NULL),
- resource_object_type_(OBJECT_IS_PROXY) {
-}
-
-PPB_VideoCapture_Shared::~PPB_VideoCapture_Shared() {
-}
-
-thunk::PPB_VideoCapture_API* PPB_VideoCapture_Shared::AsPPB_VideoCapture_API() {
- return this;
-}
-
-int32_t PPB_VideoCapture_Shared::EnumerateDevices(
- PP_Resource* devices,
- scoped_refptr<TrackedCallback> callback) {
- if (TrackedCallback::IsPending(enumerate_devices_callback_))
- return PP_ERROR_INPROGRESS;
-
- return InternalEnumerateDevices(devices, callback);
-}
-
-int32_t PPB_VideoCapture_Shared::Open(
- const std::string& device_id,
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count,
- scoped_refptr<TrackedCallback> callback) {
- if (open_state_ != BEFORE_OPEN)
- return PP_ERROR_FAILED;
-
- if (TrackedCallback::IsPending(open_callback_))
- return PP_ERROR_INPROGRESS;
-
- return InternalOpen(device_id, requested_info, buffer_count, callback);
-}
-
-int32_t PPB_VideoCapture_Shared::StartCapture() {
- if (open_state_ != OPENED ||
- !SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false)) {
- return PP_ERROR_FAILED;
- }
-
- return InternalStartCapture();
-}
-
-int32_t PPB_VideoCapture_Shared::ReuseBuffer(uint32_t buffer) {
- return InternalReuseBuffer(buffer);
-}
-
-int32_t PPB_VideoCapture_Shared::StopCapture() {
- if (open_state_ != OPENED ||
- !SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, false)) {
- return PP_ERROR_FAILED;
- }
-
- return InternalStopCapture();
-}
-
-void PPB_VideoCapture_Shared::Close() {
- if (open_state_ == CLOSED)
- return;
-
- InternalClose();
- open_state_ = CLOSED;
-
- if (TrackedCallback::IsPending(open_callback_))
- open_callback_->PostAbort();
-}
-
-int32_t PPB_VideoCapture_Shared::StartCapture0_1(
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count) {
- if (open_state_ == BEFORE_OPEN) {
- if (TrackedCallback::IsPending(open_callback_))
- return PP_ERROR_FAILED;
- open_state_ = OPENED;
- } else if (open_state_ == CLOSED) {
- return PP_ERROR_FAILED;
- }
-
- if (!SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTING, false))
- return PP_ERROR_FAILED;
-
- return InternalStartCapture0_1(requested_info, buffer_count);
-}
-
-const std::vector<DeviceRefData>& PPB_VideoCapture_Shared::GetDeviceRefData(
- ) const {
- return InternalGetDeviceRefData();
-}
-
-void PPB_VideoCapture_Shared::OnEnumerateDevicesComplete(
- int32_t result,
- const std::vector<DeviceRefData>& devices) {
- DCHECK(TrackedCallback::IsPending(enumerate_devices_callback_));
-
- if (result == PP_OK && devices_) {
- *devices_ = PPB_DeviceRef_Shared::CreateResourceArray(
- resource_object_type_, pp_instance(), devices);
- }
- devices_ = NULL;
-
- enumerate_devices_callback_->Run(result);
-}
-
-void PPB_VideoCapture_Shared::OnOpenComplete(int32_t result) {
- if (open_state_ == BEFORE_OPEN && result == PP_OK)
- open_state_ = OPENED;
-
- // The callback may have been aborted by Close(), or the open operation is
- // completed synchronously.
- if (TrackedCallback::IsPending(open_callback_))
- open_callback_->Run(result);
-}
-
-bool PPB_VideoCapture_Shared::SetStatus(PP_VideoCaptureStatus_Dev status,
- bool forced) {
- if (!forced) {
- switch (status) {
- case PP_VIDEO_CAPTURE_STATUS_STOPPED:
- if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPING)
- return false;
- break;
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- if (status_ != PP_VIDEO_CAPTURE_STATUS_STOPPED)
- return false;
- break;
- case PP_VIDEO_CAPTURE_STATUS_STARTED:
- switch (status_) {
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- case PP_VIDEO_CAPTURE_STATUS_PAUSED:
- break;
- default:
- return false;
- }
- break;
- case PP_VIDEO_CAPTURE_STATUS_PAUSED:
- switch (status_) {
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- case PP_VIDEO_CAPTURE_STATUS_STARTED:
- break;
- default:
- return false;
- }
- break;
- case PP_VIDEO_CAPTURE_STATUS_STOPPING:
- switch (status_) {
- case PP_VIDEO_CAPTURE_STATUS_STARTING:
- case PP_VIDEO_CAPTURE_STATUS_STARTED:
- case PP_VIDEO_CAPTURE_STATUS_PAUSED:
- break;
- default:
- return false;
- }
- break;
- }
- }
-
- status_ = status;
- return true;
-}
-
-} // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_video_capture_shared.h b/ppapi/shared_impl/ppb_video_capture_shared.h
deleted file mode 100644
index 80b29fe..0000000
--- a/ppapi/shared_impl/ppb_video_capture_shared.h
+++ /dev/null
@@ -1,100 +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.
-
-#ifndef PPAPI_SHARED_IMPL_PPB_VIDEO_CAPTURE_SHARED_H_
-#define PPAPI_SHARED_IMPL_PPB_VIDEO_CAPTURE_SHARED_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_video_capture_api.h"
-
-namespace ppapi {
-
-class PPAPI_SHARED_EXPORT PPB_VideoCapture_Shared
- : public Resource,
- NON_EXPORTED_BASE(public thunk::PPB_VideoCapture_API) {
- public:
- explicit PPB_VideoCapture_Shared(PP_Instance instance);
- explicit PPB_VideoCapture_Shared(const HostResource& host_resource);
- virtual ~PPB_VideoCapture_Shared();
-
- // Resource implementation.
- virtual thunk::PPB_VideoCapture_API* AsPPB_VideoCapture_API() OVERRIDE;
-
- // PPB_VideoCapture_API implementation.
- virtual int32_t EnumerateDevices(
- PP_Resource* devices,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t Open(const std::string& device_id,
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t StartCapture() OVERRIDE;
- virtual int32_t ReuseBuffer(uint32_t buffer) OVERRIDE;
- virtual int32_t StopCapture() OVERRIDE;
- virtual void Close() OVERRIDE;
- virtual int32_t StartCapture0_1(
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count) OVERRIDE;
- virtual const std::vector<DeviceRefData>& GetDeviceRefData() const OVERRIDE;
-
- void OnEnumerateDevicesComplete(int32_t result,
- const std::vector<DeviceRefData>& devices);
- void OnOpenComplete(int32_t result);
-
- protected:
- enum OpenState {
- BEFORE_OPEN,
- OPENED,
- CLOSED
- };
-
- // Subclasses should implement these methods to do impl- and proxy-specific
- // work.
- virtual int32_t InternalEnumerateDevices(
- PP_Resource* devices,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t InternalOpen(
- const std::string& device_id,
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count,
- scoped_refptr<TrackedCallback> callback) = 0;
- virtual int32_t InternalStartCapture() = 0;
- virtual int32_t InternalReuseBuffer(uint32_t buffer) = 0;
- virtual int32_t InternalStopCapture() = 0;
- virtual void InternalClose() = 0;
- virtual int32_t InternalStartCapture0_1(
- const PP_VideoCaptureDeviceInfo_Dev& requested_info,
- uint32_t buffer_count) = 0;
- virtual const std::vector<DeviceRefData>& InternalGetDeviceRefData(
- ) const = 0;
-
- // Checks whether |status| is expected and sets |status_| if yes. If |forced|
- // is set to true, this method will bypass sanity check and always set
- // |status_|.
- bool SetStatus(PP_VideoCaptureStatus_Dev status, bool forced);
-
- OpenState open_state_;
- PP_VideoCaptureStatus_Dev status_;
-
- scoped_refptr<TrackedCallback> enumerate_devices_callback_;
- scoped_refptr<TrackedCallback> open_callback_;
-
- // Output parameter of EnumerateDevices(). It should not be accessed after
- // |enumerate_devices_callback_| is run.
- PP_Resource* devices_;
-
- ResourceObjectType resource_object_type_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PPB_VideoCapture_Shared);
-};
-
-} // namespace ppapi
-
-#endif // PPAPI_SHARED_IMPL_PPB_VIDEO_CAPTURE_SHARED_H_
diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.cc b/ppapi/shared_impl/ppb_video_decoder_shared.cc
index e2547aa..ffd422d 100644
--- a/ppapi/shared_impl/ppb_video_decoder_shared.cc
+++ b/ppapi/shared_impl/ppb_video_decoder_shared.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "ppapi/c/pp_errors.h"
+#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/thunk/enter.h"
@@ -90,8 +91,16 @@
}
void PPB_VideoDecoder_Shared::FlushCommandBuffer() {
- if (gles2_impl_)
+ 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);
gles2_impl_->Flush();
+ }
}
} // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_view_shared.cc b/ppapi/shared_impl/ppb_view_shared.cc
index 54659a3..f11fe1f 100644
--- a/ppapi/shared_impl/ppb_view_shared.cc
+++ b/ppapi/shared_impl/ppb_view_shared.cc
@@ -4,11 +4,22 @@
#include "ppapi/shared_impl/ppb_view_shared.h"
+namespace {
+
+bool IsRectNonempty(const PP_Rect& rect) {
+ return rect.size.width > 0 && rect.size.height > 0;
+}
+
+} // namespace
+
namespace ppapi {
ViewData::ViewData() {
// Assume POD.
memset(this, 0, sizeof(ViewData));
+
+ device_scale = 1.0f;
+ css_scale = 1.0f;
}
ViewData::~ViewData() {
@@ -47,4 +58,38 @@
return data_;
}
+PP_Bool PPB_View_Shared::GetRect(PP_Rect* viewport) const {
+ if (!viewport)
+ return PP_FALSE;
+ *viewport = data_.rect;
+ return PP_TRUE;
+}
+
+PP_Bool PPB_View_Shared::IsFullscreen() const {
+ return PP_FromBool(data_.is_fullscreen);
+}
+
+PP_Bool PPB_View_Shared::IsVisible() const {
+ return PP_FromBool(data_.is_page_visible && IsRectNonempty(data_.clip_rect));
+}
+
+PP_Bool PPB_View_Shared::IsPageVisible() const {
+ return PP_FromBool(data_.is_page_visible);
+}
+
+PP_Bool PPB_View_Shared::GetClipRect(PP_Rect* clip) const {
+ if (!clip)
+ return PP_FALSE;
+ *clip = data_.clip_rect;
+ return PP_TRUE;
+}
+
+float PPB_View_Shared::GetDeviceScale() const {
+ return data_.device_scale;
+}
+
+float PPB_View_Shared::GetCSSScale() const {
+ return data_.css_scale;
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_view_shared.h b/ppapi/shared_impl/ppb_view_shared.h
index e3d41ac..77bf8f2 100644
--- a/ppapi/shared_impl/ppb_view_shared.h
+++ b/ppapi/shared_impl/ppb_view_shared.h
@@ -43,6 +43,14 @@
// PPB_View_API implementation.
virtual const ViewData& GetData() const OVERRIDE;
+ virtual PP_Bool GetRect(PP_Rect* viewport) const OVERRIDE;
+ virtual PP_Bool IsFullscreen() const OVERRIDE;
+ virtual PP_Bool IsVisible() const OVERRIDE;
+ virtual PP_Bool IsPageVisible() const OVERRIDE;
+ virtual PP_Bool GetClipRect(PP_Rect* clip) const
+ OVERRIDE;
+ virtual float GetDeviceScale() const OVERRIDE;
+ virtual float GetCSSScale() const OVERRIDE;
private:
ViewData data_;
diff --git a/ppapi/shared_impl/private/net_address_private_impl.cc b/ppapi/shared_impl/private/net_address_private_impl.cc
index 7a8e375..87a929f 100644
--- a/ppapi/shared_impl/private/net_address_private_impl.cc
+++ b/ppapi/shared_impl/private/net_address_private_impl.cc
@@ -24,6 +24,7 @@
#include "build/build_config.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/private/ppb_net_address_private.h"
+#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/thunk.h"
@@ -285,6 +286,9 @@
*addr, PP_ToBool(include_port));
if (str.empty())
return PP_MakeUndefined();
+ // We must acquire the lock while accessing the VarTracker, which is part of
+ // the critical section of the proxy which may be accessed by other threads.
+ ProxyAutoLock lock;
return StringVar::StringToPPVar(str);
}
diff --git a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.cc b/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.cc
deleted file mode 100644
index 9b2c0f5..0000000
--- a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.cc
+++ /dev/null
@@ -1,440 +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/shared_impl/private/ppb_browser_font_trusted_shared.h"
-
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "ppapi/c/dev/ppb_font_dev.h"
-#include "ppapi/shared_impl/ppapi_preferences.h"
-#include "ppapi/shared_impl/var.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_image_data_api.h"
-#include "ppapi/thunk/thunk.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCanvas.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoint.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFont.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFontDescription.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextRun.h"
-#include "unicode/ubidi.h"
-
-using ppapi::StringVar;
-using ppapi::thunk::EnterResourceNoLock;
-using ppapi::thunk::PPB_ImageData_API;
-using WebKit::WebFloatPoint;
-using WebKit::WebFloatRect;
-using WebKit::WebFont;
-using WebKit::WebFontDescription;
-using WebKit::WebRect;
-using WebKit::WebTextRun;
-using WebKit::WebCanvas;
-
-namespace ppapi {
-
-namespace {
-
-// Same as WebPreferences::kCommonScript. I'd use that directly here, but get an
-// undefined reference linker error.
-const char kCommonScript[] = "Zyyy";
-
-string16 GetFontFromMap(
- const webkit_glue::WebPreferences::ScriptFontFamilyMap& map,
- const std::string& script) {
- webkit_glue::WebPreferences::ScriptFontFamilyMap::const_iterator it =
- map.find(script);
- if (it != map.end())
- return it->second;
- return string16();
-}
-
-// Splits a PP_BrowserFont_Trusted_TextRun into a sequence or LTR and RTL
-// WebTextRuns that can be used for WebKit. Normally WebKit does this for us,
-// but the font drawing and measurement routines we call happen after this
-// step. So for correct rendering of RTL content, we need to do it ourselves.
-class TextRunCollection {
- public:
- explicit TextRunCollection(const PP_BrowserFont_Trusted_TextRun& run)
- : bidi_(NULL),
- num_runs_(0) {
- StringVar* text_string = StringVar::FromPPVar(run.text);
- if (!text_string)
- return; // Leave num_runs_ = 0 so we'll do nothing.
- text_ = UTF8ToUTF16(text_string->value());
-
- if (run.override_direction) {
- // Skip autodetection.
- num_runs_ = 1;
- override_run_ = WebTextRun(text_, PP_ToBool(run.rtl), true);
- } else {
- bidi_ = ubidi_open();
- UErrorCode uerror = U_ZERO_ERROR;
- ubidi_setPara(bidi_, text_.data(), text_.size(), run.rtl, NULL, &uerror);
- if (U_SUCCESS(uerror))
- num_runs_ = ubidi_countRuns(bidi_, &uerror);
- }
- }
-
- ~TextRunCollection() {
- if (bidi_)
- ubidi_close(bidi_);
- }
-
- const string16& text() const { return text_; }
- int num_runs() const { return num_runs_; }
-
- // Returns a WebTextRun with the info for the run at the given index.
- // The range covered by the run is in the two output params.
- WebTextRun GetRunAt(int index, int32_t* run_start, int32_t* run_len) const {
- DCHECK(index < num_runs_);
- if (bidi_) {
- bool run_rtl = !!ubidi_getVisualRun(bidi_, index, run_start, run_len);
- return WebTextRun(string16(&text_[*run_start], *run_len),
- run_rtl, true);
- }
-
- // Override run, return the single one.
- DCHECK(index == 0);
- *run_start = 0;
- *run_len = static_cast<int32_t>(text_.size());
- return override_run_;
- }
-
- private:
- // Will be null if we skipped autodetection.
- UBiDi* bidi_;
-
- // Text of all the runs.
- string16 text_;
-
- int num_runs_;
-
- // When the content specifies override_direction (bidi_ is null) then this
- // will contain the single text run for WebKit.
- WebTextRun override_run_;
-
- DISALLOW_COPY_AND_ASSIGN(TextRunCollection);
-};
-
-bool PPTextRunToWebTextRun(const PP_BrowserFont_Trusted_TextRun& text,
- WebTextRun* run) {
- StringVar* text_string = StringVar::FromPPVar(text.text);
- if (!text_string)
- return false;
-
- *run = WebTextRun(UTF8ToUTF16(text_string->value()),
- PP_ToBool(text.rtl),
- PP_ToBool(text.override_direction));
- return true;
-}
-
-// The PP_* version lacks "None", so is just one value shifted from the
-// WebFontDescription version. These values are checked in
-// PPFontDescToWebFontDesc to make sure the conversion is correct. This is a
-// macro so it can also be used in the COMPILE_ASSERTS.
-#define PP_FAMILY_TO_WEB_FAMILY(f) \
- static_cast<WebFontDescription::GenericFamily>(f + 1)
-
-// Assumes the given PP_FontDescription has been validated.
-WebFontDescription PPFontDescToWebFontDesc(
- const PP_BrowserFont_Trusted_Description& font,
- const Preferences& prefs) {
- // Verify that the enums match so we can just static cast.
- COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight100) ==
- static_cast<int>(PP_BROWSERFONT_TRUSTED_WEIGHT_100),
- FontWeight100);
- COMPILE_ASSERT(static_cast<int>(WebFontDescription::Weight900) ==
- static_cast<int>(PP_BROWSERFONT_TRUSTED_WEIGHT_900),
- FontWeight900);
- COMPILE_ASSERT(WebFontDescription::GenericFamilyStandard ==
- PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_DEFAULT),
- StandardFamily);
- COMPILE_ASSERT(WebFontDescription::GenericFamilySerif ==
- PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_SERIF),
- SerifFamily);
- COMPILE_ASSERT(WebFontDescription::GenericFamilySansSerif ==
- PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_SANSSERIF),
- SansSerifFamily);
- COMPILE_ASSERT(WebFontDescription::GenericFamilyMonospace ==
- PP_FAMILY_TO_WEB_FAMILY(PP_FONTFAMILY_MONOSPACE),
- MonospaceFamily);
-
- StringVar* face_name = StringVar::FromPPVar(font.face); // Possibly null.
-
- WebFontDescription result;
- string16 resolved_family;
- if (!face_name || face_name->value().empty()) {
- // Resolve the generic family.
- switch (font.family) {
- case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF:
- resolved_family = GetFontFromMap(prefs.serif_font_family_map,
- kCommonScript);
- break;
- case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF:
- resolved_family = GetFontFromMap(prefs.sans_serif_font_family_map,
- kCommonScript);
- break;
- case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE:
- resolved_family = GetFontFromMap(prefs.fixed_font_family_map,
- kCommonScript);
- break;
- case PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT:
- default:
- resolved_family = GetFontFromMap(prefs.standard_font_family_map,
- kCommonScript);
- break;
- }
- } else {
- // Use the exact font.
- resolved_family = UTF8ToUTF16(face_name->value());
- }
- result.family = resolved_family;
-
- result.genericFamily = PP_FAMILY_TO_WEB_FAMILY(font.family);
-
- if (font.size == 0) {
- // Resolve the default font size, using the resolved family to see if
- // we should use the fixed or regular font size. It's difficult at this
- // level to detect if the requested font is fixed width, so we only apply
- // the alternate font size to the default fixed font family.
- if (StringToLowerASCII(resolved_family) ==
- StringToLowerASCII(GetFontFromMap(prefs.fixed_font_family_map,
- kCommonScript)))
- result.size = static_cast<float>(prefs.default_fixed_font_size);
- else
- result.size = static_cast<float>(prefs.default_font_size);
- } else {
- // Use the exact size.
- result.size = static_cast<float>(font.size);
- }
-
- result.italic = font.italic != PP_FALSE;
- result.smallCaps = font.small_caps != PP_FALSE;
- result.weight = static_cast<WebFontDescription::Weight>(font.weight);
- result.letterSpacing = static_cast<short>(font.letter_spacing);
- result.wordSpacing = static_cast<short>(font.word_spacing);
- return result;
-}
-
-} // namespace
-
-// static
-bool PPB_BrowserFont_Trusted_Shared::IsPPFontDescriptionValid(
- const PP_BrowserFont_Trusted_Description& desc) {
- // Check validity of string. We can't check the actual text since we could
- // be on the wrong thread and don't know if we're in the plugin or the host.
- if (desc.face.type != PP_VARTYPE_STRING &&
- desc.face.type != PP_VARTYPE_UNDEFINED)
- return false;
-
- // Check enum ranges.
- if (static_cast<int>(desc.family) < PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT ||
- static_cast<int>(desc.family) > PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE)
- return false;
- if (static_cast<int>(desc.weight) < PP_BROWSERFONT_TRUSTED_WEIGHT_100 ||
- static_cast<int>(desc.weight) > PP_BROWSERFONT_TRUSTED_WEIGHT_900)
- return false;
-
- // Check for excessive sizes which may cause layout to get confused.
- if (desc.size > 200)
- return false;
-
- return true;
-}
-
-// static
-PP_Resource PPB_BrowserFont_Trusted_Shared::Create(
- ResourceObjectType type,
- PP_Instance instance,
- const PP_BrowserFont_Trusted_Description& description,
- const Preferences& prefs) {
- if (!PPB_BrowserFont_Trusted_Shared::IsPPFontDescriptionValid(description))
- return 0;
- return (new PPB_BrowserFont_Trusted_Shared(type, instance,
- description,
- prefs))->GetReference();
-}
-
-PPB_BrowserFont_Trusted_Shared::PPB_BrowserFont_Trusted_Shared(
- ResourceObjectType type,
- PP_Instance instance,
- const PP_BrowserFont_Trusted_Description& desc,
- const Preferences& prefs)
- : Resource(type, instance),
- font_(WebFont::create(PPFontDescToWebFontDesc(desc, prefs))) {
-}
-
-PPB_BrowserFont_Trusted_Shared::~PPB_BrowserFont_Trusted_Shared() {
-}
-
-thunk::PPB_BrowserFont_Trusted_API*
-PPB_BrowserFont_Trusted_Shared::AsPPB_BrowserFont_Trusted_API() {
- return this;
-}
-
-PP_Bool PPB_BrowserFont_Trusted_Shared::Describe(
- PP_BrowserFont_Trusted_Description* description,
- PP_BrowserFont_Trusted_Metrics* metrics) {
- if (description->face.type != PP_VARTYPE_UNDEFINED)
- return PP_FALSE;
-
- // While converting the other way in PPFontDescToWebFontDesc we validated
- // that the enums can be casted.
- WebFontDescription web_desc = font_->fontDescription();
- description->face = StringVar::StringToPPVar(UTF16ToUTF8(web_desc.family));
- description->family =
- static_cast<PP_BrowserFont_Trusted_Family>(web_desc.genericFamily);
- description->size = static_cast<uint32_t>(web_desc.size);
- description->weight = static_cast<PP_BrowserFont_Trusted_Weight>(
- web_desc.weight);
- description->italic = web_desc.italic ? PP_TRUE : PP_FALSE;
- description->small_caps = web_desc.smallCaps ? PP_TRUE : PP_FALSE;
- description->letter_spacing = static_cast<int32_t>(web_desc.letterSpacing);
- description->word_spacing = static_cast<int32_t>(web_desc.wordSpacing);
-
- metrics->height = font_->height();
- metrics->ascent = font_->ascent();
- metrics->descent = font_->descent();
- metrics->line_spacing = font_->lineSpacing();
- metrics->x_height = static_cast<int32_t>(font_->xHeight());
-
- // Convert the string.
- return PP_TRUE;
-}
-
-PP_Bool PPB_BrowserFont_Trusted_Shared::DrawTextAt(
- PP_Resource image_data,
- const PP_BrowserFont_Trusted_TextRun* text,
- const PP_Point* position,
- uint32_t color,
- const PP_Rect* clip,
- PP_Bool image_data_is_opaque) {
- PP_Bool result = PP_FALSE;
- // Get and map the image data we're painting to.
- EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
- if (enter.failed())
- return result;
-
- PPB_ImageData_API* image = static_cast<PPB_ImageData_API*>(
- enter.object());
- skia::PlatformCanvas* canvas = image->GetPlatformCanvas();
- bool needs_unmapping = false;
- if (!canvas) {
- needs_unmapping = true;
- image->Map();
- canvas = image->GetPlatformCanvas();
- if (!canvas)
- return result; // Failure mapping.
- }
-
- DrawTextToCanvas(canvas, *text, position, color, clip, image_data_is_opaque);
-
- if (needs_unmapping)
- image->Unmap();
- return PP_TRUE;
-}
-
-int32_t PPB_BrowserFont_Trusted_Shared::MeasureText(
- const PP_BrowserFont_Trusted_TextRun* text) {
- WebTextRun run;
- if (!PPTextRunToWebTextRun(*text, &run))
- return -1;
- return font_->calculateWidth(run);
-}
-
-uint32_t PPB_BrowserFont_Trusted_Shared::CharacterOffsetForPixel(
- const PP_BrowserFont_Trusted_TextRun* text,
- int32_t pixel_position) {
- TextRunCollection runs(*text);
- int32_t cur_pixel_offset = 0;
- for (int i = 0; i < runs.num_runs(); i++) {
- int32_t run_begin = 0;
- int32_t run_len = 0;
- WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
- int run_width = font_->calculateWidth(run);
- if (pixel_position < cur_pixel_offset + run_width) {
- // Offset is in this run.
- return static_cast<uint32_t>(font_->offsetForPosition(
- run, static_cast<float>(pixel_position - cur_pixel_offset))) +
- run_begin;
- }
- cur_pixel_offset += run_width;
- }
- return runs.text().size();
-}
-
-int32_t PPB_BrowserFont_Trusted_Shared::PixelOffsetForCharacter(
- const PP_BrowserFont_Trusted_TextRun* text,
- uint32_t char_offset) {
- TextRunCollection runs(*text);
- int32_t cur_pixel_offset = 0;
- for (int i = 0; i < runs.num_runs(); i++) {
- int32_t run_begin = 0;
- int32_t run_len = 0;
- WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
- if (char_offset >= static_cast<uint32_t>(run_begin) &&
- char_offset < static_cast<uint32_t>(run_begin + run_len)) {
- // Character we're looking for is in this run.
- //
- // Here we ask WebKit to give us the rectangle around the character in
- // question, and then return the left edge. If we asked for a range of
- // 0 characters starting at the character in question, it would give us
- // a 0-width rect around the insertion point. But that will be on the
- // right side of the character for an RTL run, which would be wrong.
- WebFloatRect rect = font_->selectionRectForText(
- run, WebFloatPoint(0.0f, 0.0f), font_->height(),
- char_offset - run_begin, char_offset - run_begin + 1);
- return cur_pixel_offset + static_cast<int>(rect.x);
- } else {
- // Character is past this run, account for the pixels and continue
- // looking.
- cur_pixel_offset += font_->calculateWidth(run);
- }
- }
- return -1; // Requested a char beyond the end.
-}
-
-void PPB_BrowserFont_Trusted_Shared::DrawTextToCanvas(
- skia::PlatformCanvas* destination,
- const PP_BrowserFont_Trusted_TextRun& text,
- const PP_Point* position,
- uint32_t color,
- const PP_Rect* clip,
- PP_Bool image_data_is_opaque) {
- // Convert position and clip.
- WebFloatPoint web_position(static_cast<float>(position->x),
- static_cast<float>(position->y));
- WebRect web_clip;
- if (!clip) {
- // Use entire canvas. SkCanvas doesn't have a size on it, so we just use
- // the current clip bounds.
- SkRect skclip;
- destination->getClipBounds(&skclip);
- web_clip = WebRect(skclip.fLeft, skclip.fTop, skclip.fRight - skclip.fLeft,
- skclip.fBottom - skclip.fTop);
- } else {
- web_clip = WebRect(clip->point.x, clip->point.y,
- clip->size.width, clip->size.height);
- }
-
- TextRunCollection runs(text);
- for (int i = 0; i < runs.num_runs(); i++) {
- int32_t run_begin = 0;
- int32_t run_len = 0;
- WebTextRun run = runs.GetRunAt(i, &run_begin, &run_len);
- font_->drawText(destination, run, web_position, color, web_clip,
- PP_ToBool(image_data_is_opaque));
-
- // Advance to the next run. Note that we avoid doing this for the last run
- // since it's unnecessary, measuring text is slow, and most of the time
- // there will be only one run anyway.
- if (i != runs.num_runs() - 1)
- web_position.x += font_->calculateWidth(run);
- }
-}
-
-} // namespace ppapi
diff --git a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h b/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h
deleted file mode 100644
index e77be56..0000000
--- a/ppapi/shared_impl/private/ppb_browser_font_trusted_shared.h
+++ /dev/null
@@ -1,90 +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.
-
-#ifndef PPAPI_SHARED_IMPL_PRIVATE_PPB_BROWSER_FONT_TRUSTED_SHARED_H_
-#define PPAPI_SHARED_IMPL_PRIVATE_PPB_BROWSER_FONT_TRUSTED_SHARED_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "ppapi/c/pp_bool.h"
-#include "ppapi/c/pp_instance.h"
-#include "ppapi/c/pp_resource.h"
-#include "ppapi/c/pp_stdint.h"
-#include "ppapi/shared_impl/ppapi_preferences.h"
-#include "ppapi/shared_impl/ppapi_shared_export.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/thunk/ppb_browser_font_trusted_api.h"
-
-namespace skia {
-class PlatformCanvas;
-}
-
-namespace WebKit {
-class WebFont;
-}
-
-namespace ppapi {
-
-class PPAPI_SHARED_EXPORT PPB_BrowserFont_Trusted_Shared
- : public Resource,
- public thunk::PPB_BrowserFont_Trusted_API {
- public:
- // Validates the parameters in thee description. Can be called on any thread.
- static bool IsPPFontDescriptionValid(
- const PP_BrowserFont_Trusted_Description& desc);
-
- virtual ~PPB_BrowserFont_Trusted_Shared();
-
- static PP_Resource Create(
- ResourceObjectType type,
- PP_Instance instance,
- const PP_BrowserFont_Trusted_Description& description,
- const ::ppapi::Preferences& prefs);
-
- // Resource.
- virtual ::ppapi::thunk::PPB_BrowserFont_Trusted_API*
- AsPPB_BrowserFont_Trusted_API() OVERRIDE;
-
- // PPB_Font implementation.
- virtual PP_Bool Describe(PP_BrowserFont_Trusted_Description* description,
- PP_BrowserFont_Trusted_Metrics* metrics) OVERRIDE;
- virtual PP_Bool DrawTextAt(PP_Resource image_data,
- const PP_BrowserFont_Trusted_TextRun* text,
- const PP_Point* position,
- uint32_t color,
- const PP_Rect* clip,
- PP_Bool image_data_is_opaque) OVERRIDE;
- virtual int32_t MeasureText(
- const PP_BrowserFont_Trusted_TextRun* text) OVERRIDE;
- virtual uint32_t CharacterOffsetForPixel(
- const PP_BrowserFont_Trusted_TextRun* text,
- int32_t pixel_position) OVERRIDE;
- virtual int32_t PixelOffsetForCharacter(
- const PP_BrowserFont_Trusted_TextRun* text,
- uint32_t char_offset) OVERRIDE;
-
- private:
- PPB_BrowserFont_Trusted_Shared(ResourceObjectType type,
- PP_Instance instance,
- const PP_BrowserFont_Trusted_Description& desc,
- const Preferences& prefs);
-
- // Internal version of DrawTextAt that takes a mapped PlatformCanvas.
- void DrawTextToCanvas(skia::PlatformCanvas* destination,
- const PP_BrowserFont_Trusted_TextRun& text,
- const PP_Point* position,
- uint32_t color,
- const PP_Rect* clip,
- PP_Bool image_data_is_opaque);
-
- scoped_ptr<WebKit::WebFont> font_;
-
- DISALLOW_COPY_AND_ASSIGN(PPB_BrowserFont_Trusted_Shared);
-};
-
-} // namespace ppapi
-
-#endif // PPAPI_SHARED_IMPL_PRIVATE_PPB_BROWSER_FONT_TRUSTED_SHARED_H_
diff --git a/ppapi/shared_impl/private/ppb_char_set_shared.cc b/ppapi/shared_impl/private/ppb_char_set_shared.cc
index 8424b00..5ce51a6 100644
--- a/ppapi/shared_impl/private/ppb_char_set_shared.cc
+++ b/ppapi/shared_impl/private/ppb_char_set_shared.cc
@@ -9,10 +9,10 @@
#include "base/i18n/icu_string_conversions.h"
#include "ppapi/c/dev/ppb_memory_dev.h"
#include "ppapi/thunk/thunk.h"
-#include "unicode/ucnv.h"
-#include "unicode/ucnv_cb.h"
-#include "unicode/ucnv_err.h"
-#include "unicode/ustring.h"
+#include "third_party/icu/public/common/unicode/ucnv.h"
+#include "third_party/icu/public/common/unicode/ucnv_cb.h"
+#include "third_party/icu/public/common/unicode/ucnv_err.h"
+#include "third_party/icu/public/common/unicode/ustring.h"
namespace ppapi {
diff --git a/ppapi/shared_impl/private/ppb_host_resolver_shared.cc b/ppapi/shared_impl/private/ppb_host_resolver_shared.cc
deleted file mode 100644
index ba026dc..0000000
--- a/ppapi/shared_impl/private/ppb_host_resolver_shared.cc
+++ /dev/null
@@ -1,99 +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/shared_impl/private/ppb_host_resolver_shared.h"
-
-#include <cstddef>
-#include <cstring>
-
-#include "base/memory/scoped_ptr.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/private/net_address_private_impl.h"
-#include "ppapi/shared_impl/var.h"
-#include "ppapi/thunk/thunk.h"
-
-namespace ppapi {
-
-PPB_HostResolver_Shared::PPB_HostResolver_Shared(PP_Instance instance)
- : Resource(OBJECT_IS_IMPL, instance),
- host_resolver_id_(GenerateHostResolverID()) {
-}
-
-PPB_HostResolver_Shared::PPB_HostResolver_Shared(
- const HostResource& resource)
- : Resource(OBJECT_IS_PROXY, resource),
- host_resolver_id_(GenerateHostResolverID()) {
-}
-
-PPB_HostResolver_Shared::~PPB_HostResolver_Shared() {
-}
-
-thunk::PPB_HostResolver_Private_API*
-PPB_HostResolver_Shared::AsPPB_HostResolver_Private_API() {
- return this;
-}
-
-int32_t PPB_HostResolver_Shared::Resolve(
- const char* host,
- uint16_t port,
- const PP_HostResolver_Private_Hint* hint,
- scoped_refptr<TrackedCallback> callback) {
- if (!host)
- return PP_ERROR_BADARGUMENT;
- if (ResolveInProgress())
- return PP_ERROR_INPROGRESS;
-
- resolve_callback_ = callback;
-
- HostPortPair host_port;
- host_port.host = host;
- host_port.port = port;
-
- SendResolve(host_port, hint);
- return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Var PPB_HostResolver_Shared::GetCanonicalName() {
- return StringVar::StringToPPVar(canonical_name_);
-}
-
-uint32_t PPB_HostResolver_Shared::GetSize() {
- if (ResolveInProgress())
- return 0;
- return static_cast<uint32_t>(net_address_list_.size());
-}
-
-bool PPB_HostResolver_Shared::GetNetAddress(uint32 index,
- PP_NetAddress_Private* address) {
- if (ResolveInProgress() || index >= GetSize())
- return false;
- *address = net_address_list_[index];
- return true;
-}
-
-void PPB_HostResolver_Shared::OnResolveCompleted(
- bool succeeded,
- const std::string& canonical_name,
- const std::vector<PP_NetAddress_Private>& net_address_list) {
- if (succeeded) {
- canonical_name_ = canonical_name;
- net_address_list_ = net_address_list;
- } else {
- canonical_name_.clear();
- net_address_list_.clear();
- }
-
- resolve_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
-}
-
-uint32 PPB_HostResolver_Shared::GenerateHostResolverID() {
- static uint32 host_resolver_id = 0;
- return host_resolver_id++;
-}
-
-bool PPB_HostResolver_Shared::ResolveInProgress() const {
- return TrackedCallback::IsPending(resolve_callback_);
-}
-
-} // namespace ppapi
diff --git a/ppapi/shared_impl/private/ppb_host_resolver_shared.h b/ppapi/shared_impl/private/ppb_host_resolver_shared.h
deleted file mode 100644
index 7372dc5..0000000
--- a/ppapi/shared_impl/private/ppb_host_resolver_shared.h
+++ /dev/null
@@ -1,76 +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.
-
-#ifndef PPAPI_SHARED_IMPL_PRIVATE_PPB_HOST_RESOLVER_SHARED_H_
-#define PPAPI_SHARED_IMPL_PRIVATE_PPB_HOST_RESOLVER_SHARED_H_
-
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_host_resolver_private_api.h"
-
-namespace ppapi {
-
-struct HostPortPair {
- std::string host;
- uint16_t port;
-};
-
-class PPAPI_SHARED_EXPORT PPB_HostResolver_Shared
- : public thunk::PPB_HostResolver_Private_API,
- public Resource {
- public:
- // C-tor used in Impl case.
- explicit PPB_HostResolver_Shared(PP_Instance instance);
-
- // C-tor used in Proxy case.
- explicit PPB_HostResolver_Shared(const HostResource& resource);
-
- virtual ~PPB_HostResolver_Shared();
-
- // Resource overrides.
- virtual PPB_HostResolver_Private_API*
- AsPPB_HostResolver_Private_API() OVERRIDE;
-
- // PPB_HostResolver_Private_API implementation.
- virtual int32_t Resolve(const char* host,
- uint16_t port,
- const PP_HostResolver_Private_Hint* hint,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual PP_Var GetCanonicalName() OVERRIDE;
- virtual uint32_t GetSize() OVERRIDE;
- virtual bool GetNetAddress(uint32_t index,
- PP_NetAddress_Private* address) OVERRIDE;
-
- void OnResolveCompleted(
- bool succeeded,
- const std::string& canonical_name,
- const std::vector<PP_NetAddress_Private>& net_address_list);
-
- // Send functions that need to be implemented differently for the
- // proxied and non-proxied derived classes.
- virtual void SendResolve(const HostPortPair& host_port,
- const PP_HostResolver_Private_Hint* hint) = 0;
-
- protected:
- static uint32 GenerateHostResolverID();
- bool ResolveInProgress() const;
-
- const uint32 host_resolver_id_;
-
- scoped_refptr<TrackedCallback> resolve_callback_;
-
- std::string canonical_name_;
- std::vector<PP_NetAddress_Private> net_address_list_;
-
- DISALLOW_COPY_AND_ASSIGN(PPB_HostResolver_Shared);
-};
-
-} // namespace ppapi
-
-#endif // PPAPI_SHARED_IMPL_PRIVATE_PPB_HOST_RESOLVER_SHARED_H_
diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc
index e2c645f..87cc600 100644
--- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc
+++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc
@@ -212,11 +212,34 @@
PostAbortIfNecessary(&ssl_handshake_callback_);
PostAbortIfNecessary(&read_callback_);
PostAbortIfNecessary(&write_callback_);
+ PostAbortIfNecessary(&set_option_callback_);
read_buffer_ = NULL;
bytes_to_read_ = -1;
server_certificate_ = NULL;
}
+int32_t TCPSocketPrivateImpl::SetOption(
+ PP_TCPSocketOption_Private name,
+ const PP_Var& value,
+ scoped_refptr<TrackedCallback> callback) {
+ if (!IsConnected())
+ return PP_ERROR_FAILED;
+ if (TrackedCallback::IsPending(set_option_callback_))
+ return PP_ERROR_INPROGRESS;
+
+ set_option_callback_ = callback;
+
+ switch (name) {
+ case PP_TCPSOCKETOPTION_NO_DELAY:
+ if (value.type != PP_VARTYPE_BOOL)
+ return PP_ERROR_BADARGUMENT;
+ SendSetBoolOption(name, PP_ToBool(value.value.as_bool));
+ return PP_OK_COMPLETIONPENDING;
+ default:
+ return PP_ERROR_BADARGUMENT;
+ }
+}
+
void TCPSocketPrivateImpl::OnConnectCompleted(
bool succeeded,
const PP_NetAddress_Private& local_addr,
@@ -293,6 +316,15 @@
succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
}
+void TCPSocketPrivateImpl::OnSetOptionCompleted(bool succeeded) {
+ if (!TrackedCallback::IsPending(set_option_callback_)) {
+ NOTREACHED();
+ return;
+ }
+
+ set_option_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
+}
+
void TCPSocketPrivateImpl::Init(uint32 socket_id) {
DCHECK(socket_id != 0);
socket_id_ = socket_id;
diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.h b/ppapi/shared_impl/private/tcp_socket_private_impl.h
index 2792102..95057e7 100644
--- a/ppapi/shared_impl/private/tcp_socket_private_impl.h
+++ b/ppapi/shared_impl/private/tcp_socket_private_impl.h
@@ -66,6 +66,9 @@
int32_t bytes_to_write,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual void Disconnect() OVERRIDE;
+ virtual int32_t SetOption(PP_TCPSocketOption_Private name,
+ const PP_Var& value,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
// Notifications on operations completion.
void OnConnectCompleted(bool succeeded,
@@ -76,6 +79,7 @@
const PPB_X509Certificate_Fields& certificate_fields);
void OnReadCompleted(bool succeeded, const std::string& data);
void OnWriteCompleted(bool succeeded, int32_t bytes_written);
+ void OnSetOptionCompleted(bool succeeded);
// Send functions that need to be implemented differently for the
// proxied and non-proxied derived classes.
@@ -89,6 +93,8 @@
virtual void SendRead(int32_t bytes_to_read) = 0;
virtual void SendWrite(const std::string& buffer) = 0;
virtual void SendDisconnect() = 0;
+ virtual void SendSetBoolOption(PP_TCPSocketOption_Private name,
+ bool value) = 0;
protected:
enum ConnectionState {
@@ -117,6 +123,7 @@
scoped_refptr<TrackedCallback> ssl_handshake_callback_;
scoped_refptr<TrackedCallback> read_callback_;
scoped_refptr<TrackedCallback> write_callback_;
+ scoped_refptr<TrackedCallback> set_option_callback_;
char* read_buffer_;
int32_t bytes_to_read_;
diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.cc b/ppapi/shared_impl/private/udp_socket_private_impl.cc
deleted file mode 100644
index 288c38f..0000000
--- a/ppapi/shared_impl/private/udp_socket_private_impl.cc
+++ /dev/null
@@ -1,223 +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/shared_impl/private/udp_socket_private_impl.h"
-
-#include <string.h>
-
-#include <algorithm>
-
-#include "base/basictypes.h"
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "ppapi/c/pp_bool.h"
-#include "ppapi/c/pp_completion_callback.h"
-#include "ppapi/c/pp_errors.h"
-
-namespace ppapi {
-
-const int32_t UDPSocketPrivateImpl::kMaxReadSize = 1024 * 1024;
-const int32_t UDPSocketPrivateImpl::kMaxWriteSize = 1024 * 1024;
-
-UDPSocketPrivateImpl::UDPSocketPrivateImpl(const HostResource& resource,
- uint32 socket_id)
- : Resource(OBJECT_IS_PROXY, resource) {
- Init(socket_id);
-}
-
-UDPSocketPrivateImpl::UDPSocketPrivateImpl(PP_Instance instance,
- uint32 socket_id)
- : Resource(OBJECT_IS_IMPL, instance) {
- Init(socket_id);
-}
-
-UDPSocketPrivateImpl::~UDPSocketPrivateImpl() {
-}
-
-thunk::PPB_UDPSocket_Private_API*
-UDPSocketPrivateImpl::AsPPB_UDPSocket_Private_API() {
- return this;
-}
-
-int32_t UDPSocketPrivateImpl::SetSocketFeature(PP_UDPSocketFeature_Private name,
- PP_Var value) {
- if (bound_ || closed_)
- return PP_ERROR_FAILED;
-
- switch (name) {
- case PP_UDPSOCKETFEATURE_ADDRESS_REUSE:
- case PP_UDPSOCKETFEATURE_BROADCAST:
- if (value.type != PP_VARTYPE_BOOL)
- return PP_ERROR_BADARGUMENT;
- SendBoolSocketFeature(static_cast<int32_t>(name),
- PP_ToBool(value.value.as_bool));
- break;
- default:
- return PP_ERROR_BADARGUMENT;
- }
- return PP_OK;
-}
-
-int32_t UDPSocketPrivateImpl::Bind(const PP_NetAddress_Private* addr,
- scoped_refptr<TrackedCallback> callback) {
- if (!addr)
- return PP_ERROR_BADARGUMENT;
- if (bound_ || closed_)
- return PP_ERROR_FAILED;
- if (TrackedCallback::IsPending(bind_callback_))
- return PP_ERROR_INPROGRESS;
-
- bind_callback_ = callback;
-
- // Send the request, the browser will call us back via BindACK.
- SendBind(*addr);
- return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Bool UDPSocketPrivateImpl::GetBoundAddress(PP_NetAddress_Private* addr) {
- if (!addr || !bound_ || closed_)
- return PP_FALSE;
-
- *addr = bound_addr_;
- return PP_TRUE;
-}
-
-int32_t UDPSocketPrivateImpl::RecvFrom(
- char* buffer,
- int32_t num_bytes,
- scoped_refptr<TrackedCallback> callback) {
- if (!buffer || num_bytes <= 0)
- return PP_ERROR_BADARGUMENT;
- if (!bound_)
- return PP_ERROR_FAILED;
- if (TrackedCallback::IsPending(recvfrom_callback_))
- return PP_ERROR_INPROGRESS;
-
- read_buffer_ = buffer;
- bytes_to_read_ = std::min(num_bytes, kMaxReadSize);
- recvfrom_callback_ = callback;
-
- // Send the request, the browser will call us back via RecvFromACK.
- SendRecvFrom(bytes_to_read_);
- return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Bool UDPSocketPrivateImpl::GetRecvFromAddress(PP_NetAddress_Private* addr) {
- if (!addr)
- return PP_FALSE;
-
- *addr = recvfrom_addr_;
- return PP_TRUE;
-}
-
-int32_t UDPSocketPrivateImpl::SendTo(const char* buffer,
- int32_t num_bytes,
- const PP_NetAddress_Private* addr,
- scoped_refptr<TrackedCallback> callback) {
- if (!buffer || num_bytes <= 0 || !addr)
- return PP_ERROR_BADARGUMENT;
- if (!bound_)
- return PP_ERROR_FAILED;
- if (TrackedCallback::IsPending(sendto_callback_))
- return PP_ERROR_INPROGRESS;
-
- if (num_bytes > kMaxWriteSize)
- num_bytes = kMaxWriteSize;
-
- sendto_callback_ = callback;
-
- // Send the request, the browser will call us back via SendToACK.
- SendSendTo(std::string(buffer, num_bytes), *addr);
- return PP_OK_COMPLETIONPENDING;
-}
-
-void UDPSocketPrivateImpl::Close() {
- if(closed_)
- return;
-
- bound_ = false;
- closed_ = true;
-
- SendClose();
-
- socket_id_ = 0;
-
- PostAbortIfNecessary(&bind_callback_);
- PostAbortIfNecessary(&recvfrom_callback_);
- PostAbortIfNecessary(&sendto_callback_);
-}
-
-void UDPSocketPrivateImpl::OnBindCompleted(
- bool succeeded,
- const PP_NetAddress_Private& addr) {
- if (!TrackedCallback::IsPending(bind_callback_)) {
- NOTREACHED();
- return;
- }
-
- if (succeeded)
- bound_ = true;
-
- bound_addr_ = addr;
-
- bind_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
-}
-
-void UDPSocketPrivateImpl::OnRecvFromCompleted(
- bool succeeded,
- const std::string& data,
- const PP_NetAddress_Private& addr) {
- if (!TrackedCallback::IsPending(recvfrom_callback_) || !read_buffer_) {
- NOTREACHED();
- return;
- }
-
- if (succeeded) {
- CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
- if (!data.empty())
- memcpy(read_buffer_, data.c_str(), data.size());
- }
- read_buffer_ = NULL;
- bytes_to_read_ = -1;
- recvfrom_addr_ = addr;
-
- recvfrom_callback_->Run(succeeded ? static_cast<int32_t>(data.size()) :
- static_cast<int32_t>(PP_ERROR_FAILED));
-}
-
-void UDPSocketPrivateImpl::OnSendToCompleted(bool succeeded,
- int32_t bytes_written) {
- if (!TrackedCallback::IsPending(sendto_callback_)) {
- NOTREACHED();
- return;
- }
-
- sendto_callback_->Run(
- succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
-}
-
-void UDPSocketPrivateImpl::Init(uint32 socket_id) {
- DCHECK(socket_id != 0);
- socket_id_ = socket_id;
- bound_ = false;
- closed_ = false;
- read_buffer_ = NULL;
- bytes_to_read_ = -1;
-
- recvfrom_addr_.size = 0;
- memset(recvfrom_addr_.data, 0,
- arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data));
- bound_addr_.size = 0;
- memset(bound_addr_.data, 0,
- arraysize(bound_addr_.data) * sizeof(*bound_addr_.data));
-}
-
-void UDPSocketPrivateImpl::PostAbortIfNecessary(
- scoped_refptr<TrackedCallback>* callback) {
- if (TrackedCallback::IsPending(*callback))
- (*callback)->PostAbort();
-}
-
-} // namespace ppapi
diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.h b/ppapi/shared_impl/private/udp_socket_private_impl.h
deleted file mode 100644
index e8e3cb2..0000000
--- a/ppapi/shared_impl/private/udp_socket_private_impl.h
+++ /dev/null
@@ -1,99 +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.
-
-#ifndef PPAPI_SHARED_IMPL_PRIVATE_UDP_SOCKET_PRIVATE_IMPL_H_
-#define PPAPI_SHARED_IMPL_PRIVATE_UDP_SOCKET_PRIVATE_IMPL_H_
-
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/thunk/ppb_udp_socket_private_api.h"
-
-namespace ppapi {
-
-// This class provides the shared implementation of a
-// PPB_UDPSocket_Private. The functions that actually send messages
-// to browser are implemented differently for the proxied and
-// non-proxied derived classes.
-class PPAPI_SHARED_EXPORT UDPSocketPrivateImpl
- : public thunk::PPB_UDPSocket_Private_API,
- public Resource {
- public:
- // C-tor used in Impl case.
- UDPSocketPrivateImpl(PP_Instance instance, uint32 socket_id);
- // C-tor used in Proxy case.
- UDPSocketPrivateImpl(const HostResource& resource, uint32 socket_id);
-
- virtual ~UDPSocketPrivateImpl();
-
- // The maximum number of bytes that each PpapiHostMsg_PPBUDPSocket_RecvFrom
- // message is allowed to request.
- static const int32_t kMaxReadSize;
- // The maximum number of bytes that each PpapiHostMsg_PPBUDPSocket_SendTo
- // message is allowed to carry.
- static const int32_t kMaxWriteSize;
-
- // Resource overrides.
- virtual PPB_UDPSocket_Private_API* AsPPB_UDPSocket_Private_API() OVERRIDE;
-
- // PPB_UDPSocket_Private_API implementation.
- virtual int32_t SetSocketFeature(PP_UDPSocketFeature_Private name,
- PP_Var value) OVERRIDE;
- virtual int32_t Bind(const PP_NetAddress_Private* addr,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual PP_Bool GetBoundAddress(PP_NetAddress_Private* addr) OVERRIDE;
- virtual int32_t RecvFrom(char* buffer,
- int32_t num_bytes,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual PP_Bool GetRecvFromAddress(PP_NetAddress_Private* addr) OVERRIDE;
- virtual int32_t SendTo(const char* buffer,
- int32_t num_bytes,
- const PP_NetAddress_Private* addr,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual void Close() OVERRIDE;
-
- // Notifications from the proxy.
- void OnBindCompleted(bool succeeded,
- const PP_NetAddress_Private& bound_addr);
- void OnRecvFromCompleted(bool succeeded,
- const std::string& data,
- const PP_NetAddress_Private& addr);
- void OnSendToCompleted(bool succeeded, int32_t bytes_written);
-
- // Send functions that need to be implemented differently for
- // the proxied and non-proxied derived classes.
- virtual void SendBoolSocketFeature(int32_t name, bool value) = 0;
- virtual void SendBind(const PP_NetAddress_Private& addr) = 0;
- virtual void SendRecvFrom(int32_t num_bytes) = 0;
- virtual void SendSendTo(const std::string& buffer,
- const PP_NetAddress_Private& addr) = 0;
- virtual void SendClose() = 0;
-
- protected:
- void Init(uint32 socket_id);
- void PostAbortIfNecessary(scoped_refptr<TrackedCallback>* callback);
-
- uint32 socket_id_;
-
- bool bound_;
- bool closed_;
-
- scoped_refptr<TrackedCallback> bind_callback_;
- scoped_refptr<TrackedCallback> recvfrom_callback_;
- scoped_refptr<TrackedCallback> sendto_callback_;
-
- char* read_buffer_;
- int32_t bytes_to_read_;
-
- PP_NetAddress_Private recvfrom_addr_;
- PP_NetAddress_Private bound_addr_;
-
- DISALLOW_COPY_AND_ASSIGN(UDPSocketPrivateImpl);
-};
-
-} // namespace ppapi
-
-#endif // PPAPI_SHARED_IMPL_PRIVATE_UDP_SOCKET_PRIVATE_IMPL_H_
diff --git a/ppapi/shared_impl/proxy_lock.cc b/ppapi/shared_impl/proxy_lock.cc
index 990130a..f9f937f 100644
--- a/ppapi/shared_impl/proxy_lock.cc
+++ b/ppapi/shared_impl/proxy_lock.cc
@@ -4,30 +4,54 @@
#include "ppapi/shared_impl/proxy_lock.h"
+#include "base/lazy_instance.h"
#include "base/synchronization/lock.h"
+#include "base/threading/thread_local.h"
#include "ppapi/shared_impl/ppapi_globals.h"
namespace ppapi {
+// Simple single-thread deadlock detector for the proxy lock.
+// |true| when the current thread has the lock.
+base::LazyInstance<base::ThreadLocalBoolean>::Leaky
+ g_proxy_locked_on_thread = LAZY_INSTANCE_INITIALIZER;
+
// static
void ProxyLock::Acquire() {
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
- if (lock)
+ if (lock) {
+ // This thread does not already hold the lock.
+ const bool deadlock = g_proxy_locked_on_thread.Get().Get();
+ CHECK(!deadlock);
+
lock->Acquire();
+ g_proxy_locked_on_thread.Get().Set(true);
+ }
}
// static
void ProxyLock::Release() {
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
- if (lock)
+ if (lock) {
+ // This thread currently holds the lock.
+ const bool locked = g_proxy_locked_on_thread.Get().Get();
+ CHECK(locked);
+
+ g_proxy_locked_on_thread.Get().Set(false);
lock->Release();
+ }
}
// static
void ProxyLock::AssertAcquired() {
base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
- if (lock)
+ if (lock) {
+ // This thread currently holds the lock.
+ const bool locked = g_proxy_locked_on_thread.Get().Get();
+ CHECK(locked);
+
lock->AssertAcquired();
+ }
}
void CallWhileUnlocked(const base::Closure& closure) {
diff --git a/ppapi/shared_impl/resource.cc b/ppapi/shared_impl/resource.cc
index 88f908b..f1db8de 100644
--- a/ppapi/shared_impl/resource.cc
+++ b/ppapi/shared_impl/resource.cc
@@ -59,6 +59,10 @@
}
void Resource::NotifyInstanceWasDeleted() {
+ // Hold a reference, because InstanceWasDeleted() may cause us to be
+ // destroyed.
+ scoped_refptr<Resource> keep_alive(this);
+
// Notify subclasses.
InstanceWasDeleted();
@@ -70,7 +74,7 @@
NOTREACHED();
}
-void Resource::Log(PP_LogLevel_Dev level, const std::string& message) {
+void Resource::Log(PP_LogLevel level, const std::string& message) {
PpapiGlobals::Get()->LogWithSource(pp_instance(), level, std::string(),
message);
}
diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h
index 3f1f5ab..23522d5 100644
--- a/ppapi/shared_impl/resource.h
+++ b/ppapi/shared_impl/resource.h
@@ -13,7 +13,7 @@
#include "base/memory/ref_counted.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
-#include "ppapi/c/dev/ppb_console_dev.h"
+#include "ppapi/c/ppb_console.h"
#include "ppapi/shared_impl/host_resource.h"
// All resource types should be added here. This implements our hand-rolled
@@ -24,9 +24,10 @@
F(PPB_AudioInput_API) \
F(PPB_AudioTrusted_API) \
F(PPB_Broker_API) \
+ F(PPB_Broker_Instance_API) \
+ F(PPB_BrowserFont_Singleton_API) \
F(PPB_BrowserFont_Trusted_API) \
F(PPB_Buffer_API) \
- F(PPB_BufferTrusted_API) \
F(PPB_DeviceRef_API) \
F(PPB_DirectoryReader_API) \
F(PPB_FileChooser_API) \
@@ -36,10 +37,13 @@
F(PPB_Find_API) \
F(PPB_Flash_Clipboard_API) \
F(PPB_Flash_DeviceID_API) \
+ F(PPB_Flash_File_API) \
F(PPB_Flash_FontFile_API) \
+ F(PPB_Flash_Fullscreen_API) \
F(PPB_Flash_Functions_API) \
F(PPB_Flash_Menu_API) \
F(PPB_Flash_MessageLoop_API) \
+ F(PPB_Gamepad_API) \
F(PPB_Graphics2D_API) \
F(PPB_Graphics3D_API) \
F(PPB_HostResolver_Private_API) \
@@ -49,11 +53,12 @@
F(PPB_MessageLoop_API) \
F(PPB_NetworkList_Private_API) \
F(PPB_NetworkMonitor_Private_API) \
- F(PPB_PDFFont_API) \
F(PPB_Printing_API) \
F(PPB_ResourceArray_API) \
F(PPB_Scrollbar_API) \
F(PPB_Talk_Private_API) \
+ F(PPB_TrueTypeFont_API) \
+ F(PPB_TrueTypeFont_Singleton_API) \
F(PPB_TCPServerSocket_Private_API) \
F(PPB_TCPSocket_Private_API) \
F(PPB_UDPSocket_Private_API) \
@@ -199,7 +204,7 @@
protected:
// Logs a message to the console from this resource.
- void Log(PP_LogLevel_Dev level, const std::string& message);
+ void Log(PP_LogLevel level, const std::string& message);
// Notifications for subclasses.
virtual void LastPluginRefWasDeleted() {}
diff --git a/ppapi/shared_impl/resource_tracker.cc b/ppapi/shared_impl/resource_tracker.cc
index 45f127a..f7e22eb 100644
--- a/ppapi/shared_impl/resource_tracker.cc
+++ b/ppapi/shared_impl/resource_tracker.cc
@@ -10,6 +10,7 @@
#include "ppapi/shared_impl/callback_tracker.h"
#include "ppapi/shared_impl/id_assignment.h"
#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource.h"
namespace ppapi {
@@ -24,6 +25,7 @@
Resource* ResourceTracker::GetResource(PP_Resource res) const {
CHECK(thread_checker_.CalledOnValidThread());
+ ProxyLock::AssertAcquired();
ResourceMap::const_iterator i = live_resources_.find(res);
if (i == live_resources_.end())
return NULL;
@@ -78,9 +80,9 @@
void ResourceTracker::ReleaseResourceSoon(PP_Resource res) {
MessageLoop::current()->PostNonNestableTask(
FROM_HERE,
- base::Bind(&ResourceTracker::ReleaseResource,
- weak_ptr_factory_.GetWeakPtr(),
- res));
+ RunWhileLocked(base::Bind(&ResourceTracker::ReleaseResource,
+ weak_ptr_factory_.GetWeakPtr(),
+ res)));
}
void ResourceTracker::DidCreateInstance(PP_Instance instance) {
diff --git a/ppapi/shared_impl/scoped_pp_resource.cc b/ppapi/shared_impl/scoped_pp_resource.cc
index 8399208..45a1ad7 100644
--- a/ppapi/shared_impl/scoped_pp_resource.cc
+++ b/ppapi/shared_impl/scoped_pp_resource.cc
@@ -55,7 +55,8 @@
}
PP_Resource ScopedPPResource::Release() {
- CallRelease();
+ // We do NOT call CallRelease, because we want to pass our reference to the
+ // caller.
PP_Resource ret = id_;
id_ = 0;
diff --git a/ppapi/shared_impl/scoped_pp_var.cc b/ppapi/shared_impl/scoped_pp_var.cc
index fcd6806..3ae13b0 100644
--- a/ppapi/shared_impl/scoped_pp_var.cc
+++ b/ppapi/shared_impl/scoped_pp_var.cc
@@ -47,4 +47,10 @@
return *this;
}
+PP_Var ScopedPPVar::Release() {
+ PP_Var result = var_;
+ var_ = PP_MakeUndefined();
+ return result;
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/scoped_pp_var.h b/ppapi/shared_impl/scoped_pp_var.h
index 8079a91..564401d 100644
--- a/ppapi/shared_impl/scoped_pp_var.h
+++ b/ppapi/shared_impl/scoped_pp_var.h
@@ -16,7 +16,7 @@
ScopedPPVar();
- // Takes one reference to the given resource.
+ // Takes one reference to the given var.
explicit ScopedPPVar(const PP_Var& v);
// Assumes responsibility for one ref that the var already has.
diff --git a/ppapi/shared_impl/singleton_resource_id.h b/ppapi/shared_impl/singleton_resource_id.h
new file mode 100644
index 0000000..ef3096d
--- /dev/null
+++ b/ppapi/shared_impl/singleton_resource_id.h
@@ -0,0 +1,29 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_SINGLETON_RESOURCE_ID_H_
+#define PPAPI_SHARED_IMPL_SINGLETON_RESOURCE_ID_H_
+
+namespace ppapi {
+
+// These IDs are used to access singleton resource objects using
+// PPB_Instance_API.GetSingletonResource.
+enum SingletonResourceID {
+ // TODO(raymes): The broker resource isn't really a singleton. This is only
+ // a hack until PPB_Broker trusted has been fully refactored to the new
+ // resource model.
+ BROKER_SINGLETON_ID,
+ BROWSER_FONT_SINGLETON_ID,
+ FLASH_CLIPBOARD_SINGLETON_ID,
+ FLASH_FILE_SINGLETON_ID,
+ FLASH_FULLSCREEN_SINGLETON_ID,
+ FLASH_SINGLETON_ID,
+ GAMEPAD_SINGLETON_ID,
+ PDF_SINGLETON_ID,
+ TRUETYPE_FONT_SINGLETON_ID,
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_SINGLETON_RESOURCE_ID_H_
diff --git a/ppapi/shared_impl/test_globals.cc b/ppapi/shared_impl/test_globals.cc
index b1dc0fe..913d53c 100644
--- a/ppapi/shared_impl/test_globals.cc
+++ b/ppapi/shared_impl/test_globals.cc
@@ -11,8 +11,8 @@
callback_tracker_(new CallbackTracker) {
}
-TestGlobals::TestGlobals(PpapiGlobals::ForTest for_test)
- : ppapi::PpapiGlobals(for_test),
+TestGlobals::TestGlobals(PpapiGlobals::PerThreadForTest per_thread_for_test)
+ : ppapi::PpapiGlobals(per_thread_for_test),
callback_tracker_(new CallbackTracker) {
}
@@ -58,13 +58,13 @@
}
void TestGlobals::LogWithSource(PP_Instance instance,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
const std::string& source,
const std::string& value) {
}
void TestGlobals::BroadcastLogWithSource(PP_Module module,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
const std::string& source,
const std::string& value) {
}
diff --git a/ppapi/shared_impl/test_globals.h b/ppapi/shared_impl/test_globals.h
index ca67e77..5579b09 100644
--- a/ppapi/shared_impl/test_globals.h
+++ b/ppapi/shared_impl/test_globals.h
@@ -6,6 +6,7 @@
#define PPAPI_SHARED_IMPL_TEST_GLOBALS_H_
#include "base/compiler_specific.h"
+#include "base/shared_memory.h"
#include "ppapi/shared_impl/callback_tracker.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/resource_tracker.h"
@@ -20,8 +21,24 @@
virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE {
return NULL;
}
+ virtual ArrayBufferVar* CreateShmArrayBuffer(
+ uint32 size_in_bytes,
+ base::SharedMemoryHandle handle) OVERRIDE {
+ return NULL;
+ }
virtual void DidDeleteInstance(PP_Instance instance) OVERRIDE {
}
+ virtual int TrackSharedMemoryHandle(PP_Instance instance,
+ base::SharedMemoryHandle handle,
+ uint32 size_in_bytes) OVERRIDE {
+ return -1;
+ }
+ virtual bool StopTrackingSharedMemoryHandle(int id,
+ PP_Instance instance,
+ base::SharedMemoryHandle* handle,
+ uint32* size_in_bytes) OVERRIDE {
+ return false;
+ }
};
// Implementation of PpapiGlobals for tests that don't need either the host- or
@@ -29,7 +46,7 @@
class TestGlobals : public PpapiGlobals {
public:
TestGlobals();
- TestGlobals(PpapiGlobals::ForTest);
+ explicit TestGlobals(PpapiGlobals::PerThreadForTest);
virtual ~TestGlobals();
// PpapiGlobals implementation.
@@ -46,11 +63,11 @@
virtual void PreCacheFontForFlash(const void* logfontw) OVERRIDE;
virtual base::Lock* GetProxyLock() OVERRIDE;
virtual void LogWithSource(PP_Instance instance,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
const std::string& source,
const std::string& value) OVERRIDE;
virtual void BroadcastLogWithSource(PP_Module module,
- PP_LogLevel_Dev level,
+ PP_LogLevel level,
const std::string& source,
const std::string& value) OVERRIDE;
virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE;
diff --git a/ppapi/shared_impl/thread_aware_callback.cc b/ppapi/shared_impl/thread_aware_callback.cc
new file mode 100644
index 0000000..9b1063b
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback.cc
@@ -0,0 +1,63 @@
+// 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/shared_impl/thread_aware_callback.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/ppb_message_loop_shared.h"
+
+namespace ppapi {
+namespace internal {
+
+class ThreadAwareCallbackBase::Core : public base::RefCountedThreadSafe<Core> {
+ public:
+ Core() : aborted_(false) {
+ }
+
+ void MarkAsAborted() { aborted_ = true; }
+
+ void RunIfNotAborted(const base::Closure& closure) {
+ if (!aborted_)
+ CallWhileUnlocked(closure);
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<Core>;
+ ~Core() {
+ }
+
+ bool aborted_;
+};
+
+ThreadAwareCallbackBase::ThreadAwareCallbackBase()
+ : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()),
+ core_(new Core()) {
+ DCHECK(target_loop_.get());
+}
+
+ThreadAwareCallbackBase::~ThreadAwareCallbackBase() {
+ core_->MarkAsAborted();
+}
+
+// static
+bool ThreadAwareCallbackBase::HasTargetLoop() {
+ return !!PpapiGlobals::Get()->GetCurrentMessageLoop();
+}
+
+void ThreadAwareCallbackBase::InternalRunOnTargetThread(
+ const base::Closure& closure) {
+ if (target_loop_ != PpapiGlobals::Get()->GetCurrentMessageLoop()) {
+ target_loop_->PostClosure(
+ FROM_HERE,
+ RunWhileLocked(base::Bind(&Core::RunIfNotAborted, core_, closure)),
+ 0);
+ } else {
+ CallWhileUnlocked(closure);
+ }
+}
+
+} // namespace internal
+} // namespace ppapi
diff --git a/ppapi/shared_impl/thread_aware_callback.h b/ppapi/shared_impl/thread_aware_callback.h
new file mode 100644
index 0000000..b954eec
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback.h
@@ -0,0 +1,115 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
+#define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/memory/ref_counted.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+
+namespace ppapi {
+
+class MessageLoopShared;
+
+namespace internal {
+
+class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase {
+ protected:
+ ThreadAwareCallbackBase();
+ ~ThreadAwareCallbackBase();
+
+ static bool HasTargetLoop();
+
+ void InternalRunOnTargetThread(const base::Closure& closure);
+
+ private:
+ class Core;
+
+ scoped_refptr<MessageLoopShared> target_loop_;
+ scoped_refptr<Core> core_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase);
+};
+
+} // namespace internal
+
+// Some PPB interfaces have methods that set a custom callback. Usually, the
+// callback has to be called on the same thread as the one it was set on.
+// ThreadAwareCallback keeps track of the target thread, and posts a task to run
+// on it if requested from a different thread.
+//
+// Please note that:
+// - Unlike TrackedCallback, there is no restriction on how many times the
+// callback will be called.
+// - When a ThreadAwareCallback object is destroyed, all pending tasks to run
+// the callback will be ignored. It is designed this way so that when the
+// resource is destroyed or the callback is cancelled by the plugin, we can
+// simply delete the ThreadAwareCallback object to prevent touching the
+// callback later.
+// - When RunOnTargetThread() is called on the target thread, the callback runs
+// immediately.
+template <class FuncType>
+class ThreadAwareCallback : public internal::ThreadAwareCallbackBase {
+ public:
+ // The caller takes ownership of the returned object.
+ // NULL is returned if the current thread doesn't have an associated Pepper
+ // message loop, or |func| is NULL.
+ static ThreadAwareCallback* Create(FuncType func) {
+ if (!func || !HasTargetLoop())
+ return NULL;
+ return new ThreadAwareCallback(func);
+ }
+
+ ~ThreadAwareCallback() {
+ }
+
+ void RunOnTargetThread() {
+ InternalRunOnTargetThread(base::Bind(func_));
+ }
+
+ template <class P1>
+ void RunOnTargetThread(const P1& p1) {
+ InternalRunOnTargetThread(base::Bind(func_, p1));
+ }
+
+ template <class P1, class P2>
+ void RunOnTargetThread(const P1& p1, const P2& p2) {
+ InternalRunOnTargetThread(base::Bind(func_, p1, p2));
+ }
+
+ template <class P1, class P2, class P3>
+ void RunOnTargetThread(const P1& p1, const P2& p2, const P3& p3) {
+ InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3));
+ }
+
+ template <class P1, class P2, class P3, class P4>
+ void RunOnTargetThread(const P1& p1,
+ const P2& p2,
+ const P3& p3,
+ const P4& p4) {
+ InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4));
+ }
+
+ template <class P1, class P2, class P3, class P4, class P5>
+ void RunOnTargetThread(const P1& p1,
+ const P2& p2,
+ const P3& p3,
+ const P4& p4,
+ const P5& p5) {
+ InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4, p5));
+ }
+
+ private:
+ explicit ThreadAwareCallback(FuncType func) : func_(func) {
+ }
+
+ FuncType func_;
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
diff --git a/ppapi/shared_impl/thread_aware_callback_unittest.cc b/ppapi/shared_impl/thread_aware_callback_unittest.cc
new file mode 100644
index 0000000..f86048a
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback_unittest.cc
@@ -0,0 +1,218 @@
+// 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/shared_impl/thread_aware_callback.h"
+
+#include "base/bind_helpers.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+
+namespace {
+
+class TestParameter {
+ public:
+ TestParameter() : value_(0) {
+ }
+
+ int value_;
+};
+
+int called_num = 0;
+
+void TestCallback_0() {
+ ++called_num;
+}
+
+void TestCallback_1(int p1) {
+ ++called_num;
+}
+
+void TestCallback_2(int p1, const double* p2) {
+ ++called_num;
+}
+
+void TestCallback_3(int p1, const double* p2, bool* p3) {
+ ++called_num;
+}
+
+void TestCallback_4(int p1, const double* p2, bool* p3, TestParameter p4) {
+ ++called_num;
+}
+
+void TestCallback_5(int p1,
+ const double* p2,
+ bool* p3,
+ TestParameter p4,
+ const TestParameter& p5) {
+ ++called_num;
+}
+
+typedef proxy::PluginProxyTest ThreadAwareCallbackTest;
+
+// Test that a callback created on the main thread will run on the main thread,
+// even when requested from a different thread.
+class ThreadAwareCallbackMultiThreadTest
+ : public proxy::PluginProxyMultiThreadTest {
+ public:
+ ThreadAwareCallbackMultiThreadTest() : main_thread_callback_called_(false) {
+ }
+ virtual ~ThreadAwareCallbackMultiThreadTest() {
+ CHECK(main_thread_callback_called_);
+ }
+
+ // proxy::PluginProxyMultiThreadTest implementation.
+ virtual void SetUpTestOnMainThread() OVERRIDE {
+ ProxyAutoLock auto_lock;
+
+ main_thread_callback_.reset(
+ ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
+ }
+
+ virtual void SetUpTestOnSecondaryThread() OVERRIDE {
+ {
+ ProxyAutoLock auto_lock;
+ main_thread_callback_->RunOnTargetThread(this);
+ }
+
+ PostQuitForSecondaryThread();
+ PostQuitForMainThread();
+ }
+
+ private:
+ typedef void (*CallbackFunc)(ThreadAwareCallbackMultiThreadTest*);
+
+ static void MainThreadCallbackBody(ThreadAwareCallbackMultiThreadTest* thiz) {
+ thiz->CheckOnThread(MAIN_THREAD);
+ thiz->main_thread_callback_called_ = true;
+
+ {
+ ProxyAutoLock auto_lock;
+ // We have to destroy it prior to the PluginGlobals instance held by the
+ // base class. Otherwise it has a ref to Pepper message loop for the main
+ // thread and the PluginGlobals destructor will complain.
+ thiz->main_thread_callback_.reset(NULL);
+ }
+ }
+
+ scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
+ bool main_thread_callback_called_;
+};
+
+// Test that when a ThreadAwareCallback instance is destroyed, pending tasks to
+// run the callback will be ignored.
+class ThreadAwareCallbackAbortTest : public proxy::PluginProxyMultiThreadTest {
+ public:
+ ThreadAwareCallbackAbortTest() {
+ }
+ virtual ~ThreadAwareCallbackAbortTest() {
+ }
+
+ // proxy::PluginProxyMultiThreadTest implementation.
+ virtual void SetUpTestOnMainThread() OVERRIDE {
+ ProxyAutoLock auto_lock;
+
+ main_thread_callback_.reset(
+ ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
+ }
+
+ virtual void SetUpTestOnSecondaryThread() OVERRIDE {
+ {
+ ProxyAutoLock auto_lock;
+ main_thread_message_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(&ThreadAwareCallbackAbortTest::DeleteCallback,
+ base::Unretained(this)));
+ // |main_thread_callback_| is still valid, even if DeleteCallback() can be
+ // called before this following statement. That is because |auto_lock| is
+ // still held by this method, which prevents DeleteCallback() from
+ // deleting the callback.
+ main_thread_callback_->RunOnTargetThread(this);
+ }
+
+ PostQuitForSecondaryThread();
+ PostQuitForMainThread();
+ }
+
+ private:
+ typedef void (*CallbackFunc)(ThreadAwareCallbackAbortTest*);
+
+ static void MainThreadCallbackBody(ThreadAwareCallbackAbortTest* thiz) {
+ // The callback should not be called.
+ ASSERT_TRUE(false);
+ }
+
+ void DeleteCallback() {
+ ProxyAutoLock auto_lock;
+ main_thread_callback_.reset(NULL);
+ }
+
+ scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
+};
+
+} // namespace
+
+TEST_F(ThreadAwareCallbackTest, Basics) {
+ // ThreadAwareCallback should only be used when the proxy lock has been
+ // acquired.
+ ProxyAutoLock auto_lock;
+
+ double double_arg = 0.0;
+ bool bool_arg = false;
+ TestParameter object_arg;
+
+ // Exercise all the template code.
+ called_num = 0;
+ typedef void (*FuncType_0)();
+ scoped_ptr<ThreadAwareCallback<FuncType_0> > callback_0(
+ ThreadAwareCallback<FuncType_0>::Create(TestCallback_0));
+ callback_0->RunOnTargetThread();
+
+ typedef void (*FuncType_1)(int);
+ scoped_ptr<ThreadAwareCallback<FuncType_1> > callback_1(
+ ThreadAwareCallback<FuncType_1>::Create(TestCallback_1));
+ callback_1->RunOnTargetThread(1);
+
+ typedef void (*FuncType_2)(int, const double*);
+ scoped_ptr<ThreadAwareCallback<FuncType_2> > callback_2(
+ ThreadAwareCallback<FuncType_2>::Create(TestCallback_2));
+ callback_2->RunOnTargetThread(1, &double_arg);
+
+ typedef void (*FuncType_3)(int, const double*, bool*);
+ scoped_ptr<ThreadAwareCallback<FuncType_3> > callback_3(
+ ThreadAwareCallback<FuncType_3>::Create(TestCallback_3));
+ callback_3->RunOnTargetThread(1, &double_arg, &bool_arg);
+
+ typedef void (*FuncType_4)(int, const double*, bool*, TestParameter);
+ scoped_ptr<ThreadAwareCallback<FuncType_4> > callback_4(
+ ThreadAwareCallback<FuncType_4>::Create(TestCallback_4));
+ callback_4->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg);
+
+ typedef void (*FuncType_5)(int,
+ const double*,
+ bool*,
+ TestParameter,
+ const TestParameter&);
+ scoped_ptr<ThreadAwareCallback<FuncType_5> > callback_5(
+ ThreadAwareCallback<FuncType_5>::Create(TestCallback_5));
+ callback_5->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg,
+ object_arg);
+
+ EXPECT_EQ(6, called_num);
+}
+
+TEST_F(ThreadAwareCallbackMultiThreadTest, RunOnTargetThread) {
+ RunTest();
+}
+
+TEST_F(ThreadAwareCallbackAbortTest, NotRunIfAborted) {
+ RunTest();
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/time_conversion.cc b/ppapi/shared_impl/time_conversion.cc
index 53d7b99..27ea494 100644
--- a/ppapi/shared_impl/time_conversion.cc
+++ b/ppapi/shared_impl/time_conversion.cc
@@ -30,6 +30,12 @@
}
base::Time PPTimeToTime(PP_Time t) {
+ // The time code handles exact "0" values as special, and produces
+ // a "null" Time object. But calling code would expect t==0 to represent the
+ // epoch (according to the description of PP_Time). Hence we just return the
+ // epoch in this case.
+ if (t == 0.0)
+ return base::Time::UnixEpoch();
return base::Time::FromDoubleT(t);
}
@@ -46,4 +52,20 @@
return t - GetTimeToTimeTicksDeltaInSeconds();
}
+double PPGetLocalTimeZoneOffset(const base::Time& time) {
+ // Explode it to local time and then unexplode it as if it were UTC. Also
+ // explode it to UTC and unexplode it (this avoids mismatching rounding or
+ // lack thereof). The time zone offset is their difference.
+ base::Time::Exploded exploded = { 0 };
+ base::Time::Exploded utc_exploded = { 0 };
+ time.LocalExplode(&exploded);
+ time.UTCExplode(&utc_exploded);
+ if (exploded.HasValidValues() && utc_exploded.HasValidValues()) {
+ base::Time adj_time = base::Time::FromUTCExploded(exploded);
+ base::Time cur = base::Time::FromUTCExploded(utc_exploded);
+ return (adj_time - cur).InSecondsF();
+ }
+ return 0.0;
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/time_conversion.h b/ppapi/shared_impl/time_conversion.h
index 0acd39e..e20d809 100644
--- a/ppapi/shared_impl/time_conversion.h
+++ b/ppapi/shared_impl/time_conversion.h
@@ -23,6 +23,11 @@
PPAPI_SHARED_EXPORT PP_TimeTicks EventTimeToPPTimeTicks(double event_time);
PPAPI_SHARED_EXPORT double PPTimeTicksToEventTime(PP_TimeTicks t);
+// Gets the local time zone offset for a given time. This works in the plugin
+// process only on Windows (the sandbox prevents this from working properly on
+// other platforms).
+PPAPI_SHARED_EXPORT double PPGetLocalTimeZoneOffset(const base::Time& time);
+
} // namespace ppapi
#endif // PPAPI_SHARED_IMPL_TIME_CONVERSION_H_
diff --git a/ppapi/shared_impl/time_conversion_unittest.cc b/ppapi/shared_impl/time_conversion_unittest.cc
new file mode 100644
index 0000000..1ec70bf
--- /dev/null
+++ b/ppapi/shared_impl/time_conversion_unittest.cc
@@ -0,0 +1,73 @@
+// 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 <math.h>
+#include <stdlib.h>
+
+#include "ppapi/shared_impl/time_conversion.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+
+// Slop we'll allow in two Time "internal values" to consider them equal.
+// Double conversion can introduce rounding errors. The internal values are in
+// microseconds, so an error here is very small.
+static const int kTimeInternalValueSlop = 2;
+
+// Same as above in double-precision seconds units.
+static const double kTimeSecondsSlop =
+ static_cast<double>(kTimeInternalValueSlop) /
+ base::Time::kMicrosecondsPerSecond;
+
+TEST(TimeConversion, Time) {
+ // Should be able to round-trip.
+ base::Time now = base::Time::Now();
+ base::Time converted = ppapi::PPTimeToTime(TimeToPPTime(now));
+ EXPECT_GE(kTimeInternalValueSlop,
+ abs(static_cast<int>((converted - now).ToInternalValue())));
+
+ // Units should be in seconds.
+ base::Time one_second_from_now = now + base::TimeDelta::FromSeconds(1);
+ double converted_one_second_from_now =
+ ppapi::TimeToPPTime(one_second_from_now) - ppapi::TimeToPPTime(now);
+ EXPECT_GE(kTimeSecondsSlop, fabs(converted_one_second_from_now - 1));
+}
+
+TEST(TimeConversion, EventTime) {
+ // Should be able to round-trip.
+ base::Time now = base::Time::Now();
+ double event_now = now.ToDoubleT();
+ double converted =
+ ppapi::EventTimeToPPTimeTicks(ppapi::PPTimeTicksToEventTime(event_now));
+ EXPECT_GE(kTimeSecondsSlop, fabs(converted - event_now));
+
+ // Units should be in seconds.
+ base::Time one_second_from_now = now + base::TimeDelta::FromSeconds(1);
+ double event_one_second_from_now = one_second_from_now.ToDoubleT();
+ EXPECT_GE(kTimeSecondsSlop,
+ 1.0 - ppapi::EventTimeToPPTimeTicks(event_one_second_from_now) -
+ ppapi::EventTimeToPPTimeTicks(event_now));
+}
+
+TEST(TimeConversion, EpochTime) {
+ // Should be able to round-trip from epoch time.
+ base::Time epoch = base::Time::UnixEpoch();
+ base::Time converted = ppapi::PPTimeToTime(TimeToPPTime(epoch));
+ EXPECT_GE(kTimeInternalValueSlop,
+ abs(static_cast<int>((converted - epoch).ToInternalValue())));
+
+ // Units should be in seconds.
+ base::Time one_second_from_epoch = epoch + base::TimeDelta::FromSeconds(1);
+ double converted_one_second_from_epoch =
+ ppapi::TimeToPPTime(one_second_from_epoch) - ppapi::TimeToPPTime(epoch);
+ EXPECT_GE(kTimeSecondsSlop, fabs(converted_one_second_from_epoch - 1));
+
+ // Epoch time should be equal to a PP_Time of 0.0.
+ EXPECT_GE(kTimeSecondsSlop, fabs(ppapi::TimeToPPTime(epoch) - 0.0));
+ EXPECT_GE(kTimeInternalValueSlop,
+ abs(static_cast<int>(
+ (ppapi::PPTimeToTime(0.0) - epoch).ToInternalValue())));
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/tracked_callback.cc b/ppapi/shared_impl/tracked_callback.cc
index bd011df..ae4656e 100644
--- a/ppapi/shared_impl/tracked_callback.cc
+++ b/ppapi/shared_impl/tracked_callback.cc
@@ -9,9 +9,9 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/synchronization/lock.h"
-#include "ppapi/c/dev/ppb_message_loop_dev.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_message_loop.h"
#include "ppapi/shared_impl/callback_tracker.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/ppb_message_loop_shared.h"
diff --git a/ppapi/shared_impl/tracked_callback_unittest.cc b/ppapi/shared_impl/tracked_callback_unittest.cc
index ca4d3b1..bc1c7f3 100644
--- a/ppapi/shared_impl/tracked_callback_unittest.cc
+++ b/ppapi/shared_impl/tracked_callback_unittest.cc
@@ -220,18 +220,18 @@
// Kill resource #1, spin the message loop to run posted calls, and check that
// things are in the expected states.
resource_tracker->ReleaseResource(resource_1_id);
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
resource_1->CheckFinalState();
resource_2->CheckIntermediateState();
// Kill resource #2.
resource_tracker->ReleaseResource(resource_2_id);
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
resource_1->CheckFinalState();
resource_2->CheckFinalState();
// This shouldn't be needed, but make sure there are no stranded tasks.
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
}
// Test that "resurrecting" a resource (getting a new ID for a |Resource|)
@@ -247,21 +247,21 @@
// Unref it, spin the message loop to run posted calls, and check that things
// are in the expected states.
resource_tracker->ReleaseResource(resource_id);
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
resource->CheckFinalState();
// "Resurrect" it and check that the callbacks are still dead.
PP_Resource new_resource_id = resource->GetReference();
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
resource->CheckFinalState();
// Unref it again and do the same.
resource_tracker->ReleaseResource(new_resource_id);
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
resource->CheckFinalState();
// This shouldn't be needed, but make sure there are no stranded tasks.
- MessageLoop::current()->RunAllPending();
+ MessageLoop::current()->RunUntilIdle();
}
} // namespace ppapi
diff --git a/ppapi/shared_impl/url_response_info_data.cc b/ppapi/shared_impl/url_response_info_data.cc
new file mode 100644
index 0000000..0b4b078
--- /dev/null
+++ b/ppapi/shared_impl/url_response_info_data.cc
@@ -0,0 +1,15 @@
+// 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/shared_impl/url_response_info_data.h"
+
+namespace ppapi {
+
+URLResponseInfoData::URLResponseInfoData() : status_code(-1) {
+}
+
+URLResponseInfoData::~URLResponseInfoData() {
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/url_response_info_data.h b/ppapi/shared_impl/url_response_info_data.h
new file mode 100644
index 0000000..a40ca50
--- /dev/null
+++ b/ppapi/shared_impl/url_response_info_data.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_
+#define PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_
+
+#include <string>
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/ppb_file_ref_shared.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace ppapi {
+
+struct PPAPI_SHARED_EXPORT URLResponseInfoData {
+ URLResponseInfoData();
+ ~URLResponseInfoData();
+
+ std::string url;
+ std::string headers;
+ int32_t status_code;
+ std::string status_text;
+ std::string redirect_url;
+
+ // Nonzero when streaming to a file.
+ PPB_FileRef_CreateInfo body_as_file_ref;
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_URL_RESPONSE_INFO_DATA_H_
diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc
index 2e63dbe..0aff583 100644
--- a/ppapi/shared_impl/var.cc
+++ b/ppapi/shared_impl/var.cc
@@ -56,6 +56,12 @@
}
case PP_VARTYPE_OBJECT:
return "[Object]";
+ case PP_VARTYPE_ARRAY:
+ return "[Array]";
+ case PP_VARTYPE_DICTIONARY:
+ return "[Dictionary]";
+ case PP_VARTYPE_ARRAY_BUFFER:
+ return "[Array buffer]";
default:
return "[Invalid var]";
}
@@ -77,6 +83,14 @@
return NULL;
}
+ArrayVar* Var::AsArrayVar() {
+ return NULL;
+}
+
+DictionaryVar* Var::AsDictionaryVar() {
+ return NULL;
+}
+
PP_Var Var::GetPPVar() {
int32 id = GetOrCreateVarID();
if (!id)
diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h
index 77f707c..50c13b9 100644
--- a/ppapi/shared_impl/var.h
+++ b/ppapi/shared_impl/var.h
@@ -9,12 +9,17 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
+#include "base/platform_file.h"
+#include "base/shared_memory.h"
#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/host_resource.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
namespace ppapi {
class ArrayBufferVar;
+class ArrayVar;
+class DictionaryVar;
class NPObjectVar;
class ProxyObjectVar;
class StringVar;
@@ -34,6 +39,8 @@
virtual ArrayBufferVar* AsArrayBufferVar();
virtual NPObjectVar* AsNPObjectVar();
virtual ProxyObjectVar* AsProxyObjectVar();
+ virtual ArrayVar* AsArrayVar();
+ virtual DictionaryVar* AsDictionaryVar();
// Creates a PP_Var corresponding to this object. The return value will have
// one reference addrefed on behalf of the caller.
@@ -156,6 +163,18 @@
virtual void Unmap() = 0;
virtual uint32 ByteLength() = 0;
+ // Creates a new shared memory region, and copies the data in the
+ // ArrayBufferVar into it. On the plugin side, host_shm_handle_id will be set
+ // to some value that is not -1. On the host side, plugin_shm_handle will be
+ // set to a valid SharedMemoryHandle.
+ //
+ // Returns true if creating the shared memory (and copying) is successful,
+ // false otherwise.
+ virtual bool CopyToNewShmem(
+ PP_Instance instance,
+ int *host_shm_handle_id,
+ base::SharedMemoryHandle *plugin_shm_handle) = 0;
+
// Var override.
virtual ArrayBufferVar* AsArrayBufferVar() OVERRIDE;
virtual PP_VarType GetType() const OVERRIDE;
diff --git a/ppapi/shared_impl/var_tracker.cc b/ppapi/shared_impl/var_tracker.cc
index 8214a30..434121e 100644
--- a/ppapi/shared_impl/var_tracker.cc
+++ b/ppapi/shared_impl/var_tracker.cc
@@ -9,7 +9,10 @@
#include <limits>
#include "base/logging.h"
+#include "base/shared_memory.h"
+#include "ppapi/shared_impl/host_resource.h"
#include "ppapi/shared_impl/id_assignment.h"
+#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/var.h"
namespace ppapi {
@@ -34,12 +37,14 @@
int32 VarTracker::AddVar(Var* var) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
return AddVarInternal(var, ADD_VAR_TAKE_ONE_REFERENCE);
}
Var* VarTracker::GetVar(int32 var_id) const {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
VarMap::const_iterator result = live_vars_.find(var_id);
if (result == live_vars_.end())
@@ -49,6 +54,7 @@
Var* VarTracker::GetVar(const PP_Var& var) const {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
if (!IsVarTypeRefcounted(var.type))
return NULL;
@@ -57,6 +63,7 @@
bool VarTracker::AddRefVar(int32 var_id) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
<< var_id << " is not a PP_Var ID.";
@@ -82,14 +89,16 @@
bool VarTracker::AddRefVar(const PP_Var& var) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
if (!IsVarTypeRefcounted(var.type))
- return false;
+ return true;
return AddRefVar(static_cast<int32>(var.value.as_id));
}
bool VarTracker::ReleaseVar(int32 var_id) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
DLOG_IF(ERROR, !CheckIdType(var_id, PP_ID_TYPE_VAR))
<< var_id << " is not a PP_Var ID.";
@@ -121,6 +130,7 @@
bool VarTracker::ReleaseVar(const PP_Var& var) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
if (!IsVarTypeRefcounted(var.type))
return false;
@@ -145,6 +155,7 @@
int VarTracker::GetRefCountForObject(const PP_Var& plugin_object) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
VarMap::iterator found = GetLiveVar(plugin_object);
if (found == live_vars_.end())
@@ -155,6 +166,7 @@
int VarTracker::GetTrackedWithNoReferenceCountForObject(
const PP_Var& plugin_object) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
VarMap::iterator found = GetLiveVar(plugin_object);
if (found == live_vars_.end())
@@ -177,6 +189,7 @@
PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
scoped_refptr<ArrayBufferVar> array_buffer(CreateArrayBuffer(size_in_bytes));
if (!array_buffer)
@@ -187,16 +200,38 @@
PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes,
const void* data) {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
- scoped_refptr<ArrayBufferVar> array_buffer(CreateArrayBuffer(size_in_bytes));
+ ArrayBufferVar* array_buffer = MakeArrayBufferVar(size_in_bytes, data);
+ return array_buffer ? array_buffer->GetPPVar() : PP_MakeNull();
+}
+
+ArrayBufferVar* VarTracker::MakeArrayBufferVar(uint32 size_in_bytes,
+ const void* data) {
+ DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
+
+ ArrayBufferVar* array_buffer(CreateArrayBuffer(size_in_bytes));
+ if (!array_buffer)
+ return NULL;
+ memcpy(array_buffer->Map(), data, size_in_bytes);
+ return array_buffer;
+}
+
+PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes,
+ base::SharedMemoryHandle handle) {
+ DCHECK(CalledOnValidThread());
+
+ scoped_refptr<ArrayBufferVar> array_buffer(
+ CreateShmArrayBuffer(size_in_bytes, handle));
if (!array_buffer)
return PP_MakeNull();
- memcpy(array_buffer->Map(), data, size_in_bytes);
return array_buffer->GetPPVar();
}
std::vector<PP_Var> VarTracker::GetLiveVars() {
DCHECK(CalledOnValidThread());
+ ProxyLock::AssertAcquired();
std::vector<PP_Var> var_vector;
var_vector.reserve(live_vars_.size());
diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h
index b873250..32acdeb 100644
--- a/ppapi/shared_impl/var_tracker.h
+++ b/ppapi/shared_impl/var_tracker.h
@@ -10,10 +10,13 @@
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
+#include "base/shared_memory.h"
#include "base/threading/non_thread_safe.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/host_resource.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
namespace ppapi {
@@ -72,6 +75,16 @@
PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes);
// Same as above, but copy the contents of |data| in to the new array buffer.
PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes, const void* data);
+ // Same as above, but copy the contents of the shared memory in |h|
+ // into the new array buffer.
+ PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes,
+ base::SharedMemoryHandle h);
+
+ // Create an ArrayBuffer and copy the contents of |data| in to it. The
+ // returned object has 0 reference count in the tracker, and like all
+ // RefCounted objects, has a 0 initial internal reference count. (You should
+ // usually immediately put this in a scoped_refptr).
+ ArrayBufferVar* MakeArrayBufferVar(uint32 size_in_bytes, const void* data);
// Return a vector containing all PP_Vars that are in the tracker. This is
// to help implement PPB_Testing_Dev.GetLiveVars and should generally not be
@@ -88,6 +101,22 @@
// Called after an instance is deleted to do var cleanup.
virtual void DidDeleteInstance(PP_Instance instance) = 0;
+ // Returns an "id" for a shared memory handle that can be safely sent between
+ // the host and plugin, and resolved back into the original handle on the
+ // host. Not implemented on the plugin side.
+ virtual int TrackSharedMemoryHandle(PP_Instance instance,
+ base::SharedMemoryHandle handle,
+ uint32 size_in_bytes) = 0;
+
+ // Resolves an "id" generated by TrackSharedMemoryHandle back into
+ // a SharedMemory handle and its size on the host.
+ // Not implemented on the plugin side.
+ virtual bool StopTrackingSharedMemoryHandle(
+ int id,
+ PP_Instance instance,
+ base::SharedMemoryHandle *handle,
+ uint32* size_in_bytes) = 0;
+
protected:
struct VarInfo {
VarInfo();
@@ -165,6 +194,9 @@
// implemented by the Host and Plugin tracker separately, so that it can be
// a real WebKit ArrayBuffer on the host side.
virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) = 0;
+ virtual ArrayBufferVar* CreateShmArrayBuffer(
+ uint32 size_in_bytes,
+ base::SharedMemoryHandle handle) = 0;
DISALLOW_COPY_AND_ASSIGN(VarTracker);
};
diff --git a/ppapi/shared_impl/var_value_conversions.cc b/ppapi/shared_impl/var_value_conversions.cc
new file mode 100644
index 0000000..614002a
--- /dev/null
+++ b/ppapi/shared_impl/var_value_conversions.cc
@@ -0,0 +1,344 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/var_value_conversions.h"
+
+#include <limits>
+#include <set>
+#include <stack>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+namespace ppapi {
+
+namespace {
+
+// In CreateValueFromVar(), a stack is used to keep track of conversion progress
+// of array and dictionary vars. VarNode represents elements of that stack.
+struct VarNode {
+ VarNode(const PP_Var& in_var, base::Value* in_value)
+ : var(in_var),
+ value(in_value),
+ sentinel(false) {
+ }
+
+ // This object doesn't hold a reference to it.
+ PP_Var var;
+ // It is not owned by this object.
+ base::Value* value;
+ // When this is set to true for a node in the stack, it means that we have
+ // finished processing the node itself. However, we keep it in the stack as
+ // a sentinel. When it becomes the top element of the stack again, we know
+ // that we have processed all the descendants of this node.
+ bool sentinel;
+};
+
+// In CreateVarFromValue(), a stack is used to keep track of conversion progress
+// of list and dictionary values. ValueNode represents elements of that stack.
+struct ValueNode {
+ ValueNode(const PP_Var& in_var, const base::Value* in_value)
+ : var(in_var),
+ value(in_value) {
+ }
+
+ // This object doesn't hold a reference to it.
+ PP_Var var;
+ // It is not owned by this object.
+ const base::Value* value;
+};
+
+// Helper function for CreateValueFromVar(). It only looks at |var| but not its
+// descendants. The conversion result is stored in |value|. If |var| is array or
+// dictionary, a new node is pushed onto |state|.
+//
+// Returns false on failure.
+bool CreateValueFromVarHelper(const std::set<int64_t>& parent_ids,
+ const PP_Var& var,
+ scoped_ptr<base::Value>* value,
+ std::stack<VarNode>* state) {
+ switch (var.type) {
+ case PP_VARTYPE_UNDEFINED:
+ case PP_VARTYPE_NULL: {
+ value->reset(base::Value::CreateNullValue());
+ return true;
+ }
+ case PP_VARTYPE_BOOL: {
+ value->reset(new base::FundamentalValue(PP_ToBool(var.value.as_bool)));
+ return true;
+ }
+ case PP_VARTYPE_INT32: {
+ value->reset(new base::FundamentalValue(var.value.as_int));
+ return true;
+ }
+ case PP_VARTYPE_DOUBLE: {
+ value->reset(new base::FundamentalValue(var.value.as_double));
+ return true;
+ }
+ case PP_VARTYPE_STRING: {
+ StringVar* string_var = StringVar::FromPPVar(var);
+ if (!string_var)
+ return false;
+
+ value->reset(new base::StringValue(string_var->value()));
+ return true;
+ }
+ case PP_VARTYPE_OBJECT: {
+ return false;
+ }
+ case PP_VARTYPE_ARRAY: {
+ if (ContainsKey(parent_ids, var.value.as_id)) {
+ // A circular reference is found.
+ return false;
+ }
+
+ value->reset(new base::ListValue());
+ state->push(VarNode(var, value->get()));
+ return true;
+ }
+ case PP_VARTYPE_DICTIONARY: {
+ if (ContainsKey(parent_ids, var.value.as_id)) {
+ // A circular reference is found.
+ return false;
+ }
+
+ value->reset(new base::DictionaryValue());
+ state->push(VarNode(var, value->get()));
+ return true;
+ }
+ case PP_VARTYPE_ARRAY_BUFFER: {
+ ArrayBufferVar* array_buffer = ArrayBufferVar::FromPPVar(var);
+ if (!array_buffer)
+ return false;
+
+ base::BinaryValue* binary_value =
+ base::BinaryValue::CreateWithCopiedBuffer(
+ static_cast<const char*>(array_buffer->Map()),
+ array_buffer->ByteLength());
+ array_buffer->Unmap();
+ value->reset(binary_value);
+ return true;
+ }
+ }
+ NOTREACHED();
+ return false;
+}
+
+// Helper function for CreateVarFromValue(). It only looks at |value| but not
+// its descendants. The conversion result is stored in |var|. If |value| is list
+// or dictionary, a new node is pushed onto |state|.
+//
+// Returns false on failure.
+bool CreateVarFromValueHelper(const base::Value& value,
+ ScopedPPVar* var,
+ std::stack<ValueNode>* state) {
+ switch (value.GetType()) {
+ case base::Value::TYPE_NULL: {
+ *var = PP_MakeNull();
+ return true;
+ }
+ case base::Value::TYPE_BOOLEAN: {
+ bool result = false;
+ if (value.GetAsBoolean(&result)) {
+ *var = PP_MakeBool(PP_FromBool(result));
+ return true;
+ }
+ return false;
+ }
+ case base::Value::TYPE_INTEGER: {
+ int result = 0;
+ if (value.GetAsInteger(&result)) {
+ *var = PP_MakeInt32(result);
+ return true;
+ }
+ return false;
+ }
+ case base::Value::TYPE_DOUBLE: {
+ double result = 0;
+ if (value.GetAsDouble(&result)) {
+ *var = PP_MakeDouble(result);
+ return true;
+ }
+ return false;
+ }
+ case base::Value::TYPE_STRING: {
+ std::string result;
+ if (value.GetAsString(&result)) {
+ *var = ScopedPPVar(ScopedPPVar::PassRef(),
+ StringVar::StringToPPVar(result));
+ return true;
+ }
+ return false;
+ }
+ case base::Value::TYPE_BINARY: {
+ const base::BinaryValue& binary_value =
+ static_cast<const base::BinaryValue&>(value);
+
+ size_t size = binary_value.GetSize();
+ if (size > std::numeric_limits<uint32>::max())
+ return false;
+
+ ScopedPPVar temp(
+ ScopedPPVar::PassRef(),
+ PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
+ static_cast<uint32>(size), binary_value.GetBuffer()));
+ if (temp.get().type == PP_VARTYPE_ARRAY_BUFFER) {
+ *var = temp;
+ return true;
+ }
+ return false;
+ }
+ case base::Value::TYPE_DICTIONARY: {
+ scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+ *var = ScopedPPVar(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+ state->push(ValueNode(var->get(), &value));
+ return true;
+ }
+ case base::Value::TYPE_LIST: {
+ scoped_refptr<ArrayVar> array_var(new ArrayVar());
+ *var = ScopedPPVar(ScopedPPVar::PassRef(), array_var->GetPPVar());
+ state->push(ValueNode(var->get(), &value));
+ return true;
+ }
+ }
+ NOTREACHED();
+ return false;
+}
+
+} // namespace
+
+base::Value* CreateValueFromVar(const PP_Var& var) {
+ // Used to detect circular references.
+ std::set<int64_t> parent_ids;
+ std::stack<VarNode> state;
+ scoped_ptr<base::Value> root_value;
+
+ if (!CreateValueFromVarHelper(parent_ids, var, &root_value, &state))
+ return NULL;
+
+ while (!state.empty()) {
+ VarNode& top = state.top();
+ if (top.sentinel) {
+ parent_ids.erase(top.var.value.as_id);
+ state.pop();
+ } else if (top.var.type == PP_VARTYPE_DICTIONARY) {
+ parent_ids.insert(top.var.value.as_id);
+ top.sentinel = true;
+
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(top.var);
+ if (!dict_var)
+ return NULL;
+
+ DCHECK(top.value->GetType() == base::Value::TYPE_DICTIONARY);
+ base::DictionaryValue* dict_value =
+ static_cast<base::DictionaryValue*>(top.value);
+
+ for (DictionaryVar::KeyValueMap::const_iterator iter =
+ dict_var->key_value_map().begin();
+ iter != dict_var->key_value_map().end();
+ ++iter) {
+ // Skip the key-value pair if the value is undefined.
+ if (iter->second.get().type == PP_VARTYPE_UNDEFINED)
+ continue;
+
+ scoped_ptr<base::Value> child_value;
+ if (!CreateValueFromVarHelper(parent_ids, iter->second.get(),
+ &child_value, &state)) {
+ return NULL;
+ }
+
+ dict_value->SetWithoutPathExpansion(iter->first, child_value.release());
+ }
+ } else if (top.var.type == PP_VARTYPE_ARRAY) {
+ parent_ids.insert(top.var.value.as_id);
+ top.sentinel = true;
+
+ ArrayVar* array_var = ArrayVar::FromPPVar(top.var);
+ if (!array_var)
+ return NULL;
+
+ DCHECK(top.value->GetType() == base::Value::TYPE_LIST);
+ base::ListValue* list_value = static_cast<base::ListValue*>(top.value);
+
+ for (ArrayVar::ElementVector::const_iterator iter =
+ array_var->elements().begin();
+ iter != array_var->elements().end();
+ ++iter) {
+ scoped_ptr<base::Value> child_value;
+ if (!CreateValueFromVarHelper(parent_ids, iter->get(), &child_value,
+ &state)) {
+ return NULL;
+ }
+
+ list_value->Append(child_value.release());
+ }
+ } else {
+ NOTREACHED();
+ return NULL;
+ }
+ }
+ DCHECK(parent_ids.empty());
+ return root_value.release();
+}
+
+PP_Var CreateVarFromValue(const base::Value& value) {
+ std::stack<ValueNode> state;
+ ScopedPPVar root_var;
+
+ if (!CreateVarFromValueHelper(value, &root_var, &state))
+ return PP_MakeUndefined();
+
+ while (!state.empty()) {
+ ValueNode top = state.top();
+ state.pop();
+
+ if (top.value->GetType() == base::Value::TYPE_DICTIONARY) {
+ const base::DictionaryValue* dict_value =
+ static_cast<const base::DictionaryValue*>(top.value);
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(top.var);
+ DCHECK(dict_var);
+ for (base::DictionaryValue::Iterator iter(*dict_value);
+ !iter.IsAtEnd();
+ iter.Advance()) {
+ ScopedPPVar child_var;
+ if (!CreateVarFromValueHelper(iter.value(), &child_var, &state) ||
+ !dict_var->SetWithStringKey(iter.key(), child_var.get())) {
+ return PP_MakeUndefined();
+ }
+ }
+ } else if (top.value->GetType() == base::Value::TYPE_LIST) {
+ const base::ListValue* list_value =
+ static_cast<const base::ListValue*>(top.value);
+ ArrayVar* array_var = ArrayVar::FromPPVar(top.var);
+ DCHECK(array_var);
+ for (base::ListValue::const_iterator iter = list_value->begin();
+ iter != list_value->end();
+ ++iter) {
+ ScopedPPVar child_var;
+ if (!CreateVarFromValueHelper(**iter, &child_var, &state))
+ return PP_MakeUndefined();
+
+ array_var->elements().push_back(child_var);
+ }
+ } else {
+ NOTREACHED();
+ return PP_MakeUndefined();
+ }
+ }
+
+ return root_var.Release();
+}
+} // namespace ppapi
+
diff --git a/ppapi/shared_impl/var_value_conversions.h b/ppapi/shared_impl/var_value_conversions.h
new file mode 100644
index 0000000..09145ce
--- /dev/null
+++ b/ppapi/shared_impl/var_value_conversions.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_SHARED_IMPL_VAR_VALUE_CONVERSIONS_H_
+#define PPAPI_SHARED_IMPL_VAR_VALUE_CONVERSIONS_H_
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/ppapi_shared_export.h"
+
+namespace base {
+class Value;
+}
+
+namespace ppapi {
+
+// Converts a PP_Var to a base::Value object. The caller takes ownership of the
+// returned object.
+//
+// Both PP_VARTYPE_UNDEFINED and PP_VARTYPE_NULL are converted to
+// base::Value::TYPE_NULL. In dictionary vars, key-value pairs whose value is
+// undefined (PP_VARTYPE_UNDEFINED) are ignored. If a node in |var| appears more
+// than once, it is duplicated in the result. For example, if |var| is an array
+// and it has two elements pointing to the same dictionary, the resulting list
+// value will have two copies of the dictionary.
+//
+// The conversion fails and returns NULL if
+// - |var| is object (PP_VARTYPE_OBJECT); or
+// - |var| is an array or dictionary, and calling CreateValueFromVar() on any of
+// the array elements or dictionary values fails; or
+// - there exist circular references, i.e., an array or dictionary is its own
+// ancestor/descendant.
+PPAPI_SHARED_EXPORT base::Value* CreateValueFromVar(const PP_Var& var);
+
+// The returned var has been added ref on behalf of the caller.
+// Returns an undefined var if the conversion fails.
+PPAPI_SHARED_EXPORT PP_Var CreateVarFromValue(const base::Value& value);
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_VAR_VALUE_CONVERSIONS_H_
diff --git a/ppapi/shared_impl/var_value_conversions_unittest.cc b/ppapi/shared_impl/var_value_conversions_unittest.cc
new file mode 100644
index 0000000..8dd2c42
--- /dev/null
+++ b/ppapi/shared_impl/var_value_conversions_unittest.cc
@@ -0,0 +1,316 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/var_value_conversions.h"
+
+#include <cmath>
+#include <cstring>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/shared_impl/array_var.h"
+#include "ppapi/shared_impl/dictionary_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/proxy_lock.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/test_globals.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+namespace {
+
+bool Equals(const base::Value& value, const PP_Var& var) {
+ switch (value.GetType()) {
+ case base::Value::TYPE_NULL: {
+ return var.type == PP_VARTYPE_NULL || var.type == PP_VARTYPE_UNDEFINED;
+ }
+ case base::Value::TYPE_BOOLEAN: {
+ bool result = false;
+ return var.type == PP_VARTYPE_BOOL &&
+ value.GetAsBoolean(&result) &&
+ result == PP_ToBool(var.value.as_bool);
+ }
+ case base::Value::TYPE_INTEGER: {
+ int result = 0;
+ return var.type == PP_VARTYPE_INT32 &&
+ value.GetAsInteger(&result) &&
+ result == var.value.as_int;
+ }
+ case base::Value::TYPE_DOUBLE: {
+ double result = 0;
+ return var.type == PP_VARTYPE_DOUBLE &&
+ value.GetAsDouble(&result) &&
+ fabs(result - var.value.as_double) < 1.0e-4;
+ }
+ case base::Value::TYPE_STRING: {
+ std::string result;
+ StringVar* string_var = StringVar::FromPPVar(var);
+ return string_var &&
+ value.GetAsString(&result) &&
+ result == string_var->value();
+ }
+ case base::Value::TYPE_BINARY: {
+ const base::BinaryValue& binary_value =
+ static_cast<const base::BinaryValue&>(value);
+ ArrayBufferVar* array_buffer_var = ArrayBufferVar::FromPPVar(var);
+ if (!array_buffer_var ||
+ binary_value.GetSize() != array_buffer_var->ByteLength()) {
+ return false;
+ }
+
+ bool result = !memcmp(binary_value.GetBuffer(), array_buffer_var->Map(),
+ binary_value.GetSize());
+ array_buffer_var->Unmap();
+ return result;
+ }
+ case base::Value::TYPE_DICTIONARY: {
+ const base::DictionaryValue& dict_value =
+ static_cast<const base::DictionaryValue&>(value);
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(var);
+ if (!dict_var)
+ return false;
+
+ size_t non_undefined_count = 0;
+ for (DictionaryVar::KeyValueMap::const_iterator iter =
+ dict_var->key_value_map().begin();
+ iter != dict_var->key_value_map().end();
+ ++iter) {
+ if (iter->second.get().type == PP_VARTYPE_UNDEFINED)
+ continue;
+
+ ++non_undefined_count;
+ const base::Value* sub_value = NULL;
+ if (!dict_value.GetWithoutPathExpansion(iter->first, &sub_value) ||
+ !Equals(*sub_value, iter->second.get())) {
+ return false;
+ }
+ }
+ return non_undefined_count == dict_value.size();
+ }
+ case base::Value::TYPE_LIST: {
+ const base::ListValue& list_value =
+ static_cast<const base::ListValue&>(value);
+ ArrayVar* array_var = ArrayVar::FromPPVar(var);
+ if (!array_var || list_value.GetSize() != array_var->elements().size())
+ return false;
+
+ base::ListValue::const_iterator value_iter = list_value.begin();
+ ArrayVar::ElementVector::const_iterator var_iter =
+ array_var->elements().begin();
+ for (; value_iter != list_value.end() &&
+ var_iter != array_var->elements().end();
+ ++value_iter, ++var_iter) {
+ if (!Equals(**value_iter, var_iter->get()))
+ return false;
+ }
+ return true;
+ }
+ }
+ NOTREACHED();
+ return false;
+}
+
+class VarValueConversionsTest : public testing::Test {
+ public:
+ VarValueConversionsTest() {
+ }
+ virtual ~VarValueConversionsTest() {
+ }
+
+ // testing::Test implementation.
+ virtual void SetUp() {
+ ProxyLock::Acquire();
+ }
+ virtual void TearDown() {
+ ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty());
+ ProxyLock::Release();
+ }
+
+ private:
+ TestGlobals globals_;
+};
+
+} // namespace
+
+TEST_F(VarValueConversionsTest, CreateValueFromVar) {
+ {
+ // Var holding a ref to itself is not a valid input.
+ scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+ ScopedPPVar var_1(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+ scoped_refptr<ArrayVar> array_var(new ArrayVar());
+ ScopedPPVar var_2(ScopedPPVar::PassRef(), array_var->GetPPVar());
+
+ ASSERT_TRUE(dict_var->SetWithStringKey("key_1", var_2.get()));
+ scoped_ptr<base::Value> value(CreateValueFromVar(var_1.get()));
+ ASSERT_TRUE(value.get());
+
+ ASSERT_TRUE(array_var->Set(0, var_1.get()));
+ value.reset(CreateValueFromVar(var_1.get()));
+ ASSERT_EQ(NULL, value.get());
+
+ // Make sure |var_1| doesn't indirectly hold a ref to itself, otherwise it
+ // is leaked.
+ dict_var->DeleteWithStringKey("key_1");
+ }
+
+ // Vars of null or undefined type are converted to null values.
+ {
+ scoped_ptr<base::Value> value(CreateValueFromVar(PP_MakeNull()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, PP_MakeNull()));
+
+ value.reset(CreateValueFromVar(PP_MakeUndefined()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, PP_MakeUndefined()));
+ }
+
+ {
+ // Test empty dictionary.
+ scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+ ScopedPPVar var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+ scoped_ptr<base::Value> value(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+ }
+
+ {
+ // Key-value pairs whose value is undefined are ignored.
+ scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+ ASSERT_TRUE(dict_var->SetWithStringKey("key_1", PP_MakeUndefined()));
+ ASSERT_TRUE(dict_var->SetWithStringKey("key_2", PP_MakeInt32(1)));
+ ScopedPPVar var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+ scoped_ptr<base::Value> value(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+ }
+
+ {
+ // The same PP_Var is allowed to appear multiple times.
+ scoped_refptr<DictionaryVar> dict_var_1(new DictionaryVar());
+ ScopedPPVar dict_pp_var_1(ScopedPPVar::PassRef(), dict_var_1->GetPPVar());
+ scoped_refptr<DictionaryVar> dict_var_2(new DictionaryVar());
+ ScopedPPVar dict_pp_var_2(ScopedPPVar::PassRef(), dict_var_2->GetPPVar());
+ scoped_refptr<StringVar> string_var(new StringVar("string_value"));
+ ScopedPPVar string_pp_var(ScopedPPVar::PassRef(), string_var->GetPPVar());
+
+ ASSERT_TRUE(dict_var_1->SetWithStringKey("key_1", dict_pp_var_2.get()));
+ ASSERT_TRUE(dict_var_1->SetWithStringKey("key_2", dict_pp_var_2.get()));
+ ASSERT_TRUE(dict_var_1->SetWithStringKey("key_3", string_pp_var.get()));
+ ASSERT_TRUE(dict_var_2->SetWithStringKey("key_4", string_pp_var.get()));
+
+ scoped_ptr<base::Value> value(CreateValueFromVar(dict_pp_var_1.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, dict_pp_var_1.get()));
+ }
+
+ {
+ // Test basic cases for array.
+ scoped_refptr<ArrayVar> array_var(new ArrayVar());
+ ScopedPPVar var(ScopedPPVar::PassRef(), array_var->GetPPVar());
+
+ scoped_ptr<base::Value> value(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+
+ ASSERT_TRUE(array_var->Set(0, PP_MakeDouble(1)));
+ value.reset(CreateValueFromVar(var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, var.get()));
+ }
+
+ {
+ // Test more complex inputs.
+ scoped_refptr<DictionaryVar> dict_var_1(new DictionaryVar());
+ ScopedPPVar dict_pp_var_1(ScopedPPVar::PassRef(), dict_var_1->GetPPVar());
+ scoped_refptr<DictionaryVar> dict_var_2(new DictionaryVar());
+ ScopedPPVar dict_pp_var_2(ScopedPPVar::PassRef(), dict_var_2->GetPPVar());
+ scoped_refptr<ArrayVar> array_var(new ArrayVar());
+ ScopedPPVar array_pp_var(ScopedPPVar::PassRef(), array_var->GetPPVar());
+ scoped_refptr<StringVar> string_var(new StringVar("string_value"));
+ ScopedPPVar string_pp_var(ScopedPPVar::PassRef(), string_var->GetPPVar());
+
+ ASSERT_TRUE(dict_var_1->SetWithStringKey("null_key", PP_MakeNull()));
+ ASSERT_TRUE(dict_var_1->SetWithStringKey("string_key",
+ string_pp_var.get()));
+ ASSERT_TRUE(dict_var_1->SetWithStringKey("dict_key", dict_pp_var_2.get()));
+
+ ASSERT_TRUE(dict_var_2->SetWithStringKey("undefined_key",
+ PP_MakeUndefined()));
+ ASSERT_TRUE(dict_var_2->SetWithStringKey("double_key", PP_MakeDouble(1)));
+ ASSERT_TRUE(dict_var_2->SetWithStringKey("array_key", array_pp_var.get()));
+
+ ASSERT_TRUE(array_var->Set(0, PP_MakeInt32(2)));
+ ASSERT_TRUE(array_var->Set(1, PP_MakeBool(PP_TRUE)));
+ ASSERT_TRUE(array_var->SetLength(4));
+
+ scoped_ptr<base::Value> value(CreateValueFromVar(dict_pp_var_1.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, dict_pp_var_1.get()));
+ }
+
+ {
+ // Test that dictionary keys containing '.' are handled correctly.
+ scoped_refptr<DictionaryVar> dict_var(new DictionaryVar());
+ ScopedPPVar dict_pp_var(ScopedPPVar::PassRef(), dict_var->GetPPVar());
+
+ ASSERT_TRUE(dict_var->SetWithStringKey("double.key", PP_MakeDouble(1)));
+ ASSERT_TRUE(dict_var->SetWithStringKey("int.key..name", PP_MakeInt32(2)));
+
+ scoped_ptr<base::Value> value(CreateValueFromVar(dict_pp_var.get()));
+ ASSERT_TRUE(value.get());
+ ASSERT_TRUE(Equals(*value, dict_pp_var.get()));
+ }
+}
+
+TEST_F(VarValueConversionsTest, CreateVarFromValue) {
+ {
+ // Test basic cases for dictionary.
+ base::DictionaryValue dict_value;
+ ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+ ASSERT_TRUE(Equals(dict_value, var.get()));
+
+ dict_value.SetInteger("int_key", 1);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+ ASSERT_TRUE(Equals(dict_value, var.get()));
+ }
+
+ {
+ // Test basic cases for array.
+ base::ListValue list_value;
+ ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(list_value));
+ ASSERT_TRUE(Equals(list_value, var.get()));
+
+ list_value.AppendInteger(1);
+ var = ScopedPPVar(ScopedPPVar::PassRef(), CreateVarFromValue(list_value));
+ ASSERT_TRUE(Equals(list_value, var.get()));
+ }
+
+ {
+ // Test more complex inputs.
+ base::DictionaryValue dict_value;
+ dict_value.Set("null_key", base::Value::CreateNullValue());
+ dict_value.SetString("string_key", "string_value");
+ dict_value.SetDouble("dict_key.double_key", 1);
+
+ scoped_ptr<base::ListValue> list_value(new base::ListValue());
+ list_value->AppendInteger(2);
+ list_value->AppendBoolean(true);
+ list_value->Append(base::Value::CreateNullValue());
+
+ dict_value.Set("dict_key.array_key", list_value.release());
+
+ ScopedPPVar var(ScopedPPVar::PassRef(), CreateVarFromValue(dict_value));
+ ASSERT_TRUE(Equals(dict_value, var.get()));
+ }
+}
+
+} // namespace ppapi