diff options
author | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-26 12:11:37 +0000 |
---|---|---|
committer | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-26 12:11:37 +0000 |
commit | 6666e5bf840b8198909a9207604855f4e8dbc2af (patch) | |
tree | 007dfbde26855ac2261042045c916b855fe7068e /chromeos | |
parent | 278f9ac61cdf6bebaec0be4ec6daab1c1399c2fd (diff) | |
download | chromium_src-6666e5bf840b8198909a9207604855f4e8dbc2af.zip chromium_src-6666e5bf840b8198909a9207604855f4e8dbc2af.tar.gz chromium_src-6666e5bf840b8198909a9207604855f4e8dbc2af.tar.bz2 |
chromeos: Move src/chrome/browser/chromeos/cryptohome to src/chromeos
BUG=None
TEST=build
TBR=ben@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10878061
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153410 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/chromeos.gyp | 4 | ||||
-rw-r--r-- | chromeos/cryptohome/async_method_caller.cc | 183 | ||||
-rw-r--r-- | chromeos/cryptohome/async_method_caller.h | 87 | ||||
-rw-r--r-- | chromeos/cryptohome/mock_async_method_caller.cc | 43 | ||||
-rw-r--r-- | chromeos/cryptohome/mock_async_method_caller.h | 50 |
5 files changed, 367 insertions, 0 deletions
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 575dfaf..762adfd 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -26,6 +26,8 @@ 'chromeos_export.h', 'chromeos_switches.cc', 'chromeos_switches.h', + 'cryptohome/async_method_caller.cc', + 'cryptohome/async_method_caller.h', 'dbus/blocking_method_caller.cc', 'dbus/blocking_method_caller.h', 'dbus/bluetooth_adapter_client.cc', @@ -134,6 +136,8 @@ 'chromeos', ], 'sources': [ + 'cryptohome/mock_async_method_caller.cc', + 'cryptohome/mock_async_method_caller.h', 'dbus/mock_bluetooth_adapter_client.cc', 'dbus/mock_bluetooth_adapter_client.h', 'dbus/mock_bluetooth_device_client.cc', diff --git a/chromeos/cryptohome/async_method_caller.cc b/chromeos/cryptohome/async_method_caller.cc new file mode 100644 index 0000000..4deb338 --- /dev/null +++ b/chromeos/cryptohome/async_method_caller.cc @@ -0,0 +1,183 @@ +// 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 "chromeos/cryptohome/async_method_caller.h" + +#include "base/bind.h" +#include "base/hash_tables.h" +#include "base/location.h" +#include "base/message_loop_proxy.h" +#include "chromeos/dbus/cryptohome_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" + +using chromeos::DBusThreadManager; + +namespace cryptohome { + +namespace { + +AsyncMethodCaller* g_async_method_caller = NULL; + +// The implementation of AsyncMethodCaller +class AsyncMethodCallerImpl : public AsyncMethodCaller { + public: + AsyncMethodCallerImpl() : weak_ptr_factory_(this) { + DBusThreadManager::Get()->GetCryptohomeClient()->SetAsyncCallStatusHandler( + base::Bind(&AsyncMethodCallerImpl::HandleAsyncResponse, + weak_ptr_factory_.GetWeakPtr())); + } + + virtual ~AsyncMethodCallerImpl() { + DBusThreadManager::Get()->GetCryptohomeClient()-> + ResetAsyncCallStatusHandler(); + } + + virtual void AsyncCheckKey(const std::string& user_email, + const std::string& passhash, + Callback callback) OVERRIDE { + DBusThreadManager::Get()->GetCryptohomeClient()-> + AsyncCheckKey(user_email, passhash, base::Bind( + &AsyncMethodCallerImpl::RegisterAsyncCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + "Couldn't initiate async check of user's key.")); + } + + virtual void AsyncMigrateKey(const std::string& user_email, + const std::string& old_hash, + const std::string& new_hash, + Callback callback) OVERRIDE { + DBusThreadManager::Get()->GetCryptohomeClient()-> + AsyncMigrateKey(user_email, old_hash, new_hash, base::Bind( + &AsyncMethodCallerImpl::RegisterAsyncCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + "Couldn't initiate aync migration of user's key")); + } + + virtual void AsyncMount(const std::string& user_email, + const std::string& passhash, + const bool create_if_missing, + Callback callback) OVERRIDE { + DBusThreadManager::Get()->GetCryptohomeClient()-> + AsyncMount(user_email, passhash, create_if_missing, base::Bind( + &AsyncMethodCallerImpl::RegisterAsyncCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + "Couldn't initiate async mount of cryptohome.")); + } + + virtual void AsyncMountGuest(Callback callback) OVERRIDE { + DBusThreadManager::Get()->GetCryptohomeClient()-> + AsyncMountGuest(base::Bind( + &AsyncMethodCallerImpl::RegisterAsyncCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + "Couldn't initiate async mount of cryptohome.")); + } + + virtual void AsyncRemove(const std::string& user_email, + Callback callback) OVERRIDE { + DBusThreadManager::Get()->GetCryptohomeClient()-> + AsyncRemove(user_email, base::Bind( + &AsyncMethodCallerImpl::RegisterAsyncCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + "Couldn't initiate async removal of cryptohome.")); + } + + private: + struct CallbackElement { + CallbackElement() {} + explicit CallbackElement( + const AsyncMethodCaller::Callback& callback) + : callback(callback), + proxy(base::MessageLoopProxy::current()) { + } + AsyncMethodCaller::Callback callback; + scoped_refptr<base::MessageLoopProxy> proxy; + }; + + typedef base::hash_map<int, CallbackElement> CallbackMap; + + // Hanldes the response for async calls. + // Below is described how async calls work. + // 1. CryptohomeClient::AsyncXXX returns "async ID". + // 2. RegisterAsyncCallback registers the "async ID" with the user-provided + // callback. + // 3. Cryptohome will return the result asynchronously as a signal with + // "async ID" + // 4. "HandleAsyncResponse" handles the result signal and call the registered + // callback associated with the "async ID". + void HandleAsyncResponse(int async_id, bool return_status, int return_code) { + const CallbackMap::iterator it = callback_map_.find(async_id); + if (it == callback_map_.end()) { + LOG(ERROR) << "Received signal for unknown async_id " << async_id; + return; + } + it->second.proxy->PostTask(FROM_HERE, + base::Bind(it->second.callback, + return_status, + static_cast<MountError>(return_code))); + callback_map_.erase(it); + } + + // Registers a callback which is called when the result for AsyncXXX is ready. + void RegisterAsyncCallback( + Callback callback, const char* error, int async_id) { + if (async_id == 0) { + LOG(ERROR) << error; + return; + } + VLOG(1) << "Adding handler for " << async_id; + DCHECK_EQ(callback_map_.count(async_id), 0U); + callback_map_[async_id] = CallbackElement(callback); + } + + base::WeakPtrFactory<AsyncMethodCallerImpl> weak_ptr_factory_; + CallbackMap callback_map_; + + DISALLOW_COPY_AND_ASSIGN(AsyncMethodCallerImpl); +}; + +} // namespace + +// static +void AsyncMethodCaller::Initialize() { + if (g_async_method_caller) { + LOG(WARNING) << "AsyncMethodCaller was already initialized"; + return; + } + g_async_method_caller = new AsyncMethodCallerImpl(); + VLOG(1) << "AsyncMethodCaller initialized"; +} + +// static +void AsyncMethodCaller::InitializeForTesting( + AsyncMethodCaller* async_method_caller) { + if (g_async_method_caller) { + LOG(WARNING) << "AsyncMethodCaller was already initialized"; + return; + } + g_async_method_caller = async_method_caller; + VLOG(1) << "AsyncMethodCaller initialized"; +} + +// static +void AsyncMethodCaller::Shutdown() { + if (!g_async_method_caller) { + LOG(WARNING) << "AsyncMethodCaller::Shutdown() called with NULL manager"; + return; + } + delete g_async_method_caller; + g_async_method_caller = NULL; + VLOG(1) << "AsyncMethodCaller Shutdown completed"; +} + +// static +AsyncMethodCaller* AsyncMethodCaller::GetInstance() { + return g_async_method_caller; +} + +} // namespace cryptohome diff --git a/chromeos/cryptohome/async_method_caller.h b/chromeos/cryptohome/async_method_caller.h new file mode 100644 index 0000000..e1e54bb --- /dev/null +++ b/chromeos/cryptohome/async_method_caller.h @@ -0,0 +1,87 @@ +// 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 CHROMEOS_CRYPTOHOME_ASYNC_METHOD_CALLER_H_ +#define CHROMEOS_CRYPTOHOME_ASYNC_METHOD_CALLER_H_ + +#include <string> + +#include "base/callback_forward.h" +#include "chromeos/chromeos_export.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace cryptohome { + +// This class manages calls to Cryptohome service's 'async' methods. +// Note: This class is placed in ::cryptohome instead of ::chromeos::cryptohome +// since there is already a namespace ::cryptohome which holds the error code +// enum (MountError) and referencing ::chromeos::cryptohome and ::cryptohome +// within the same code is confusing. +class CHROMEOS_EXPORT AsyncMethodCaller { + public: + // A callback type which is called back on the UI thread when the results of + // method calls are ready. + typedef base::Callback<void(bool success, MountError return_code)> Callback; + + virtual ~AsyncMethodCaller() {} + + // Asks cryptohomed to asynchronously try to find the cryptohome for + // |user_email| and then use |passhash| to unlock the key. + // |callback| will be called with status info on completion. + virtual void AsyncCheckKey(const std::string& user_email, + const std::string& passhash, + Callback callback) = 0; + + // Asks cryptohomed to asynchronously try to find the cryptohome for + // |user_email| and then change from using |old_hash| to lock the + // key to using |new_hash|. + // |callback| will be called with status info on completion. + virtual void AsyncMigrateKey(const std::string& user_email, + const std::string& old_hash, + const std::string& new_hash, + Callback callback) = 0; + + // Asks cryptohomed to asynchronously try to find the cryptohome for + // |user_email| and then mount it using |passhash| to unlock the key. + // |create_if_missing| controls whether or not we ask cryptohomed to + // create a new home dir if one does not yet exist for |user_email|. + // |callback| will be called with status info on completion. + // If |create_if_missing| is false, and no cryptohome exists for |user_email|, + // we'll get + // callback.Run(false, kCryptohomeMountErrorUserDoesNotExist). + // Otherwise, we expect the normal range of return codes. + virtual void AsyncMount(const std::string& user_email, + const std::string& passhash, + const bool create_if_missing, + Callback callback) = 0; + + // Asks cryptohomed to asynchronously to mount a tmpfs for guest mode. + // |callback| will be called with status info on completion. + virtual void AsyncMountGuest(Callback callback) = 0; + + // Asks cryptohomed to asynchronously try to find the cryptohome for + // |user_email| and then nuke it. + virtual void AsyncRemove(const std::string& user_email, + Callback callback) = 0; + + // Creates the global AsyncMethodCaller instance. + static void Initialize(); + + // Similar to Initialize(), but can inject an alternative + // AsyncMethodCaller such as MockAsyncMethodCaller for testing. + // The injected object will be owned by the internal pointer and deleted + // by Shutdown(). + static void InitializeForTesting(AsyncMethodCaller* async_method_caller); + + // Destroys the global AsyncMethodCaller instance if it exists. + static void Shutdown(); + + // Returns a pointer to the global AsyncMethodCaller instance. + // Initialize() should already have been called. + static AsyncMethodCaller* GetInstance(); +}; + +} // namespace cryptohome + +#endif // CHROMEOS_CRYPTOHOME_ASYNC_METHOD_CALLER_H_ diff --git a/chromeos/cryptohome/mock_async_method_caller.cc b/chromeos/cryptohome/mock_async_method_caller.cc new file mode 100644 index 0000000..eb2203c --- /dev/null +++ b/chromeos/cryptohome/mock_async_method_caller.cc @@ -0,0 +1,43 @@ +// 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 "chromeos/cryptohome/mock_async_method_caller.h" + +using ::testing::Invoke; +using ::testing::WithArgs; +using ::testing::_; + +namespace cryptohome { + +MockAsyncMethodCaller::MockAsyncMethodCaller() + : success_(false), return_code_(cryptohome::MOUNT_ERROR_NONE) { +} + +MockAsyncMethodCaller::~MockAsyncMethodCaller() {} + +void MockAsyncMethodCaller::SetUp(bool success, MountError return_code) { + success_ = success; + return_code_ = return_code; + ON_CALL(*this, AsyncCheckKey(_, _, _)) + .WillByDefault( + WithArgs<2>(Invoke(this, &MockAsyncMethodCaller::DoCallback))); + ON_CALL(*this, AsyncMigrateKey(_, _, _, _)) + .WillByDefault( + WithArgs<3>(Invoke(this, &MockAsyncMethodCaller::DoCallback))); + ON_CALL(*this, AsyncMount(_, _, _, _)) + .WillByDefault( + WithArgs<3>(Invoke(this, &MockAsyncMethodCaller::DoCallback))); + ON_CALL(*this, AsyncMountGuest(_)) + .WillByDefault( + WithArgs<0>(Invoke(this, &MockAsyncMethodCaller::DoCallback))); + ON_CALL(*this, AsyncRemove(_, _)) + .WillByDefault( + WithArgs<1>(Invoke(this, &MockAsyncMethodCaller::DoCallback))); +} + +void MockAsyncMethodCaller::DoCallback(Callback callback) { + callback.Run(success_, return_code_); +} + +} // namespace cryptohome diff --git a/chromeos/cryptohome/mock_async_method_caller.h b/chromeos/cryptohome/mock_async_method_caller.h new file mode 100644 index 0000000..5b301cb --- /dev/null +++ b/chromeos/cryptohome/mock_async_method_caller.h @@ -0,0 +1,50 @@ +// 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 CHROMEOS_CRYPTOHOME_MOCK_ASYNC_METHOD_CALLER_H_ +#define CHROMEOS_CRYPTOHOME_MOCK_ASYNC_METHOD_CALLER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "chromeos/cryptohome/async_method_caller.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace cryptohome { + +class MockAsyncMethodCaller : public AsyncMethodCaller { + public: + MockAsyncMethodCaller(); + virtual ~MockAsyncMethodCaller(); + + void SetUp(bool success, MountError return_code); + + MOCK_METHOD3(AsyncCheckKey, void(const std::string& user_email, + const std::string& passhash, + Callback callback)); + MOCK_METHOD4(AsyncMigrateKey, void(const std::string& user_email, + const std::string& old_hash, + const std::string& new_hash, + Callback callback)); + MOCK_METHOD4(AsyncMount, void(const std::string& user_email, + const std::string& passhash, + const bool create_if_missing, + Callback callback)); + MOCK_METHOD1(AsyncMountGuest, void(Callback callback)); + MOCK_METHOD2(AsyncRemove, void(const std::string& user_email, + Callback callback)); + + private: + bool success_; + MountError return_code_; + + void DoCallback(Callback callback); + + DISALLOW_COPY_AND_ASSIGN(MockAsyncMethodCaller); +}; + +} // namespace cryptohome + +#endif // CHROMEOS_CRYPTOHOME_MOCK_ASYNC_METHOD_CALLER_H_ |