1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2015 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
1624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
1759b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan#include "shill/daemon_task.h"
1824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
1924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include <base/bind.h>
2024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
21bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal#if !defined(ENABLE_JSON_STORE)
22bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal#include <glib-object.h>
2359b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan#include <glib.h>
2460ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#endif  // ENABLE_JSON_STORE
25bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal
26a04c6448da585d8bef65b8bbd44711fd7882c917Samuel Tan#if defined(ENABLE_BINDER)
27a04c6448da585d8bef65b8bbd44711fd7882c917Samuel Tan#include "shill/binder/binder_control.h"
28a04c6448da585d8bef65b8bbd44711fd7882c917Samuel Tan#elif defined(ENABLE_CHROMEOS_DBUS)
29646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan#include "shill/dbus/chromeos_dbus_control.h"
30a04c6448da585d8bef65b8bbd44711fd7882c917Samuel Tan#endif  // ENABLE_BINDER, ENABLE_CHROMEOS_DBUS
3160ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#include "shill/control_interface.h"
3224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/dhcp/dhcp_provider.h"
3324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/error.h"
3424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/logging.h"
3524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/manager.h"
3624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/ndisc.h"
3724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/rtnl_handler.h"
38dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu#include "shill/process_manager.h"
3924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/routing_table.h"
4024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/shill_config.h"
4124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
4224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#if !defined(DISABLE_WIFI)
4324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/netlink_manager.h"
4424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#include "shill/net/nl80211_message.h"
4524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#endif  // DISABLE_WIFI
4624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
4724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing base::Bind;
4824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing base::Unretained;
4924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiuusing std::string;
5024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
5124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiunamespace shill {
5224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
5324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiunamespace Logging {
5424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiustatic auto kModuleLogScope = ScopeLogger::kDaemon;
5559b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanstatic string ObjectID(DaemonTask* d) { return "(chromeos_daemon)"; }
5624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
5724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
5859b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel TanDaemonTask::DaemonTask(const Settings& settings, Config* config)
5960ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan    : settings_(settings), config_(config) {}
6024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
6159b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel TanDaemonTask::~DaemonTask() {}
6224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
6359b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::ApplySettings() {
6491b7150819b785f36c2c094ae4aa102336bd6f71Peter Qiu  manager_->SetBlacklistedDevices(settings_.device_blacklist);
65c1d447354db29b83262c7db0857baa84e05e0c2aChristopher Grant  manager_->SetWhitelistedDevices(settings_.device_whitelist);
6624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  Error error;
67dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetTechnologyOrder(settings_.default_technology_order, &error);
6824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  CHECK(error.IsSuccess());  // Command line should have been validated.
69dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetIgnoreUnknownEthernet(settings_.ignore_unknown_ethernet);
70dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  if (settings_.use_portal_list) {
71dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu    manager_->SetStartupPortalList(settings_.portal_list);
7224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
73dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  if (settings_.passive_mode) {
7424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    manager_->SetPassiveMode();
7524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
76dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetPrependDNSServers(settings_.prepend_dns_servers);
77dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  if (settings_.minimum_mtu) {
78dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu    manager_->SetMinimumMTU(settings_.minimum_mtu);
7924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
80dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetAcceptHostnameFrom(settings_.accept_hostname_from);
81dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  manager_->SetDHCPv6EnabledDevices(settings_.dhcpv6_enabled_devices);
8224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
8324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
8459b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanbool DaemonTask::Quit(const base::Closure& completion_callback) {
8524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  SLOG(this, 1) << "Starting termination actions.";
86e6b41922d4bb33e7b80f77ef4b8cf02a9d68dd5emukesh agrawal  if (manager_->RunTerminationActionsAndNotifyMetrics(
8759b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan          Bind(&DaemonTask::TerminationActionsCompleted, Unretained(this)))) {
88e6b41922d4bb33e7b80f77ef4b8cf02a9d68dd5emukesh agrawal    SLOG(this, 1) << "Will wait for termination actions to complete";
89e6b41922d4bb33e7b80f77ef4b8cf02a9d68dd5emukesh agrawal    termination_completed_callback_ = completion_callback;
90e6b41922d4bb33e7b80f77ef4b8cf02a9d68dd5emukesh agrawal    return false;  // Note to caller: don't exit yet!
91e6b41922d4bb33e7b80f77ef4b8cf02a9d68dd5emukesh agrawal  } else {
9224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    SLOG(this, 1) << "No termination actions were run";
9324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    StopAndReturnToMain();
94e6b41922d4bb33e7b80f77ef4b8cf02a9d68dd5emukesh agrawal    return true;  // All done, ready to exit.
9524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
9624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
9724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
9859b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::Init() {
9960ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  dispatcher_.reset(new EventDispatcher());
10060ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#if defined(ENABLE_BINDER)
10160ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  control_.reset(new BinderControl(dispatcher_.get()));
10260ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#elif defined(ENABLE_CHROMEOS_DBUS)
10360ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  control_.reset(new ChromeosDBusControl(dispatcher_.get()));
10460ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#else
10560ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan// TODO(zqiu): use default stub control interface.
10660ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#error Control interface type not specified.
10760ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#endif  // ENABLE_BINDER, ENABLE_CHROMEOS_DBUS
10860ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  metrics_.reset(new Metrics(dispatcher_.get()));
10960ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  rtnl_handler_ = RTNLHandler::GetInstance();
11060ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  routing_table_ = RoutingTable::GetInstance();
11160ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  dhcp_provider_ = DHCPProvider::GetInstance();
11260ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  process_manager_ = ProcessManager::GetInstance();
11360ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#if !defined(DISABLE_WIFI)
11460ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  netlink_manager_ = NetlinkManager::GetInstance();
11560ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  callback80211_metrics_.reset(new Callback80211Metrics(metrics_.get()));
11660ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan#endif  // DISABLE_WIFI
11760ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  manager_.reset(new Manager(control_.get(), dispatcher_.get(), metrics_.get(),
11860ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan                             config_->GetRunDirectory(),
11960ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan                             config_->GetStorageDirectory(),
12060ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan                             config_->GetUserStorageDirectory()));
12160ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  control_->RegisterManagerObject(
12259b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan      manager_.get(), base::Bind(&DaemonTask::Start, base::Unretained(this)));
12360ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan  ApplySettings();
12460ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan}
12560ea15d40a3ad77536e01f2bb780181aa9c3c084Samuel Tan
12659b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::TerminationActionsCompleted(const Error& error) {
12724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  SLOG(this, 1) << "Finished termination actions.  Result: " << error;
12824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  metrics_->NotifyTerminationActionsCompleted(error.IsSuccess());
12924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
13024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::TerminationActionsCompleted() should not directly call
13124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::Stop(). Otherwise, it could lead to the call sequence below. That
13224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // is not safe as the HookTable's start callback only holds a weak pointer to
13324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // the Cellular object, which is destroyed in midst of the
13424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Cellular::OnTerminationCompleted() call. We schedule the
13524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::StopAndReturnToMain() call through the message loop instead.
13624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //
13724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  // Daemon::Quit
13824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //   -> Manager::RunTerminationActionsAndNotifyMetrics
13924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //     -> Manager::RunTerminationActions
14024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //       -> HookTable::Run
14124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //         ...
14224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //         -> Cellular::OnTerminationCompleted
14324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //           -> Manager::TerminationActionComplete
14424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //             -> HookTable::ActionComplete
14524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //               -> Daemon::TerminationActionsCompleted
14624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                 -> Daemon::Stop
14724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                   -> Manager::Stop
14824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                     -> DeviceInfo::Stop
14924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //                       -> Cellular::~Cellular
15024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  //           -> Manager::RemoveTerminationAction
151dde57ef146d3868130cd8597e805b42395440c9aPeter Qiu  dispatcher_->PostTask(
15259b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan      Bind(&DaemonTask::StopAndReturnToMain, Unretained(this)));
15324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
15424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
15559b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::StopAndReturnToMain() {
15624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  Stop();
1575988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  if (!termination_completed_callback_.is_null()) {
1585988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu    termination_completed_callback_.Run();
1595988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  }
16024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
16124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
16259b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::Start() {
163bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal#if !defined(ENABLE_JSON_STORE)
164bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal  g_type_init();
165bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal#endif
16624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  metrics_->Start();
16759b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan  rtnl_handler_->Start(RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
16859b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan                       RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
16959b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan                       RTMGRP_ND_USEROPT);
17024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  routing_table_->Start();
171646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan  dhcp_provider_->Init(control_.get(), dispatcher_.get(), metrics_.get());
172646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan  process_manager_->Init(dispatcher_.get());
17324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#if !defined(DISABLE_WIFI)
17424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  if (netlink_manager_) {
17524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    netlink_manager_->Init();
17659b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan    uint16_t nl80211_family_id =
17759b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan        netlink_manager_->GetFamily(Nl80211Message::kMessageTypeString,
17859b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan                                    Bind(&Nl80211Message::CreateMessage));
17924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    if (nl80211_family_id == NetlinkMessage::kIllegalMessageType) {
18024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu      LOG(FATAL) << "Didn't get a legal message type for 'nl80211' messages.";
18124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    }
18224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    Nl80211Message::SetMessageType(nl80211_family_id);
18324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    netlink_manager_->Start();
18424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
18524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    // Install handlers for NetlinkMessages that don't have specific handlers
18624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu    // (which are registered by message sequence number).
18759b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan    netlink_manager_->AddBroadcastHandler(
18859b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan        Bind(&Callback80211Metrics::CollectDisconnectStatistics,
18959b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tan             callback80211_metrics_->AsWeakPtr()));
19024b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  }
19124b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu#endif  // DISABLE_WIFI
19224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
19324b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  manager_->Start();
19424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
19524b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
19659b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::Stop() {
19724b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  manager_->Stop();
19824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  manager_ = nullptr;  // Release manager resources, including DBus adaptor.
1995988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu#if !defined(DISABLE_WIFI)
2005988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  callback80211_metrics_ = nullptr;
2015988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu#endif  // DISABLE_WIFI
20224b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  metrics_->Stop();
20389dfada74364ef9d750d7251236f8c58b111e57aPeter Qiu  process_manager_->Stop();
20424b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu  dhcp_provider_->Stop();
2055988a853c0faf8b5cf4a9c6a504a29a7098095a9Peter Qiu  metrics_ = nullptr;
206fb76b1b84bc3b3b75b12dd7889bdfd4b6dc00578Peter Qiu  // Must retain |control_|, as the D-Bus library may
207fb76b1b84bc3b3b75b12dd7889bdfd4b6dc00578Peter Qiu  // have some work left to do. See crbug.com/537771.
20824b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}
20924b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu
21059b397b6ac7fa39edf26d8e0ff2ecac6ac8ebc5bSamuel Tanvoid DaemonTask::BreakTerminationLoop() {
211646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan  // Break out of the termination loop, to continue on with other shutdown
212646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan  // tasks.
213646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan  brillo::MessageLoop::current()->BreakLoop();
214646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan}
215646c7e891789ea8abadd9e88bdd625d8bea2536dSamuel Tan
21624b34a0263ade24d39dfe41a7422bfcd0148fda6Peter Qiu}  // namespace shill
217