Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "service.h" | 5 #include "service.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 | 9 |
| 10 #include <base/file_util.h> | 10 #include <base/file_util.h> |
| 11 #include <base/logging.h> | 11 #include <base/logging.h> |
| 12 #include <base/string_util.h> | 12 #include <base/string_util.h> |
| 13 #include <base/time.h> | 13 #include <base/time.h> |
| 14 #include <chromeos/dbus/dbus.h> | 14 #include <chromeos/dbus/dbus.h> |
| 15 #include <string> | |
| 16 #include <vector> | |
| 15 | 17 |
| 16 #include "cryptohome/marshal.glibmarshal.h" | 18 #include "cryptohome/marshal.glibmarshal.h" |
| 17 #include "cryptohome_event_source.h" | 19 #include "cryptohome_event_source.h" |
| 18 #include "interface.h" | 20 #include "interface.h" |
| 19 #include "crypto.h" | 21 #include "crypto.h" |
| 22 #include "lockbox.h" | |
| 20 #include "mount.h" | 23 #include "mount.h" |
| 21 #include "secure_blob.h" | 24 #include "secure_blob.h" |
| 22 #include "tpm.h" | 25 #include "tpm.h" |
| 23 #include "username_passkey.h" | 26 #include "username_passkey.h" |
| 24 #include "vault_keyset.pb.h" | 27 #include "vault_keyset.pb.h" |
| 25 | 28 |
| 26 // Forcibly namespace the dbus-bindings generated server bindings instead of | 29 // Forcibly namespace the dbus-bindings generated server bindings instead of |
| 27 // modifying the files afterward. | 30 // modifying the files afterward. |
| 28 namespace cryptohome { // NOLINT | 31 namespace cryptohome { // NOLINT |
| 29 namespace gobject { // NOLINT | 32 namespace gobject { // NOLINT |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 system_salt_(), | 82 system_salt_(), |
| 80 default_mount_(new cryptohome::Mount()), | 83 default_mount_(new cryptohome::Mount()), |
| 81 mount_(default_mount_.get()), | 84 mount_(default_mount_.get()), |
| 82 default_tpm_init_(new TpmInit()), | 85 default_tpm_init_(new TpmInit()), |
| 83 tpm_init_(default_tpm_init_.get()), | 86 tpm_init_(default_tpm_init_.get()), |
| 84 initialize_tpm_(true), | 87 initialize_tpm_(true), |
| 85 mount_thread_(kMountThreadName), | 88 mount_thread_(kMountThreadName), |
| 86 async_complete_signal_(-1), | 89 async_complete_signal_(-1), |
| 87 tpm_init_signal_(-1), | 90 tpm_init_signal_(-1), |
| 88 event_source_(), | 91 event_source_(), |
| 89 auto_cleanup_period_(kAutoCleanupPeriodMS) { | 92 auto_cleanup_period_(kAutoCleanupPeriodMS), |
| 93 default_lockbox_(new cryptohome::Lockbox()), | |
| 94 lockbox_(default_lockbox_.get()) { | |
| 90 } | 95 } |
| 91 | 96 |
| 92 Service::~Service() { | 97 Service::~Service() { |
| 93 if (loop_) | 98 if (loop_) |
| 94 g_main_loop_unref(loop_); | 99 g_main_loop_unref(loop_); |
| 95 if (cryptohome_) | 100 if (cryptohome_) |
| 96 g_object_unref(cryptohome_); | 101 g_object_unref(cryptohome_); |
| 97 if (mount_thread_.IsRunning()) { | 102 if (mount_thread_.IsRunning()) { |
| 98 mount_thread_.Stop(); | 103 mount_thread_.Stop(); |
| 99 } | 104 } |
| 100 } | 105 } |
| 101 | 106 |
| 102 bool Service::Initialize() { | 107 bool Service::Initialize() { |
| 103 bool result = true; | 108 bool result = true; |
| 104 | 109 |
| 105 mount_->Init(); | 110 mount_->Init(); |
| 111 // If the TPM is unowned or doesn't exist, it's safe for | |
| 112 // this function to be called again. However, it shouldn't | |
| 113 // be called across multiple threads in parallel. | |
|
gauravsh
2011/04/11 04:03:20
Is this comment for InitializeLockBox()? If so, ca
Will Drewry
2011/04/13 16:04:59
The part that is relevant (thread safety) is in th
| |
| 114 InitializeLockbox(); | |
| 115 | |
| 106 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); | 116 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); |
| 107 if (tpm && initialize_tpm_) { | 117 if (tpm && initialize_tpm_) { |
| 108 tpm_init_->set_tpm(tpm); | 118 tpm_init_->set_tpm(tpm); |
| 109 tpm_init_->Init(this); | 119 tpm_init_->Init(this); |
| 110 if (!SeedUrandom()) { | 120 if (!SeedUrandom()) { |
| 111 LOG(ERROR) << "FAILED TO SEED /dev/urandom AT START"; | 121 LOG(ERROR) << "FAILED TO SEED /dev/urandom AT START"; |
| 112 } | 122 } |
| 113 } | 123 } |
| 114 | |
| 115 // Install the type-info for the service with dbus. | 124 // Install the type-info for the service with dbus. |
| 116 dbus_g_object_type_install_info(gobject::cryptohome_get_type(), | 125 dbus_g_object_type_install_info(gobject::cryptohome_get_type(), |
| 117 &gobject::dbus_glib_cryptohome_object_info); | 126 &gobject::dbus_glib_cryptohome_object_info); |
| 118 if (!Reset()) { | 127 if (!Reset()) { |
| 119 result = false; | 128 result = false; |
| 120 } | 129 } |
| 121 | 130 |
| 122 async_complete_signal_ = g_signal_new("async_call_status", | 131 async_complete_signal_ = g_signal_new("async_call_status", |
| 123 gobject::cryptohome_get_type(), | 132 gobject::cryptohome_get_type(), |
| 124 G_SIGNAL_RUN_LAST, | 133 G_SIGNAL_RUN_LAST, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 149 | 158 |
| 150 // Start scheduling periodic cleanup events. Note, that the first | 159 // Start scheduling periodic cleanup events. Note, that the first |
| 151 // event will be called by Chrome explicitly from the login screen. | 160 // event will be called by Chrome explicitly from the login screen. |
| 152 mount_thread_.message_loop()->PostDelayedTask( | 161 mount_thread_.message_loop()->PostDelayedTask( |
| 153 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback), | 162 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback), |
| 154 auto_cleanup_period_); | 163 auto_cleanup_period_); |
| 155 | 164 |
| 156 return result; | 165 return result; |
| 157 } | 166 } |
| 158 | 167 |
| 168 void Service::InitializeLockbox() { | |
|
gauravsh
2011/04/11 04:03:20
Should this return true or false? Otherwise the ca
Will Drewry
2011/04/13 16:04:59
The caller doesn't matter as much unless we want c
| |
| 169 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); | |
| 170 // Don't call this until the TPM is owned. | |
| 171 if (tpm && !tpm->IsOwned()) | |
| 172 return; | |
| 173 // tpm will be NULL if the system lacks one. | |
| 174 lockbox_->Init(tpm, | |
| 175 Lockbox::kDefaultNvramIndex, | |
| 176 Lockbox::kDefaultPath); | |
| 177 } | |
| 178 | |
| 159 bool Service::SeedUrandom() { | 179 bool Service::SeedUrandom() { |
| 160 SecureBlob random; | 180 SecureBlob random; |
| 161 if (!tpm_init_->GetRandomData(kDefaultRandomSeedLength, &random)) { | 181 if (!tpm_init_->GetRandomData(kDefaultRandomSeedLength, &random)) { |
| 162 LOG(ERROR) << "Could not get random data from the TPM"; | 182 LOG(ERROR) << "Could not get random data from the TPM"; |
| 163 return false; | 183 return false; |
| 164 } | 184 } |
| 165 size_t written = file_util::WriteFile(FilePath(kDefaultEntropySource), | 185 size_t written = file_util::WriteFile(FilePath(kDefaultEntropySource), |
| 166 static_cast<const char*>(random.const_data()), random.size()); | 186 static_cast<const char*>(random.const_data()), random.size()); |
| 167 if (written != random.size()) { | 187 if (written != random.size()) { |
| 168 LOG(ERROR) << "Error writing data to /dev/urandom"; | 188 LOG(ERROR) << "Error writing data to /dev/urandom"; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 199 | 219 |
| 200 void Service::NotifyEvent(CryptohomeEventBase* event) { | 220 void Service::NotifyEvent(CryptohomeEventBase* event) { |
| 201 if (!strcmp(event->GetEventName(), kMountTaskResultEventType)) { | 221 if (!strcmp(event->GetEventName(), kMountTaskResultEventType)) { |
| 202 MountTaskResult* result = static_cast<MountTaskResult*>(event); | 222 MountTaskResult* result = static_cast<MountTaskResult*>(event); |
| 203 g_signal_emit(cryptohome_, async_complete_signal_, 0, result->sequence_id(), | 223 g_signal_emit(cryptohome_, async_complete_signal_, 0, result->sequence_id(), |
| 204 result->return_status(), result->return_code()); | 224 result->return_status(), result->return_code()); |
| 205 } else if (!strcmp(event->GetEventName(), kTpmInitStatusEventType)) { | 225 } else if (!strcmp(event->GetEventName(), kTpmInitStatusEventType)) { |
| 206 TpmInitStatus* result = static_cast<TpmInitStatus*>(event); | 226 TpmInitStatus* result = static_cast<TpmInitStatus*>(event); |
| 207 g_signal_emit(cryptohome_, tpm_init_signal_, 0, tpm_init_->IsTpmReady(), | 227 g_signal_emit(cryptohome_, tpm_init_signal_, 0, tpm_init_->IsTpmReady(), |
| 208 tpm_init_->IsTpmEnabled(), result->get_took_ownership()); | 228 tpm_init_->IsTpmEnabled(), result->get_took_ownership()); |
| 229 // TODO(wad) should we package up a Lockbox status here too? | |
| 209 } | 230 } |
| 210 } | 231 } |
| 211 | 232 |
| 212 void Service::InitializeTpmComplete(bool status, bool took_ownership) { | 233 void Service::InitializeTpmComplete(bool status, bool took_ownership) { |
| 213 if (took_ownership) { | 234 if (took_ownership) { |
| 214 MountTaskResult ignored_result; | 235 MountTaskResult ignored_result; |
| 215 base::WaitableEvent event(true, false); | 236 base::WaitableEvent event(true, false); |
| 216 MountTaskResetTpmContext* mount_task = | 237 MountTaskResetTpmContext* mount_task = |
| 217 new MountTaskResetTpmContext(NULL, mount_); | 238 new MountTaskResetTpmContext(NULL, mount_); |
| 218 mount_task->set_result(&ignored_result); | 239 mount_task->set_result(&ignored_result); |
| 219 mount_task->set_complete_event(&event); | 240 mount_task->set_complete_event(&event); |
| 220 mount_thread_.message_loop()->PostTask(FROM_HERE, mount_task); | 241 mount_thread_.message_loop()->PostTask(FROM_HERE, mount_task); |
| 221 event.Wait(); | 242 event.Wait(); |
| 243 // Initialize the install-time locked attributes since we | |
| 244 // can't do it prior to ownership. | |
| 245 InitializeLockbox(); | |
| 222 } | 246 } |
| 223 // The event source will free this object | 247 // The event source will free this object |
| 224 TpmInitStatus* tpm_init_status = new TpmInitStatus(); | 248 TpmInitStatus* tpm_init_status = new TpmInitStatus(); |
| 225 tpm_init_status->set_status(status); | 249 tpm_init_status->set_status(status); |
| 226 tpm_init_status->set_took_ownership(took_ownership); | 250 tpm_init_status->set_took_ownership(took_ownership); |
| 227 event_source_.AddEvent(tpm_init_status); | 251 event_source_.AddEvent(tpm_init_status); |
| 228 } | 252 } |
| 229 | 253 |
| 230 gboolean Service::CheckKey(gchar *userid, | 254 gboolean Service::CheckKey(gchar *userid, |
| 231 gchar *key, | 255 gchar *key, |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 tpm_init_->StartInitializeTpm(); | 584 tpm_init_->StartInitializeTpm(); |
| 561 } | 585 } |
| 562 return TRUE; | 586 return TRUE; |
| 563 } | 587 } |
| 564 | 588 |
| 565 gboolean Service::TpmClearStoredPassword(GError** error) { | 589 gboolean Service::TpmClearStoredPassword(GError** error) { |
| 566 tpm_init_->ClearStoredTpmPassword(); | 590 tpm_init_->ClearStoredTpmPassword(); |
| 567 return TRUE; | 591 return TRUE; |
| 568 } | 592 } |
| 569 | 593 |
| 594 gboolean Service::LockboxGet(gchar* name, | |
| 595 GArray** OUT_value, | |
| 596 gboolean* OUT_successful, | |
| 597 GError** error) { | |
| 598 chromeos::Blob value; | |
| 599 *OUT_successful = lockbox_->Get(name, &value); | |
| 600 *OUT_value = g_array_new(false, false, sizeof(char)); | |
| 601 if (*OUT_successful) | |
| 602 g_array_append_vals(*OUT_value, &value.front(), value.size()); | |
| 603 return TRUE; | |
| 604 } | |
| 605 | |
| 606 gboolean Service::LockboxSet(gchar* name, | |
| 607 GArray* value, | |
| 608 gboolean* OUT_successful, | |
| 609 GError** error) { | |
| 610 // Convert from GArray to vector | |
| 611 chromeos::Blob value_blob; | |
| 612 value_blob.assign(value->data, value->data + value->len); | |
| 613 *OUT_successful = lockbox_->Set(name, value_blob); | |
| 614 return TRUE; | |
| 615 } | |
| 616 | |
| 617 gboolean Service::LockboxLock(gboolean* OUT_locked, GError** error) { | |
| 618 *OUT_locked = lockbox_->Lock(); | |
| 619 return TRUE; | |
| 620 } | |
| 621 | |
| 622 gboolean Service::LockboxCount(gint* OUT_count, GError** error) { | |
| 623 // TODO(wad) for all of these functions return error on uninit. | |
| 624 // Follow the CHROMEOS_LOGIN_ERROR quark example in chromeos/dbus/ | |
| 625 *OUT_count = lockbox_->Count(); | |
| 626 return TRUE; | |
| 627 } | |
| 628 | |
| 629 gboolean Service::LockboxIsReady(gboolean* OUT_ready, GError** error) { | |
| 630 // Initialization is handled automatically when possible and async | |
| 631 // notification implies readiness. This allows other code to poll. | |
| 632 *OUT_ready = (lockbox_->initialized() == true); | |
| 633 return TRUE; | |
| 634 } | |
| 635 | |
| 636 gboolean Service::LockboxIsLocked(gboolean* OUT_locked, GError** error) { | |
| 637 *OUT_locked = (lockbox_->locked() == true); | |
| 638 return TRUE; | |
| 639 } | |
| 640 | |
| 641 gboolean Service::LockboxIsSecure(gboolean* OUT_secure, GError** error) { | |
| 642 *OUT_secure = (lockbox_->secure() == true); | |
| 643 return TRUE; | |
| 644 } | |
| 645 | |
| 646 gboolean Service::LockboxIsTampered(gboolean* OUT_tampered, GError** error) { | |
| 647 *OUT_tampered = (lockbox_->tampered() == true); | |
| 648 return TRUE; | |
| 649 } | |
| 650 | |
| 651 gboolean Service::LockboxIsLegacy(gboolean* OUT_legacy, GError** error) { | |
| 652 *OUT_legacy = (lockbox_->legacy() == true); | |
| 653 return TRUE; | |
| 654 } | |
| 655 | |
| 570 gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { | 656 gboolean Service::GetStatusString(gchar** OUT_status, GError** error) { |
| 571 Tpm::TpmStatusInfo tpm_status; | 657 Tpm::TpmStatusInfo tpm_status; |
| 572 mount_->get_crypto()->EnsureTpm(false); | 658 mount_->get_crypto()->EnsureTpm(false); |
| 573 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); | 659 Tpm* tpm = const_cast<Tpm*>(mount_->get_crypto()->get_tpm()); |
| 574 | 660 |
| 575 if (tpm) { | 661 if (tpm) { |
| 576 tpm->GetStatus(true, &tpm_status); | 662 tpm->GetStatus(true, &tpm_status); |
| 577 } else { | 663 } else { |
| 578 Tpm::GetSingleton()->GetStatus(true, &tpm_status); | 664 Tpm::GetSingleton()->GetStatus(true, &tpm_status); |
| 579 } | 665 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 " (UTC)\n", | 706 " (UTC)\n", |
| 621 ((serialized.flags() & | 707 ((serialized.flags() & |
| 622 cryptohome::SerializedVaultKeyset::TPM_WRAPPED) ? "1" : "0"), | 708 cryptohome::SerializedVaultKeyset::TPM_WRAPPED) ? "1" : "0"), |
| 623 ((serialized.flags() & | 709 ((serialized.flags() & |
| 624 cryptohome::SerializedVaultKeyset::SCRYPT_WRAPPED) ? "1" : "0"), | 710 cryptohome::SerializedVaultKeyset::SCRYPT_WRAPPED) ? "1" : "0"), |
| 625 exploded.month, exploded.day_of_month, exploded.year, | 711 exploded.month, exploded.day_of_month, exploded.year, |
| 626 exploded.hour, exploded.minute, exploded.second); | 712 exploded.hour, exploded.minute, exploded.second); |
| 627 | 713 |
| 628 } while(false); | 714 } while(false); |
| 629 } | 715 } |
| 716 int lockbox_size = lockbox_->Count(); | |
| 717 std::string lockbox_data("Lockbox Contents:\n"); | |
| 718 if (lockbox_->Count()) { | |
| 719 std::string name; | |
| 720 chromeos::Blob value; | |
| 721 for (int pair = 0; pair < lockbox_size; ++pair) { | |
| 722 lockbox_data += StringPrintf( | |
|
gauravsh
2011/04/11 04:03:20
is using += as efficient as using append()? (not t
Will Drewry
2011/04/13 16:04:59
No idea. Done.
gauravsh
2011/04/14 07:39:52
Yeah, it seems either append or += is ok. What's n
| |
| 723 " Index...........................: %d\n", pair); | |
| 724 if (lockbox_->GetNameByIndex(pair, &name) && | |
| 725 lockbox_->GetValueByIndex(pair, &value)) { | |
| 726 std::string value_str(reinterpret_cast<const char*>(&value[0]), | |
| 727 value.size()); | |
| 728 lockbox_data += StringPrintf( | |
| 729 " Name............................: %s\n" | |
| 730 " Value...........................: %s\n", | |
| 731 name.c_str(), | |
| 732 value_str.c_str()); | |
| 733 } | |
| 734 } | |
| 735 } | |
| 630 | 736 |
| 631 *OUT_status = g_strdup_printf( | 737 *OUT_status = g_strdup_printf( |
| 632 "TPM Status:\n" | 738 "TPM Status:\n" |
| 633 " Enabled.........................: %s\n" | 739 " Enabled.........................: %s\n" |
| 634 " Owned...........................: %s\n" | 740 " Owned...........................: %s\n" |
| 635 " Being Owned.....................: %s\n" | 741 " Being Owned.....................: %s\n" |
| 636 " Can Connect.....................: %s\n" | 742 " Can Connect.....................: %s\n" |
| 637 " Can Load SRK....................: %s\n" | 743 " Can Load SRK....................: %s\n" |
| 638 " Can Load SRK Public.............: %s\n" | 744 " Can Load SRK Public.............: %s\n" |
| 639 " Has Cryptohome Key..............: %s\n" | 745 " Has Cryptohome Key..............: %s\n" |
| 640 " Can Encrypt.....................: %s\n" | 746 " Can Encrypt.....................: %s\n" |
| 641 " Can Decrypt.....................: %s\n" | 747 " Can Decrypt.....................: %s\n" |
| 642 " Instance Context................: %s\n" | 748 " Instance Context................: %s\n" |
| 643 " Instance Key Handle.............: %s\n" | 749 " Instance Key Handle.............: %s\n" |
| 644 " Last Error......................: %08x\n" | 750 " Last Error......................: %08x\n" |
| 645 "%s" | 751 "%s" |
| 646 "Mount Status:\n" | 752 "Mount Status:\n" |
| 647 " Vault Is Mounted................: %s\n", | 753 " Vault Is Mounted................: %s\n" |
| 754 "Lockbox Status:\n" | |
| 755 " Initialized.....................: %s\n" | |
| 756 " Secure..........................: %s\n" | |
| 757 " Legacy..........................: %s\n" | |
| 758 " Locked..........................: %s\n" | |
| 759 " Tampered........................: %s\n" | |
| 760 " Entries.........................: %d\n" | |
| 761 "%s", | |
| 648 (tpm_status.Enabled ? "1" : "0"), | 762 (tpm_status.Enabled ? "1" : "0"), |
| 649 (tpm_status.Owned ? "1" : "0"), | 763 (tpm_status.Owned ? "1" : "0"), |
| 650 (tpm_status.BeingOwned ? "1" : "0"), | 764 (tpm_status.BeingOwned ? "1" : "0"), |
| 651 (tpm_status.CanConnect ? "1" : "0"), | 765 (tpm_status.CanConnect ? "1" : "0"), |
| 652 (tpm_status.CanLoadSrk ? "1" : "0"), | 766 (tpm_status.CanLoadSrk ? "1" : "0"), |
| 653 (tpm_status.CanLoadSrkPublicKey ? "1" : "0"), | 767 (tpm_status.CanLoadSrkPublicKey ? "1" : "0"), |
| 654 (tpm_status.HasCryptohomeKey ? "1" : "0"), | 768 (tpm_status.HasCryptohomeKey ? "1" : "0"), |
| 655 (tpm_status.CanEncrypt ? "1" : "0"), | 769 (tpm_status.CanEncrypt ? "1" : "0"), |
| 656 (tpm_status.CanDecrypt ? "1" : "0"), | 770 (tpm_status.CanDecrypt ? "1" : "0"), |
| 657 (tpm_status.ThisInstanceHasContext ? "1" : "0"), | 771 (tpm_status.ThisInstanceHasContext ? "1" : "0"), |
| 658 (tpm_status.ThisInstanceHasKeyHandle ? "1" : "0"), | 772 (tpm_status.ThisInstanceHasKeyHandle ? "1" : "0"), |
| 659 tpm_status.LastTpmError, | 773 tpm_status.LastTpmError, |
| 660 user_data.c_str(), | 774 user_data.c_str(), |
| 661 (mount_->IsCryptohomeMounted() ? "1" : "0")); | 775 (mount_->IsCryptohomeMounted() ? "1" : "0"), |
| 776 (lockbox_->initialized() ? "1" : "0"), | |
| 777 (lockbox_->secure() ? "1" : "0"), | |
| 778 (lockbox_->legacy() ? "1" : "0"), | |
| 779 (lockbox_->locked() ? "1" : "0"), | |
| 780 (lockbox_->tampered() ? "1" : "0"), | |
| 781 lockbox_size, | |
| 782 lockbox_data.c_str()); | |
| 662 return TRUE; | 783 return TRUE; |
| 663 } | 784 } |
| 664 | 785 |
| 665 // Called on Mount thread. | 786 // Called on Mount thread. |
| 666 void Service::AutoCleanupCallback() { | 787 void Service::AutoCleanupCallback() { |
| 667 mount_->DoAutomaticFreeDiskSpaceControl(); | 788 mount_->DoAutomaticFreeDiskSpaceControl(); |
| 668 | 789 |
| 669 // Schedule our next call. If the thread is terminating, we would | 790 // Schedule our next call. If the thread is terminating, we would |
| 670 // not be called. | 791 // not be called. |
| 671 mount_thread_.message_loop()->PostDelayedTask( | 792 mount_thread_.message_loop()->PostDelayedTask( |
| 672 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback), | 793 FROM_HERE, NewRunnableMethod(this, &Service::AutoCleanupCallback), |
| 673 auto_cleanup_period_); | 794 auto_cleanup_period_); |
| 674 } | 795 } |
| 675 | 796 |
| 676 } // namespace cryptohome | 797 } // namespace cryptohome |
| 677 | 798 |
| 678 // We do not want AutoCleanupCallback() to refer the class and make it | 799 // We do not want AutoCleanupCallback() to refer the class and make it |
| 679 // wait for its execution. If Mount thread terminates, it will delete | 800 // wait for its execution. If Mount thread terminates, it will delete |
| 680 // our pending task or wait for it to finish. | 801 // our pending task or wait for it to finish. |
| 681 DISABLE_RUNNABLE_METHOD_REFCOUNT(cryptohome::Service); | 802 DISABLE_RUNNABLE_METHOD_REFCOUNT(cryptohome::Service); |
| OLD | NEW |