Home | History | Annotate | Download | only in dbus
      1 // Copyright 2013 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 "chromeos/dbus/fake_cryptohome_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/files/file_util.h"
      9 #include "base/location.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/path_service.h"
     12 #include "base/threading/thread_restrictions.h"
     13 #include "chromeos/chromeos_paths.h"
     14 #include "chromeos/dbus/cryptohome/key.pb.h"
     15 #include "chromeos/dbus/cryptohome/rpc.pb.h"
     16 #include "third_party/cros_system_api/dbus/service_constants.h"
     17 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h"
     18 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h"
     19 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h"
     20 
     21 namespace chromeos {
     22 
     23 FakeCryptohomeClient::FakeCryptohomeClient()
     24     : service_is_available_(true),
     25       async_call_id_(1),
     26       tpm_is_ready_counter_(0),
     27       unmount_result_(true),
     28       system_salt_(GetStubSystemSalt()),
     29       weak_ptr_factory_(this) {
     30   base::FilePath cache_path;
     31   locked_ = PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path) &&
     32             base::PathExists(cache_path);
     33 }
     34 
     35 FakeCryptohomeClient::~FakeCryptohomeClient() {}
     36 
     37 void FakeCryptohomeClient::Init(dbus::Bus* bus) {
     38 }
     39 
     40 void FakeCryptohomeClient::SetAsyncCallStatusHandlers(
     41     const AsyncCallStatusHandler& handler,
     42     const AsyncCallStatusWithDataHandler& data_handler) {
     43   async_call_status_handler_ = handler;
     44   async_call_status_data_handler_ = data_handler;
     45 }
     46 
     47 void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
     48   async_call_status_handler_.Reset();
     49   async_call_status_data_handler_.Reset();
     50 }
     51 
     52 void FakeCryptohomeClient::WaitForServiceToBeAvailable(
     53     const WaitForServiceToBeAvailableCallback& callback) {
     54   if (service_is_available_) {
     55     base::MessageLoop::current()->PostTask(FROM_HERE,
     56                                            base::Bind(callback, true));
     57   } else {
     58     pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
     59   }
     60 }
     61 
     62 void FakeCryptohomeClient::IsMounted(
     63     const BoolDBusMethodCallback& callback) {
     64   base::MessageLoop::current()->PostTask(
     65       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
     66 }
     67 
     68 bool FakeCryptohomeClient::Unmount(bool* success) {
     69   *success = unmount_result_;
     70   return true;
     71 }
     72 
     73 void FakeCryptohomeClient::AsyncCheckKey(
     74     const std::string& username,
     75     const std::string& key,
     76     const AsyncMethodCallback& callback) {
     77   ReturnAsyncMethodResult(callback, false);
     78 }
     79 
     80 void FakeCryptohomeClient::AsyncMigrateKey(
     81     const std::string& username,
     82     const std::string& from_key,
     83     const std::string& to_key,
     84     const AsyncMethodCallback& callback) {
     85   ReturnAsyncMethodResult(callback, false);
     86 }
     87 
     88 void FakeCryptohomeClient::AsyncRemove(
     89     const std::string& username,
     90     const AsyncMethodCallback& callback) {
     91   ReturnAsyncMethodResult(callback, false);
     92 }
     93 
     94 void FakeCryptohomeClient::GetSystemSalt(
     95     const GetSystemSaltCallback& callback) {
     96   base::MessageLoop::current()->PostTask(
     97       FROM_HERE,
     98       base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, system_salt_));
     99 }
    100 
    101 void FakeCryptohomeClient::GetSanitizedUsername(
    102     const std::string& username,
    103     const StringDBusMethodCallback& callback) {
    104   // Even for stub implementation we have to return different values so that
    105   // multi-profiles would work.
    106   std::string sanitized_username = GetStubSanitizedUsername(username);
    107   base::MessageLoop::current()->PostTask(
    108       FROM_HERE,
    109       base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username));
    110 }
    111 
    112 std::string FakeCryptohomeClient::BlockingGetSanitizedUsername(
    113     const std::string& username) {
    114   return GetStubSanitizedUsername(username);
    115 }
    116 
    117 void FakeCryptohomeClient::AsyncMount(const std::string& username,
    118                                           const std::string& key,
    119                                           int flags,
    120                                           const AsyncMethodCallback& callback) {
    121   ReturnAsyncMethodResult(callback, false);
    122 }
    123 
    124 void FakeCryptohomeClient::AsyncAddKey(
    125     const std::string& username,
    126     const std::string& key,
    127     const std::string& new_key,
    128     const AsyncMethodCallback& callback) {
    129   ReturnAsyncMethodResult(callback, false);
    130 }
    131 
    132 void FakeCryptohomeClient::AsyncMountGuest(
    133     const AsyncMethodCallback& callback) {
    134   ReturnAsyncMethodResult(callback, false);
    135 }
    136 
    137 void FakeCryptohomeClient::AsyncMountPublic(
    138     const std::string& public_mount_id,
    139     int flags,
    140     const AsyncMethodCallback& callback) {
    141   ReturnAsyncMethodResult(callback, false);
    142 }
    143 
    144 void FakeCryptohomeClient::TpmIsReady(
    145     const BoolDBusMethodCallback& callback) {
    146   base::MessageLoop::current()->PostTask(
    147       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    148 }
    149 
    150 void FakeCryptohomeClient::TpmIsEnabled(
    151     const BoolDBusMethodCallback& callback) {
    152   base::MessageLoop::current()->PostTask(
    153       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    154 }
    155 
    156 bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) {
    157   *enabled = true;
    158   return true;
    159 }
    160 
    161 void FakeCryptohomeClient::TpmGetPassword(
    162     const StringDBusMethodCallback& callback) {
    163   const char kStubTpmPassword[] = "Stub-TPM-password";
    164   base::MessageLoop::current()->PostTask(
    165       FROM_HERE,
    166       base::Bind(callback, DBUS_METHOD_CALL_SUCCESS,
    167                  std::string(kStubTpmPassword)));
    168 }
    169 
    170 void FakeCryptohomeClient::TpmIsOwned(
    171     const BoolDBusMethodCallback& callback) {
    172   base::MessageLoop::current()->PostTask(
    173       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    174 }
    175 
    176 bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) {
    177   *owned = true;
    178   return true;
    179 }
    180 
    181 void FakeCryptohomeClient::TpmIsBeingOwned(
    182     const BoolDBusMethodCallback& callback) {
    183   base::MessageLoop::current()->PostTask(
    184       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    185 }
    186 
    187 bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) {
    188   *owning = true;
    189   return true;
    190 }
    191 
    192 void FakeCryptohomeClient::TpmCanAttemptOwnership(
    193     const VoidDBusMethodCallback& callback) {
    194   base::MessageLoop::current()->PostTask(
    195       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
    196 }
    197 
    198 void FakeCryptohomeClient::TpmClearStoredPassword(
    199     const VoidDBusMethodCallback& callback) {
    200   base::MessageLoop::current()->PostTask(
    201       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
    202 }
    203 
    204 bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() {
    205   return true;
    206 }
    207 
    208 void FakeCryptohomeClient::Pkcs11IsTpmTokenReady(
    209     const BoolDBusMethodCallback& callback) {
    210   base::MessageLoop::current()->PostTask(
    211       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    212 }
    213 
    214 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo(
    215     const Pkcs11GetTpmTokenInfoCallback& callback) {
    216   const char kStubTPMTokenName[] = "StubTPMTokenName";
    217   const char kStubUserPin[] = "012345";
    218   const int kStubSlot = 0;
    219   base::MessageLoop::current()->PostTask(
    220       FROM_HERE,
    221       base::Bind(callback,
    222                  DBUS_METHOD_CALL_SUCCESS,
    223                  std::string(kStubTPMTokenName),
    224                  std::string(kStubUserPin),
    225                  kStubSlot));
    226 }
    227 
    228 void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser(
    229     const std::string& username,
    230     const Pkcs11GetTpmTokenInfoCallback& callback) {
    231   Pkcs11GetTpmTokenInfo(callback);
    232 }
    233 
    234 bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name,
    235                                                     std::vector<uint8>* value,
    236                                                     bool* successful) {
    237   if (install_attrs_.find(name) != install_attrs_.end()) {
    238     *value = install_attrs_[name];
    239     *successful = true;
    240   } else {
    241     value->clear();
    242     *successful = false;
    243   }
    244   return true;
    245 }
    246 
    247 bool FakeCryptohomeClient::InstallAttributesSet(
    248     const std::string& name,
    249     const std::vector<uint8>& value,
    250     bool* successful) {
    251   install_attrs_[name] = value;
    252   *successful = true;
    253   return true;
    254 }
    255 
    256 bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
    257   locked_ = true;
    258   *successful = true;
    259 
    260   // Persist the install attributes so that they can be reloaded if the
    261   // browser is restarted. This is used for ease of development when device
    262   // enrollment is required.
    263   // The cryptohome::SerializedInstallAttributes protobuf lives in
    264   // chrome/browser/chromeos, so it can't be used directly here; use the
    265   // low-level protobuf API instead to just write the name-value pairs.
    266   // The cache file is read by EnterpriseInstallAttributes::ReadCacheFile.
    267   base::FilePath cache_path;
    268   if (!PathService::Get(chromeos::FILE_INSTALL_ATTRIBUTES, &cache_path))
    269     return false;
    270 
    271   std::string result;
    272   {
    273     // |result| can be used only after the StringOutputStream goes out of
    274     // scope.
    275     google::protobuf::io::StringOutputStream result_stream(&result);
    276     google::protobuf::io::CodedOutputStream result_output(&result_stream);
    277 
    278     // These tags encode a variable-length value on the wire, which can be
    279     // used to encode strings, bytes and messages. We only needs constants
    280     // for tag numbers 1 and 2 (see install_attributes.proto).
    281     const int kVarLengthTag1 = (1 << 3) | 0x2;
    282     const int kVarLengthTag2 = (2 << 3) | 0x2;
    283 
    284     typedef std::map<std::string, std::vector<uint8> >::const_iterator Iter;
    285     for (Iter it = install_attrs_.begin(); it != install_attrs_.end(); ++it) {
    286       std::string attr;
    287       {
    288         google::protobuf::io::StringOutputStream attr_stream(&attr);
    289         google::protobuf::io::CodedOutputStream attr_output(&attr_stream);
    290 
    291         attr_output.WriteVarint32(kVarLengthTag1);
    292         attr_output.WriteVarint32(it->first.size());
    293         attr_output.WriteString(it->first);
    294         attr_output.WriteVarint32(kVarLengthTag2);
    295         attr_output.WriteVarint32(it->second.size());
    296         attr_output.WriteRaw(it->second.data(), it->second.size());
    297       }
    298 
    299       // Two CodedOutputStreams are needed because inner messages must be
    300       // prefixed by their total length, which can't be easily computed before
    301       // writing their tags and values.
    302       result_output.WriteVarint32(kVarLengthTag2);
    303       result_output.WriteVarint32(attr.size());
    304       result_output.WriteRaw(attr.data(), attr.size());
    305     }
    306   }
    307 
    308   // The real implementation does a blocking wait on the dbus call; the fake
    309   // implementation must have this file written before returning.
    310   base::ThreadRestrictions::ScopedAllowIO allow_io;
    311   base::WriteFile(cache_path, result.data(), result.size());
    312 
    313   return true;
    314 }
    315 
    316 void FakeCryptohomeClient::InstallAttributesIsReady(
    317     const BoolDBusMethodCallback& callback) {
    318   base::MessageLoop::current()->PostTask(
    319       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    320 }
    321 
    322 bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) {
    323   *is_invalid = false;
    324   return true;
    325 }
    326 
    327 bool FakeCryptohomeClient::InstallAttributesIsFirstInstall(
    328     bool* is_first_install) {
    329   *is_first_install = !locked_;
    330   return true;
    331 }
    332 
    333 void FakeCryptohomeClient::TpmAttestationIsPrepared(
    334     const BoolDBusMethodCallback& callback) {
    335   base::MessageLoop::current()->PostTask(
    336       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    337 }
    338 
    339 void FakeCryptohomeClient::TpmAttestationIsEnrolled(
    340     const BoolDBusMethodCallback& callback) {
    341   base::MessageLoop::current()->PostTask(
    342       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
    343 }
    344 
    345 void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest(
    346     chromeos::attestation::PrivacyCAType pca_type,
    347     const AsyncMethodCallback& callback) {
    348   ReturnAsyncMethodResult(callback, true);
    349 }
    350 
    351 void FakeCryptohomeClient::AsyncTpmAttestationEnroll(
    352     chromeos::attestation::PrivacyCAType pca_type,
    353     const std::string& pca_response,
    354     const AsyncMethodCallback& callback) {
    355   ReturnAsyncMethodResult(callback, false);
    356 }
    357 
    358 void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest(
    359     chromeos::attestation::PrivacyCAType pca_type,
    360     attestation::AttestationCertificateProfile certificate_profile,
    361     const std::string& user_id,
    362     const std::string& request_origin,
    363     const AsyncMethodCallback& callback) {
    364   ReturnAsyncMethodResult(callback, true);
    365 }
    366 
    367 void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest(
    368     const std::string& pca_response,
    369     attestation::AttestationKeyType key_type,
    370     const std::string& user_id,
    371     const std::string& key_name,
    372     const AsyncMethodCallback& callback) {
    373   ReturnAsyncMethodResult(callback, true);
    374 }
    375 
    376 void FakeCryptohomeClient::TpmAttestationDoesKeyExist(
    377     attestation::AttestationKeyType key_type,
    378     const std::string& user_id,
    379     const std::string& key_name,
    380     const BoolDBusMethodCallback& callback) {
    381   base::MessageLoop::current()->PostTask(
    382       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
    383 }
    384 
    385 void FakeCryptohomeClient::TpmAttestationGetCertificate(
    386     attestation::AttestationKeyType key_type,
    387     const std::string& user_id,
    388     const std::string& key_name,
    389     const DataMethodCallback& callback) {
    390   base::MessageLoop::current()->PostTask(
    391       FROM_HERE,
    392       base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
    393 }
    394 
    395 void FakeCryptohomeClient::TpmAttestationGetPublicKey(
    396     attestation::AttestationKeyType key_type,
    397     const std::string& user_id,
    398     const std::string& key_name,
    399     const DataMethodCallback& callback) {
    400   base::MessageLoop::current()->PostTask(
    401       FROM_HERE,
    402       base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
    403 }
    404 
    405 void FakeCryptohomeClient::TpmAttestationRegisterKey(
    406     attestation::AttestationKeyType key_type,
    407     const std::string& user_id,
    408     const std::string& key_name,
    409     const AsyncMethodCallback& callback) {
    410   ReturnAsyncMethodResult(callback, true);
    411 }
    412 
    413 void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
    414     attestation::AttestationKeyType key_type,
    415     const std::string& user_id,
    416     const std::string& key_name,
    417     const std::string& domain,
    418     const std::string& device_id,
    419     attestation::AttestationChallengeOptions options,
    420     const std::string& challenge,
    421     const AsyncMethodCallback& callback) {
    422   ReturnAsyncMethodResult(callback, true);
    423 }
    424 
    425 void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge(
    426     attestation::AttestationKeyType key_type,
    427     const std::string& user_id,
    428     const std::string& key_name,
    429     const std::string& challenge,
    430     const AsyncMethodCallback& callback) {
    431   ReturnAsyncMethodResult(callback, true);
    432 }
    433 
    434 void FakeCryptohomeClient::TpmAttestationGetKeyPayload(
    435     attestation::AttestationKeyType key_type,
    436     const std::string& user_id,
    437     const std::string& key_name,
    438     const DataMethodCallback& callback) {
    439   base::MessageLoop::current()->PostTask(
    440       FROM_HERE,
    441       base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
    442 }
    443 
    444 void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
    445     attestation::AttestationKeyType key_type,
    446     const std::string& user_id,
    447     const std::string& key_name,
    448     const std::string& payload,
    449     const BoolDBusMethodCallback& callback) {
    450   base::MessageLoop::current()->PostTask(
    451       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
    452 }
    453 
    454 void FakeCryptohomeClient::TpmAttestationDeleteKeys(
    455     attestation::AttestationKeyType key_type,
    456     const std::string& user_id,
    457     const std::string& key_prefix,
    458     const BoolDBusMethodCallback& callback) {
    459   base::MessageLoop::current()->PostTask(
    460       FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
    461 }
    462 
    463 void FakeCryptohomeClient::GetKeyDataEx(
    464     const cryptohome::AccountIdentifier& id,
    465     const cryptohome::AuthorizationRequest& auth,
    466     const cryptohome::GetKeyDataRequest& request,
    467     const ProtobufMethodCallback& callback) {
    468   cryptohome::BaseReply reply;
    469   reply.MutableExtension(cryptohome::GetKeyDataReply::reply);
    470   ReturnProtobufMethodCallback(reply, callback);
    471 }
    472 
    473 void FakeCryptohomeClient::CheckKeyEx(
    474     const cryptohome::AccountIdentifier& id,
    475     const cryptohome::AuthorizationRequest& auth,
    476     const cryptohome::CheckKeyRequest& request,
    477     const ProtobufMethodCallback& callback) {
    478   cryptohome::BaseReply reply;
    479   ReturnProtobufMethodCallback(reply, callback);
    480 }
    481 
    482 void FakeCryptohomeClient::MountEx(
    483     const cryptohome::AccountIdentifier& id,
    484     const cryptohome::AuthorizationRequest& auth,
    485     const cryptohome::MountRequest& request,
    486     const ProtobufMethodCallback& callback) {
    487   cryptohome::BaseReply reply;
    488   cryptohome::MountReply* mount =
    489       reply.MutableExtension(cryptohome::MountReply::reply);
    490   mount->set_sanitized_username(GetStubSanitizedUsername(id.email()));
    491   ReturnProtobufMethodCallback(reply, callback);
    492 }
    493 
    494 void FakeCryptohomeClient::AddKeyEx(
    495     const cryptohome::AccountIdentifier& id,
    496     const cryptohome::AuthorizationRequest& auth,
    497     const cryptohome::AddKeyRequest& request,
    498     const ProtobufMethodCallback& callback) {
    499   cryptohome::BaseReply reply;
    500   ReturnProtobufMethodCallback(reply, callback);
    501 }
    502 
    503 void FakeCryptohomeClient::RemoveKeyEx(
    504     const cryptohome::AccountIdentifier& id,
    505     const cryptohome::AuthorizationRequest& auth,
    506     const cryptohome::RemoveKeyRequest& request,
    507     const ProtobufMethodCallback& callback) {
    508   cryptohome::BaseReply reply;
    509   ReturnProtobufMethodCallback(reply, callback);
    510 }
    511 
    512 void FakeCryptohomeClient::UpdateKeyEx(
    513     const cryptohome::AccountIdentifier& id,
    514     const cryptohome::AuthorizationRequest& auth,
    515     const cryptohome::UpdateKeyRequest& request,
    516     const ProtobufMethodCallback& callback) {
    517   cryptohome::BaseReply reply;
    518   ReturnProtobufMethodCallback(reply, callback);
    519 }
    520 
    521 void FakeCryptohomeClient::GetBootAttribute(
    522     const cryptohome::GetBootAttributeRequest& request,
    523     const ProtobufMethodCallback& callback) {
    524   cryptohome::BaseReply reply;
    525   cryptohome::GetBootAttributeReply* attr_reply =
    526       reply.MutableExtension(cryptohome::GetBootAttributeReply::reply);
    527   attr_reply->set_value("");
    528   ReturnProtobufMethodCallback(reply, callback);
    529 }
    530 
    531 void FakeCryptohomeClient::SetBootAttribute(
    532     const cryptohome::SetBootAttributeRequest& request,
    533     const ProtobufMethodCallback& callback) {
    534   cryptohome::BaseReply reply;
    535   ReturnProtobufMethodCallback(reply, callback);
    536 }
    537 
    538 void FakeCryptohomeClient::FlushAndSignBootAttributes(
    539     const cryptohome::FlushAndSignBootAttributesRequest& request,
    540     const ProtobufMethodCallback& callback) {
    541   cryptohome::BaseReply reply;
    542   ReturnProtobufMethodCallback(reply, callback);
    543 }
    544 
    545 void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
    546   service_is_available_ = is_available;
    547   if (is_available) {
    548     std::vector<WaitForServiceToBeAvailableCallback> callbacks;
    549     callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
    550     for (size_t i = 0; i < callbacks.size(); ++i)
    551       callbacks[i].Run(is_available);
    552   }
    553 }
    554 
    555 // static
    556 std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
    557   const char kStubSystemSalt[] = "stub_system_salt";
    558   return std::vector<uint8>(kStubSystemSalt,
    559                             kStubSystemSalt + arraysize(kStubSystemSalt) - 1);
    560 }
    561 
    562 void FakeCryptohomeClient::ReturnProtobufMethodCallback(
    563     const cryptohome::BaseReply& reply,
    564     const ProtobufMethodCallback& callback) {
    565   base::MessageLoop::current()->PostTask(
    566       FROM_HERE,
    567       base::Bind(callback,
    568                  DBUS_METHOD_CALL_SUCCESS,
    569                  true,
    570                  reply));
    571 }
    572 
    573 void FakeCryptohomeClient::ReturnAsyncMethodResult(
    574     const AsyncMethodCallback& callback,
    575     bool returns_data) {
    576   base::MessageLoop::current()->PostTask(
    577       FROM_HERE,
    578       base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal,
    579                  weak_ptr_factory_.GetWeakPtr(),
    580                  callback,
    581                  returns_data));
    582 }
    583 
    584 void FakeCryptohomeClient::ReturnAsyncMethodResultInternal(
    585     const AsyncMethodCallback& callback,
    586     bool returns_data) {
    587   callback.Run(async_call_id_);
    588   if (!returns_data && !async_call_status_handler_.is_null()) {
    589     base::MessageLoop::current()->PostTask(
    590         FROM_HERE,
    591         base::Bind(async_call_status_handler_,
    592                    async_call_id_,
    593                    true,
    594                    cryptohome::MOUNT_ERROR_NONE));
    595   } else if (returns_data && !async_call_status_data_handler_.is_null()) {
    596     base::MessageLoop::current()->PostTask(
    597         FROM_HERE,
    598         base::Bind(async_call_status_data_handler_,
    599                    async_call_id_,
    600                    true,
    601                    std::string()));
    602   }
    603   ++async_call_id_;
    604 }
    605 
    606 }  // namespace chromeos
    607