• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "stack_manager.h"
18 
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <chrono>
22 #include <future>
23 #include <queue>
24 
25 #include "common/bind.h"
26 #include "module.h"
27 #include "os/handler.h"
28 #include "os/log.h"
29 #include "os/thread.h"
30 #include "os/wakelock_manager.h"
31 
32 using ::bluetooth::os::Handler;
33 using ::bluetooth::os::Thread;
34 using ::bluetooth::os::WakelockManager;
35 
36 namespace bluetooth {
37 
38 constexpr char bluetooth_pid_file[] = "/var/run/bluetooth";
39 
40 void StackManager::StartUp(ModuleList* modules, Thread* stack_thread) {
41   management_thread_ = new Thread("management_thread", Thread::Priority::NORMAL);
42   handler_ = new Handler(management_thread_);
43 
44   WakelockManager::Get().Acquire();
45 
46   std::promise<void> promise;
47   auto future = promise.get_future();
48   handler_->Post(common::BindOnce(&StackManager::handle_start_up, common::Unretained(this), modules, stack_thread,
49                                   std::move(promise)));
50 
51   auto init_status = future.wait_for(std::chrono::seconds(3));
52 
53   WakelockManager::Get().Release();
54 
55   ASSERT_LOG(
56       init_status == std::future_status::ready,
57       "Can't start stack, last instance: %s",
58       registry_.last_instance_.c_str());
59 
60   pid_fd_ = open(bluetooth_pid_file, O_WRONLY | O_CREAT, 0644);
61   pid_t my_pid = getpid();
62   write(pid_fd_, &my_pid, sizeof(pid_t));
63 
64   LOG_INFO("init complete");
65 }
66 
67 void StackManager::handle_start_up(ModuleList* modules, Thread* stack_thread, std::promise<void> promise) {
68   registry_.Start(modules, stack_thread);
69   promise.set_value();
70 }
71 
72 void StackManager::ShutDown() {
73   WakelockManager::Get().Acquire();
74 
75   std::promise<void> promise;
76   auto future = promise.get_future();
77   handler_->Post(common::BindOnce(&StackManager::handle_shut_down, common::Unretained(this), std::move(promise)));
78 
79   auto stop_status = future.wait_for(std::chrono::seconds(5));
80 
81   WakelockManager::Get().Release();
82   WakelockManager::Get().CleanUp();
83 
84   ASSERT_LOG(
85       stop_status == std::future_status::ready,
86       "Can't stop stack, last instance: %s",
87       registry_.last_instance_.c_str());
88 
89   handler_->Clear();
90   handler_->WaitUntilStopped(std::chrono::milliseconds(2000));
91   delete handler_;
92   delete management_thread_;
93 
94   unlink(bluetooth_pid_file);
95   close(pid_fd_);
96 }
97 
98 void StackManager::handle_shut_down(std::promise<void> promise) {
99   registry_.StopAll();
100   promise.set_value();
101 }
102 
103 }  // namespace bluetooth
104