diff options
author | Ben Murdoch <benm@google.com> | 2013-07-10 11:40:50 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2013-07-10 11:40:50 +0100 |
commit | eb525c5499e34cc9c4b825d6d9e75bb07cc06ace (patch) | |
tree | d908ce4bfe1717d2cd53f41327d8b9ba8304355f /ios | |
parent | 3c54152607de4272b3da0c146b71dcba8a0e5610 (diff) | |
download | chromium_org-eb525c5499e34cc9c4b825d6d9e75bb07cc06ace.tar.gz |
Merge from Chromium at DEPS revision r210036
This commit was generated by merge_to_master.py.
Change-Id: Ib0e33a83ad5dfa541481e83d7acfc6970e68f471
Diffstat (limited to 'ios')
-rw-r--r-- | ios/consumer/base/supports_user_data.cc | 90 | ||||
-rw-r--r-- | ios/consumer/base/supports_user_data_unittest.cc | 116 | ||||
-rw-r--r-- | ios/consumer/base/util.mm | 2 | ||||
-rw-r--r-- | ios/ios.gyp | 19 | ||||
-rw-r--r-- | ios/ios_base.gyp (renamed from ios/consumer/ios_consumer.gyp) | 10 | ||||
-rw-r--r-- | ios/ios_tests_unit.gyp | 25 | ||||
-rw-r--r-- | ios/ios_web.gyp | 24 | ||||
-rw-r--r-- | ios/public/DEPS (renamed from ios/consumer/public/DEPS) | 0 | ||||
-rw-r--r-- | ios/public/consumer/base/supports_user_data.h | 50 | ||||
-rw-r--r-- | ios/public/consumer/base/util.h (renamed from ios/consumer/public/base/util.h) | 6 | ||||
-rw-r--r-- | ios/public/provider/web/web_state.h | 23 | ||||
-rw-r--r-- | ios/public/provider/web/web_state_user_data.h | 72 |
12 files changed, 429 insertions, 8 deletions
diff --git a/ios/consumer/base/supports_user_data.cc b/ios/consumer/base/supports_user_data.cc new file mode 100644 index 0000000000..74ed3a7210 --- /dev/null +++ b/ios/consumer/base/supports_user_data.cc @@ -0,0 +1,90 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/public/consumer/base/supports_user_data.h" + +#include "base/memory/scoped_ptr.h" +#include "base/supports_user_data.h" + +namespace ios { + +// Class that wraps a ios::SupportsUserData::Data object in a +// base::SupportsUserData::Data object. The wrapper object takes ownership of +// the wrapped object and will delete it on destruction. +class DataAdaptor : public base::SupportsUserData::Data { + public: + DataAdaptor(SupportsUserData::Data* data); + virtual ~DataAdaptor(); + + SupportsUserData::Data* data() { return data_.get(); } + + private: + scoped_ptr<SupportsUserData::Data> data_; +}; + +DataAdaptor::DataAdaptor(SupportsUserData::Data* data) + : data_(data) {} + +DataAdaptor::~DataAdaptor() {} + +// Class that subclasses base::SupportsUserData in order to enable it to +// support ios::SupportsUserData::Data objects. It accomplishes this by +// wrapping these objects internally in ios::DataAdaptor objects. +class SupportsUserDataInternal : public base::SupportsUserData { + public: + // Returns the data that is associated with |key|, or NULL if there is no + // such associated data. + ios::SupportsUserData::Data* GetIOSUserData(const void* key); + + // Associates |data| with |key|. Takes ownership of |data| and will delete it + // on either a call to |RemoveUserData(key)| or otherwise on destruction. + void SetIOSUserData(const void* key, ios::SupportsUserData::Data* data); + + private: + SupportsUserDataInternal() {} + virtual ~SupportsUserDataInternal() {} + + friend class ios::SupportsUserData; +}; + +ios::SupportsUserData::Data* SupportsUserDataInternal::GetIOSUserData( + const void* key) { + DataAdaptor* adaptor = static_cast<DataAdaptor*>( + base::SupportsUserData::GetUserData(key)); + if (!adaptor) + return NULL; + return adaptor->data(); +} + +void SupportsUserDataInternal::SetIOSUserData( + const void* key, ios::SupportsUserData::Data* data) { + base::SupportsUserData::SetUserData(key, new DataAdaptor(data)); +} + +// ios::SupportsUserData implementation. +SupportsUserData::SupportsUserData() + : internal_helper_(new SupportsUserDataInternal()) { +} + +SupportsUserData::~SupportsUserData() { + delete internal_helper_; +} + +SupportsUserData::Data* SupportsUserData::GetUserData(const void* key) const { + return internal_helper_->GetIOSUserData(key); +} + +void SupportsUserData::SetUserData(const void* key, Data* data) { + internal_helper_->SetIOSUserData(key, data); +} + +void SupportsUserData::RemoveUserData(const void* key) { + internal_helper_->RemoveUserData(key); +} + +void SupportsUserData::DetachUserDataThread() { + internal_helper_->DetachUserDataThread(); +} + +} // namespace ios diff --git a/ios/consumer/base/supports_user_data_unittest.cc b/ios/consumer/base/supports_user_data_unittest.cc new file mode 100644 index 0000000000..1aeb417a15 --- /dev/null +++ b/ios/consumer/base/supports_user_data_unittest.cc @@ -0,0 +1,116 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/public/consumer/base/supports_user_data.h" + +#include "base/memory/scoped_ptr.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +namespace ios { + +namespace { + const char* kTestData1Key = "test_data1"; + const char* kTestData2Key = "test_data2"; +} // namespace + +class TestData : public SupportsUserData::Data { + public: + TestData(bool* was_destroyed) + : was_destroyed_(was_destroyed) { + *was_destroyed_ = false; + } + virtual ~TestData() { + *was_destroyed_ = true; + } + + private: + bool* was_destroyed_; +}; + +class TestSupportsUserData : public SupportsUserData { + public: + TestSupportsUserData() {} + virtual ~TestSupportsUserData() {} +}; + +class SupportsUserDataTest : public PlatformTest { + public: + virtual void SetUp() OVERRIDE { + PlatformTest::SetUp(); + + test_data1_was_destroyed_ = false; + test_data1_ = new TestData(&test_data1_was_destroyed_); + test_data2_was_destroyed_ = false; + test_data2_ = new TestData(&test_data2_was_destroyed_); + supports_user_data_.reset(new TestSupportsUserData()); + } + + virtual void TearDown() OVERRIDE { + if (!test_data1_was_destroyed_ && + supports_user_data_ && + supports_user_data_->GetUserData(kTestData1Key) != test_data1_) + delete test_data1_; + if (!test_data2_was_destroyed_ && + supports_user_data_ && + supports_user_data_->GetUserData(kTestData2Key) != test_data2_) + delete test_data2_; + + PlatformTest::TearDown(); + } + + protected: + scoped_ptr<TestSupportsUserData> supports_user_data_; + bool test_data1_was_destroyed_; + TestData* test_data1_; + bool test_data2_was_destroyed_; + TestData* test_data2_; +}; + +TEST_F(SupportsUserDataTest, SetAndGetData) { + EXPECT_FALSE(supports_user_data_->GetUserData(kTestData1Key)); + supports_user_data_->SetUserData(kTestData1Key, test_data1_); + EXPECT_EQ(supports_user_data_->GetUserData(kTestData1Key), test_data1_); +} + +TEST_F(SupportsUserDataTest, DataDestroyedOnDestruction) { + EXPECT_FALSE(supports_user_data_->GetUserData(kTestData1Key)); + supports_user_data_->SetUserData(kTestData1Key, test_data1_); + EXPECT_FALSE(test_data1_was_destroyed_); + supports_user_data_.reset(); + EXPECT_TRUE(test_data1_was_destroyed_); +} + +TEST_F(SupportsUserDataTest, DataDestroyedOnRemoval) { + EXPECT_FALSE(supports_user_data_->GetUserData(kTestData1Key)); + supports_user_data_->SetUserData(kTestData1Key, test_data1_); + EXPECT_FALSE(test_data1_was_destroyed_); + supports_user_data_->RemoveUserData(kTestData1Key); + EXPECT_TRUE(test_data1_was_destroyed_); +} + +TEST_F(SupportsUserDataTest, DistinctDataStoredSeparately) { + EXPECT_FALSE(supports_user_data_->GetUserData(kTestData2Key)); + supports_user_data_->SetUserData(kTestData1Key, test_data1_); + EXPECT_FALSE(supports_user_data_->GetUserData(kTestData2Key)); + supports_user_data_->SetUserData(kTestData2Key, test_data2_); + EXPECT_EQ(supports_user_data_->GetUserData(kTestData2Key), test_data2_); +} + +TEST_F(SupportsUserDataTest, DistinctDataDestroyedSeparately) { + supports_user_data_->SetUserData(kTestData1Key, test_data1_); + supports_user_data_->SetUserData(kTestData2Key, test_data2_); + EXPECT_FALSE(test_data1_was_destroyed_); + EXPECT_FALSE(test_data2_was_destroyed_); + + supports_user_data_->RemoveUserData(kTestData2Key); + EXPECT_FALSE(test_data1_was_destroyed_); + EXPECT_TRUE(test_data2_was_destroyed_); + + supports_user_data_.reset(); + EXPECT_TRUE(test_data1_was_destroyed_); +} + +} // namespace ios diff --git a/ios/consumer/base/util.mm b/ios/consumer/base/util.mm index 6a94f8ffcd..1e640f5edd 100644 --- a/ios/consumer/base/util.mm +++ b/ios/consumer/base/util.mm @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/ios/ios_util.h" -#include "ios/consumer/public/base/util.h" +#include "ios/public/consumer/base/util.h" namespace ios { diff --git a/ios/ios.gyp b/ios/ios.gyp new file mode 100644 index 0000000000..4545b46cbe --- /dev/null +++ b/ios/ios.gyp @@ -0,0 +1,19 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'ios', + 'type': 'none', + 'dependencies': [ + 'ios_base.gyp:*', + 'ios_web.gyp:*', + 'ios_tests_unit.gyp:*', + ], + }, + ], +} diff --git a/ios/consumer/ios_consumer.gyp b/ios/ios_base.gyp index 9e6f7b6270..f15192a861 100644 --- a/ios/consumer/ios_consumer.gyp +++ b/ios/ios_base.gyp @@ -10,14 +10,16 @@ 'target_name': 'ios_consumer_base', 'type': 'static_library', 'dependencies': [ - '../../base/base.gyp:base', + '../base/base.gyp:base', ], 'include_dirs': [ - '../..', + '..', ], 'sources': [ - 'base/util.mm', - 'public/base/util.h', + 'consumer/base/supports_user_data.cc', + 'consumer/base/util.mm', + 'public/consumer/base/supports_user_data.h', + 'public/consumer/base/util.h', ], }, ], diff --git a/ios/ios_tests_unit.gyp b/ios/ios_tests_unit.gyp new file mode 100644 index 0000000000..5b76f8924f --- /dev/null +++ b/ios/ios_tests_unit.gyp @@ -0,0 +1,25 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'ios_unittests', + 'type': '<(gtest_target_type)', + 'dependencies': [ + '../base/base.gyp:base', + '../base/base.gyp:run_all_unittests', + '../base/base.gyp:test_support_base', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + 'ios_base.gyp:ios_consumer_base', + ], + 'sources': [ + 'consumer/base/supports_user_data_unittest.cc', + ], + }, + ], +} diff --git a/ios/ios_web.gyp b/ios/ios_web.gyp new file mode 100644 index 0000000000..6f3f2d4c29 --- /dev/null +++ b/ios/ios_web.gyp @@ -0,0 +1,24 @@ +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'ios_provider_web', + 'type': 'none', + 'include_dirs': [ + '..', + ], + 'sources': [ + 'public/provider/web/web_state.h', + 'public/provider/web/web_state_user_data.h', + ], + 'dependencies': [ + 'ios_base.gyp:ios_consumer_base', + ], + }, + ], +} diff --git a/ios/consumer/public/DEPS b/ios/public/DEPS index b9ffa717bc..b9ffa717bc 100644 --- a/ios/consumer/public/DEPS +++ b/ios/public/DEPS diff --git a/ios/public/consumer/base/supports_user_data.h b/ios/public/consumer/base/supports_user_data.h new file mode 100644 index 0000000000..5986c57def --- /dev/null +++ b/ios/public/consumer/base/supports_user_data.h @@ -0,0 +1,50 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_PUBLIC_CONSUMER_BASE_SUPPORTS_USER_DATA_H_ +#define IOS_PUBLIC_CONSUMER_BASE_SUPPORTS_USER_DATA_H_ + +namespace ios { + +class SupportsUserDataInternal; + +// This is a helper for classes that want to allow users to stash random data by +// key. At destruction all the objects will be destructed. +class SupportsUserData { + public: + SupportsUserData(); + + // Derive from this class and add your own data members to associate extra + // information with this object. Alternatively, add this as a public base + // class to any class with a virtual destructor. + class Data { + public: + virtual ~Data() {} + }; + + // The user data allows the clients to associate data with this object. + // Multiple user data values can be stored under different keys. + // This object will TAKE OWNERSHIP of the given data pointer, and will + // delete the object if it is changed or the object is destroyed. + Data* GetUserData(const void* key) const; + void SetUserData(const void* key, Data* data); + void RemoveUserData(const void* key); + + // SupportsUserData is not thread-safe, and on debug build will assert it is + // only used on one thread. Calling this method allows the caller to hand + // the SupportsUserData instance across threads. Use only if you are taking + // full control of the synchronization of that handover. + void DetachUserDataThread(); + + protected: + virtual ~SupportsUserData(); + + private: + // Owned by this object and scoped to its lifetime. + SupportsUserDataInternal* internal_helper_; +}; + +} // namespace ios + +#endif // IOS_PUBLIC_CONSUMER_BASE_SUPPORTS_USER_DATA_H_ diff --git a/ios/consumer/public/base/util.h b/ios/public/consumer/base/util.h index 9820834c1d..5977ea76cc 100644 --- a/ios/consumer/public/base/util.h +++ b/ios/public/consumer/base/util.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CONSUME_PUBLIC_BASE_UTIL_H_ -#define IOS_CONSUME_PUBLIC_BASE_UTIL_H_ +#ifndef IOS_PUBLIC_CONSUMER_BASE_UTIL_H_ +#define IOS_PUBLIC_CONSUMER_BASE_UTIL_H_ namespace ios { @@ -15,4 +15,4 @@ bool IsRunningOnOrLater(int major, int minor, int bug_fix); } // namespace ios -#endif // IOS_CONSUME_PUBLIC_BASE_UTIL_H_ +#endif // IOS_PUBLIC_CONSUMER_BASE_UTIL_H_ diff --git a/ios/public/provider/web/web_state.h b/ios/public/provider/web/web_state.h new file mode 100644 index 0000000000..0e47bbe1ea --- /dev/null +++ b/ios/public/provider/web/web_state.h @@ -0,0 +1,23 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_PUBLIC_PROVIDER_WEB_WEB_STATE_H_ +#define IOS_PUBLIC_PROVIDER_WEB_WEB_STATE_H_ + +#include "ios/public/consumer/base/supports_user_data.h" + +namespace ios { + +// Core interface for interaction with the web. +class WebState : public ios::SupportsUserData { + public: + virtual ~WebState() {} + + protected: + WebState() {} +}; + +} // namespace ios + +#endif // IOS_PUBLIC_PROVIDER_WEB_WEB_STATE_H_ diff --git a/ios/public/provider/web/web_state_user_data.h b/ios/public/provider/web/web_state_user_data.h new file mode 100644 index 0000000000..17d2fab6f9 --- /dev/null +++ b/ios/public/provider/web/web_state_user_data.h @@ -0,0 +1,72 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_PUBLIC_PROVIDER_WEB_WEB_STATE_USER_DATA_H_ +#define IOS_PUBLIC_PROVIDER_WEB_WEB_STATE_USER_DATA_H_ + +#include "ios/public/consumer/base/supports_user_data.h" +#include "ios/public/provider/web/web_state.h" + +namespace ios { + +// A base class for classes attached to, and scoped to, the lifetime of a +// WebState. For example: +// +// --- in foo.h --- +// class Foo : public ios::WebStateUserData<Foo> { +// public: +// virtual ~Foo(); +// // ... more public stuff here ... +// private: +// explicit Foo(ios::WebState* web_state); +// friend class ios::WebStateUserData<Foo>; +// // ... more private stuff here ... +// } +// --- in foo.cc --- +// DEFINE_WEB_CONTENTS_USER_DATA_KEY(Foo); +// +template <typename T> +class WebStateUserData : public ios::SupportsUserData::Data { + public: + // Creates an object of type T, and attaches it to the specified WebState. + // If an instance is already attached, does nothing. + static void CreateForWebState(WebState* web_state) { + if (!FromWebState(web_state)) + web_state->SetUserData(UserDataKey(), new T(web_state)); + } + + // Retrieves the instance of type T that was attached to the specified + // WebState (via CreateForWebState above) and returns it. If no instance + // of the type was attached, returns NULL. + static T* FromWebState(WebState* web_state) { + return static_cast<T*>(web_state->GetUserData(UserDataKey())); + } + static const T* FromWebState(const WebState* web_state) { + return static_cast<const T*>(web_state->GetUserData(UserDataKey())); + } + + protected: + static inline void* UserDataKey() { + return &kLocatorKey; + } + + private: + // The user data key. + static int kLocatorKey; +}; + +// The macro to define the locator key. This key should be defined in the .cc +// file of the derived class. +// +// The "= 0" is surprising, but is required to effect a definition rather than +// a declaration. Without it, this would be merely a declaration of a template +// specialization. (C++98: 14.7.3.15; C++11: 14.7.3.13) +// +#define DEFINE_WEB_STATE_USER_DATA_KEY(TYPE) \ +template<> \ +int ios::WebStateUserData<TYPE>::kLocatorKey = 0 + +} // namespace ios + +#endif // IOS_PUBLIC_PROVIDER_WEB_WEB_STATE_USER_DATA_H_ |