| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/chromeos/cryptohome/async_method_caller.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/hash_tables.h" | |
| 9 #include "base/location.h" | |
| 10 #include "base/message_loop_proxy.h" | |
| 11 #include "chromeos/dbus/cryptohome_client.h" | |
| 12 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 13 | |
| 14 using chromeos::DBusThreadManager; | |
| 15 | |
| 16 namespace cryptohome { | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 AsyncMethodCaller* g_async_method_caller = NULL; | |
| 21 | |
| 22 // The implementation of AsyncMethodCaller | |
| 23 class AsyncMethodCallerImpl : public AsyncMethodCaller { | |
| 24 public: | |
| 25 AsyncMethodCallerImpl() : weak_ptr_factory_(this) { | |
| 26 DBusThreadManager::Get()->GetCryptohomeClient()->SetAsyncCallStatusHandler( | |
| 27 base::Bind(&AsyncMethodCallerImpl::HandleAsyncResponse, | |
| 28 weak_ptr_factory_.GetWeakPtr())); | |
| 29 } | |
| 30 | |
| 31 virtual ~AsyncMethodCallerImpl() { | |
| 32 DBusThreadManager::Get()->GetCryptohomeClient()-> | |
| 33 ResetAsyncCallStatusHandler(); | |
| 34 } | |
| 35 | |
| 36 virtual void AsyncCheckKey(const std::string& user_email, | |
| 37 const std::string& passhash, | |
| 38 Callback callback) OVERRIDE { | |
| 39 DBusThreadManager::Get()->GetCryptohomeClient()-> | |
| 40 AsyncCheckKey(user_email, passhash, base::Bind( | |
| 41 &AsyncMethodCallerImpl::RegisterAsyncCallback, | |
| 42 weak_ptr_factory_.GetWeakPtr(), | |
| 43 callback, | |
| 44 "Couldn't initiate async check of user's key.")); | |
| 45 } | |
| 46 | |
| 47 virtual void AsyncMigrateKey(const std::string& user_email, | |
| 48 const std::string& old_hash, | |
| 49 const std::string& new_hash, | |
| 50 Callback callback) OVERRIDE { | |
| 51 DBusThreadManager::Get()->GetCryptohomeClient()-> | |
| 52 AsyncMigrateKey(user_email, old_hash, new_hash, base::Bind( | |
| 53 &AsyncMethodCallerImpl::RegisterAsyncCallback, | |
| 54 weak_ptr_factory_.GetWeakPtr(), | |
| 55 callback, | |
| 56 "Couldn't initiate aync migration of user's key")); | |
| 57 } | |
| 58 | |
| 59 virtual void AsyncMount(const std::string& user_email, | |
| 60 const std::string& passhash, | |
| 61 const bool create_if_missing, | |
| 62 Callback callback) OVERRIDE { | |
| 63 DBusThreadManager::Get()->GetCryptohomeClient()-> | |
| 64 AsyncMount(user_email, passhash, create_if_missing, base::Bind( | |
| 65 &AsyncMethodCallerImpl::RegisterAsyncCallback, | |
| 66 weak_ptr_factory_.GetWeakPtr(), | |
| 67 callback, | |
| 68 "Couldn't initiate async mount of cryptohome.")); | |
| 69 } | |
| 70 | |
| 71 virtual void AsyncMountGuest(Callback callback) OVERRIDE { | |
| 72 DBusThreadManager::Get()->GetCryptohomeClient()-> | |
| 73 AsyncMountGuest(base::Bind( | |
| 74 &AsyncMethodCallerImpl::RegisterAsyncCallback, | |
| 75 weak_ptr_factory_.GetWeakPtr(), | |
| 76 callback, | |
| 77 "Couldn't initiate async mount of cryptohome.")); | |
| 78 } | |
| 79 | |
| 80 virtual void AsyncRemove(const std::string& user_email, | |
| 81 Callback callback) OVERRIDE { | |
| 82 DBusThreadManager::Get()->GetCryptohomeClient()-> | |
| 83 AsyncRemove(user_email, base::Bind( | |
| 84 &AsyncMethodCallerImpl::RegisterAsyncCallback, | |
| 85 weak_ptr_factory_.GetWeakPtr(), | |
| 86 callback, | |
| 87 "Couldn't initiate async removal of cryptohome.")); | |
| 88 } | |
| 89 | |
| 90 private: | |
| 91 struct CallbackElement { | |
| 92 CallbackElement() {} | |
| 93 explicit CallbackElement( | |
| 94 const AsyncMethodCaller::Callback& callback) | |
| 95 : callback(callback), | |
| 96 proxy(base::MessageLoopProxy::current()) { | |
| 97 } | |
| 98 AsyncMethodCaller::Callback callback; | |
| 99 scoped_refptr<base::MessageLoopProxy> proxy; | |
| 100 }; | |
| 101 | |
| 102 typedef base::hash_map<int, CallbackElement> CallbackMap; | |
| 103 | |
| 104 // Hanldes the response for async calls. | |
| 105 // Below is described how async calls work. | |
| 106 // 1. CryptohomeClient::AsyncXXX returns "async ID". | |
| 107 // 2. RegisterAsyncCallback registers the "async ID" with the user-provided | |
| 108 // callback. | |
| 109 // 3. Cryptohome will return the result asynchronously as a signal with | |
| 110 // "async ID" | |
| 111 // 4. "HandleAsyncResponse" handles the result signal and call the registered | |
| 112 // callback associated with the "async ID". | |
| 113 void HandleAsyncResponse(int async_id, bool return_status, int return_code) { | |
| 114 const CallbackMap::iterator it = callback_map_.find(async_id); | |
| 115 if (it == callback_map_.end()) { | |
| 116 LOG(ERROR) << "Received signal for unknown async_id " << async_id; | |
| 117 return; | |
| 118 } | |
| 119 it->second.proxy->PostTask(FROM_HERE, | |
| 120 base::Bind(it->second.callback, | |
| 121 return_status, | |
| 122 static_cast<MountError>(return_code))); | |
| 123 callback_map_.erase(it); | |
| 124 } | |
| 125 | |
| 126 // Registers a callback which is called when the result for AsyncXXX is ready. | |
| 127 void RegisterAsyncCallback( | |
| 128 Callback callback, const char* error, int async_id) { | |
| 129 if (async_id == 0) { | |
| 130 LOG(ERROR) << error; | |
| 131 return; | |
| 132 } | |
| 133 VLOG(1) << "Adding handler for " << async_id; | |
| 134 DCHECK_EQ(callback_map_.count(async_id), 0U); | |
| 135 callback_map_[async_id] = CallbackElement(callback); | |
| 136 } | |
| 137 | |
| 138 base::WeakPtrFactory<AsyncMethodCallerImpl> weak_ptr_factory_; | |
| 139 CallbackMap callback_map_; | |
| 140 | |
| 141 DISALLOW_COPY_AND_ASSIGN(AsyncMethodCallerImpl); | |
| 142 }; | |
| 143 | |
| 144 } // namespace | |
| 145 | |
| 146 // static | |
| 147 void AsyncMethodCaller::Initialize() { | |
| 148 if (g_async_method_caller) { | |
| 149 LOG(WARNING) << "AsyncMethodCaller was already initialized"; | |
| 150 return; | |
| 151 } | |
| 152 g_async_method_caller = new AsyncMethodCallerImpl(); | |
| 153 VLOG(1) << "AsyncMethodCaller initialized"; | |
| 154 } | |
| 155 | |
| 156 // static | |
| 157 void AsyncMethodCaller::InitializeForTesting( | |
| 158 AsyncMethodCaller* async_method_caller) { | |
| 159 if (g_async_method_caller) { | |
| 160 LOG(WARNING) << "AsyncMethodCaller was already initialized"; | |
| 161 return; | |
| 162 } | |
| 163 g_async_method_caller = async_method_caller; | |
| 164 VLOG(1) << "AsyncMethodCaller initialized"; | |
| 165 } | |
| 166 | |
| 167 // static | |
| 168 void AsyncMethodCaller::Shutdown() { | |
| 169 if (!g_async_method_caller) { | |
| 170 LOG(WARNING) << "AsyncMethodCaller::Shutdown() called with NULL manager"; | |
| 171 return; | |
| 172 } | |
| 173 delete g_async_method_caller; | |
| 174 g_async_method_caller = NULL; | |
| 175 VLOG(1) << "AsyncMethodCaller Shutdown completed"; | |
| 176 } | |
| 177 | |
| 178 // static | |
| 179 AsyncMethodCaller* AsyncMethodCaller::GetInstance() { | |
| 180 return g_async_method_caller; | |
| 181 } | |
| 182 | |
| 183 } // namespace cryptohome | |
| OLD | NEW |