blob: 27610ec79e605078caa0b71e54e652309dd61253 [file] [log] [blame]
Vitaly Bukacad20f02015-10-16 17:27:15 -07001// Copyright 2015 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070014
15#include "buffet/manager.h"
16
Alex Vakulenko7c3226e2014-05-07 17:35:24 -070017#include <map>
Alex Vakulenkoec41a0c2015-04-17 15:35:34 -070018#include <set>
Alex Vakulenko7c3226e2014-05-07 17:35:24 -070019#include <string>
20
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070021#include <base/bind.h>
22#include <base/bind_helpers.h>
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070023#include <base/files/file_enumerator.h>
24#include <base/files/file_util.h>
Alex Vakulenko4f7778e2014-09-11 16:57:24 -070025#include <base/json/json_reader.h>
Christopher Wiley2ffa0042014-05-05 16:09:16 -070026#include <base/json/json_writer.h>
Alex Vakulenkof7754542015-06-26 12:59:50 -070027#include <base/message_loop/message_loop.h>
Christopher Wiley8994e012015-02-06 17:51:43 -080028#include <base/time/time.h>
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -080029#include <binderwrapper/binder_wrapper.h>
Alex Vakulenko790643f2015-11-19 14:38:30 -080030#include <cutils/properties.h>
Alex Vakulenko41705852015-10-13 10:12:06 -070031#include <brillo/bind_lambda.h>
Alex Vakulenko41705852015-10-13 10:12:06 -070032#include <brillo/errors/error.h>
33#include <brillo/http/http_transport.h>
34#include <brillo/http/http_utils.h>
35#include <brillo/key_value_store.h>
36#include <brillo/message_loops/message_loop.h>
37#include <brillo/mime_utils.h>
Christopher Wiley2ffa0042014-05-05 16:09:16 -070038#include <dbus/bus.h>
Christopher Wiley54028f92014-04-01 17:33:29 -070039#include <dbus/object_path.h>
Alex Vakulenkof3d77e52014-04-15 11:36:32 -070040#include <dbus/values_util.h>
Vitaly Bukae2713ac2015-08-03 13:50:01 -070041#include <weave/enum_to_string.h>
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070042
Alex Vakulenko790643f2015-11-19 14:38:30 -080043#include "brillo/weaved_system_properties.h"
Robert Gindaf86123d2015-09-11 16:10:43 -070044#include "buffet/bluetooth_client.h"
Vitaly Buka1175a9b2015-08-15 10:42:17 -070045#include "buffet/buffet_config.h"
Vitaly Buka00882b72015-08-06 00:32:11 -070046#include "buffet/http_transport_client.h"
Alex Vakulenkof0f55342015-08-18 15:51:40 -070047#include "buffet/mdns_client.h"
Peter Qiu786a9062015-10-02 11:45:01 -070048#include "buffet/shill_client.h"
Vitaly Buka4f771532015-08-14 14:58:39 -070049#include "buffet/weave_error_conversion.h"
Alex Vakulenko1642bec2015-08-19 09:34:58 -070050#include "buffet/webserv_client.h"
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -080051#include "common/binder_utils.h"
Vitaly Buka03319c22015-07-17 14:48:30 -070052
Alex Vakulenko41705852015-10-13 10:12:06 -070053using brillo::dbus_utils::AsyncEventSequencer;
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -080054using NotificationListener =
55 android::weave::IWeaveServiceManagerNotificationListener;
Christopher Wiley4b5f04c2014-03-27 14:45:37 -070056
57namespace buffet {
58
Alex Vakulenkoecf961a2014-10-28 13:50:16 -070059namespace {
Vitaly Buka7b3ba792015-06-09 17:01:54 -070060
Vitaly Buka0c6dcd22015-07-10 00:12:25 -070061const char kErrorDomain[] = "buffet";
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070062const char kFileReadError[] = "file_read_error";
63
64bool LoadFile(const base::FilePath& file_path,
65 std::string* data,
Alex Vakulenko41705852015-10-13 10:12:06 -070066 brillo::ErrorPtr* error) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070067 if (!base::ReadFileToString(file_path, data)) {
Alex Vakulenko41705852015-10-13 10:12:06 -070068 brillo::errors::system::AddSystemError(error, FROM_HERE, errno);
69 brillo::Error::AddToPrintf(error, FROM_HERE, kErrorDomain, kFileReadError,
70 "Failed to read file '%s'",
71 file_path.value().c_str());
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070072 return false;
73 }
74 return true;
75}
76
Alex Vakulenko3bd3ece2015-12-09 12:29:01 -080077void LoadTraitDefinitions(const BuffetConfig::Options& options,
78 weave::Device* device) {
79 // Load component-specific device trait definitions.
80 base::FilePath dir{options.definitions.Append("traits")};
81 LOG(INFO) << "Looking for trait definitions in " << dir.value();
82 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
83 FILE_PATH_LITERAL("*.json"));
84 std::vector<std::string> result;
85 for (base::FilePath path = enumerator.Next(); !path.empty();
86 path = enumerator.Next()) {
87 LOG(INFO) << "Loading trait definition from " << path.value();
88 std::string json;
89 CHECK(LoadFile(path, &json, nullptr));
90 device->AddTraitDefinitionsFromJson(json);
91 }
92}
93
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070094void LoadCommandDefinitions(const BuffetConfig::Options& options,
95 weave::Device* device) {
96 auto load_packages = [device](const base::FilePath& root,
97 const base::FilePath::StringType& pattern) {
98 base::FilePath dir{root.Append("commands")};
99 LOG(INFO) << "Looking for command schemas in " << dir.value();
100 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
101 pattern);
102 for (base::FilePath path = enumerator.Next(); !path.empty();
103 path = enumerator.Next()) {
104 LOG(INFO) << "Loading command schema from " << path.value();
105 std::string json;
106 CHECK(LoadFile(path, &json, nullptr));
107 device->AddCommandDefinitionsFromJson(json);
108 }
109 };
110 load_packages(options.definitions, FILE_PATH_LITERAL("*.json"));
Alex Vakulenko3bd3ece2015-12-09 12:29:01 -0800111 if (!options.test_definitions.empty())
112 load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json"));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700113}
114
115void LoadStateDefinitions(const BuffetConfig::Options& options,
116 weave::Device* device) {
117 // Load component-specific device state definitions.
118 base::FilePath dir{options.definitions.Append("states")};
119 LOG(INFO) << "Looking for state definitions in " << dir.value();
120 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
121 FILE_PATH_LITERAL("*.schema.json"));
122 std::vector<std::string> result;
123 for (base::FilePath path = enumerator.Next(); !path.empty();
124 path = enumerator.Next()) {
125 LOG(INFO) << "Loading state definition from " << path.value();
126 std::string json;
127 CHECK(LoadFile(path, &json, nullptr));
128 device->AddStateDefinitionsFromJson(json);
129 }
130}
131
132void LoadStateDefaults(const BuffetConfig::Options& options,
133 weave::Device* device) {
134 // Load component-specific device state defaults.
135 base::FilePath dir{options.definitions.Append("states")};
136 LOG(INFO) << "Looking for state defaults in " << dir.value();
137 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
138 FILE_PATH_LITERAL("*.defaults.json"));
139 std::vector<std::string> result;
140 for (base::FilePath path = enumerator.Next(); !path.empty();
141 path = enumerator.Next()) {
142 LOG(INFO) << "Loading state defaults from " << path.value();
143 std::string json;
144 CHECK(LoadFile(path, &json, nullptr));
145 CHECK(device->SetStatePropertiesFromJson(json, nullptr));
146 }
147}
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700148
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800149// Updates the manager's state property if the new value is different from
150// the current value. In this case also adds the appropriate notification ID
151// to the array to record the state change for clients.
152void UpdateValue(Manager* manager,
153 std::string Manager::* prop,
154 const std::string& new_value,
155 int notification,
156 std::vector<int>* notification_ids) {
157 if (manager->*prop != new_value) {
158 manager->*prop = new_value;
159 notification_ids->push_back(notification);
160 }
161}
162
Alex Vakulenkoecf961a2014-10-28 13:50:16 -0700163} // anonymous namespace
164
Alex Vakulenkoe32375b2015-09-28 08:55:40 -0700165class Manager::TaskRunner : public weave::provider::TaskRunner {
Vitaly Bukae74c8722015-08-13 00:33:00 -0700166 public:
167 void PostDelayedTask(const tracked_objects::Location& from_here,
168 const base::Closure& task,
169 base::TimeDelta delay) override {
Alex Vakulenko41705852015-10-13 10:12:06 -0700170 brillo::MessageLoop::current()->PostDelayedTask(from_here, task, delay);
Vitaly Bukae74c8722015-08-13 00:33:00 -0700171 }
172};
173
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700174Manager::Manager(const Options& options,
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800175 const scoped_refptr<dbus::Bus>& bus)
176 : options_{options}, bus_{bus} {}
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700177
Vitaly Buka91cc7152015-03-20 09:46:57 -0700178Manager::~Manager() {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800179 android::BinderWrapper* binder_wrapper = android::BinderWrapper::Get();
180 for (const auto& listener : notification_listeners_) {
181 binder_wrapper->UnregisterForDeathNotifications(
182 android::IInterface::asBinder(listener));
183 }
184 for (const auto& pair : services_) {
185 binder_wrapper->UnregisterForDeathNotifications(
186 android::IInterface::asBinder(pair.first));
187 }
Vitaly Buka91cc7152015-03-20 09:46:57 -0700188}
Alex Vakulenkoecf961a2014-10-28 13:50:16 -0700189
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700190void Manager::Start(AsyncEventSequencer* sequencer) {
191 RestartWeave(sequencer);
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700192}
193
194void Manager::RestartWeave(AsyncEventSequencer* sequencer) {
195 Stop();
196
Vitaly Bukae74c8722015-08-13 00:33:00 -0700197 task_runner_.reset(new TaskRunner{});
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700198 config_.reset(new BuffetConfig{options_.config_options});
Vitaly Buka00882b72015-08-06 00:32:11 -0700199 http_client_.reset(new HttpTransportClient);
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800200 shill_client_.reset(new ShillClient{bus_,
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700201 options_.device_whitelist,
202 !options_.xmpp_enabled});
Alex Vakulenko0022b752015-10-02 11:09:59 -0700203 weave::provider::HttpServer* http_server{nullptr};
Christopher Wileye925bb32015-08-03 20:09:18 -0700204#ifdef BUFFET_USE_WIFI_BOOTSTRAPPING
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700205 if (!options_.disable_privet) {
Casey Dahlin494b7242015-12-14 11:42:47 -0800206 mdns_client_ = MdnsClient::CreateInstance();
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700207 web_serv_client_.reset(new WebServClient{
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800208 bus_, sequencer,
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700209 base::Bind(&Manager::CreateDevice, weak_ptr_factory_.GetWeakPtr())});
Robert Gindaf86123d2015-09-11 16:10:43 -0700210 bluetooth_client_ = BluetoothClient::CreateInstance();
Alex Vakulenko0022b752015-10-02 11:09:59 -0700211 http_server = web_serv_client_.get();
212
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700213 if (options_.enable_ping) {
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700214 auto ping_handler = base::Bind(
215 [](std::unique_ptr<weave::provider::HttpServer::Request> request) {
Alex Vakulenko41705852015-10-13 10:12:06 -0700216 request->SendReply(brillo::http::status_code::Ok, "Hello, world!",
217 brillo::mime::text::kPlain);
Alex Vakulenko297114c2015-10-12 13:45:43 -0700218 });
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700219 http_server->AddHttpRequestHandler("/privet/ping", ping_handler);
220 http_server->AddHttpsRequestHandler("/privet/ping", ping_handler);
Alex Vakulenko0022b752015-10-02 11:09:59 -0700221 }
Alex Vakulenkof0f55342015-08-18 15:51:40 -0700222 }
Christopher Wileye925bb32015-08-03 20:09:18 -0700223#endif // BUFFET_USE_WIFI_BOOTSTRAPPING
Vitaly Buka7042c582015-07-30 17:02:14 -0700224
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700225 if (!http_server)
226 CreateDevice();
227}
228
229void Manager::CreateDevice() {
230 if (device_)
231 return;
232
Alex Vakulenko0022b752015-10-02 11:09:59 -0700233 device_ = weave::Device::Create(config_.get(), task_runner_.get(),
234 http_client_.get(), shill_client_.get(),
235 mdns_client_.get(), web_serv_client_.get(),
236 shill_client_.get(), bluetooth_client_.get());
Vitaly Buka1175a9b2015-08-15 10:42:17 -0700237
Alex Vakulenko3bd3ece2015-12-09 12:29:01 -0800238 LoadTraitDefinitions(options_.config_options, device_.get());
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700239 LoadCommandDefinitions(options_.config_options, device_.get());
240 LoadStateDefinitions(options_.config_options, device_.get());
241 LoadStateDefaults(options_.config_options, device_.get());
242
Alex Vakulenko0022b752015-10-02 11:09:59 -0700243 device_->AddSettingsChangedCallback(
244 base::Bind(&Manager::OnConfigChanged, weak_ptr_factory_.GetWeakPtr()));
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700245
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800246 device_->AddTraitDefsChangedCallback(
247 base::Bind(&Manager::OnTraitDefsChanged,
248 weak_ptr_factory_.GetWeakPtr()));
Alex Vakulenko0022b752015-10-02 11:09:59 -0700249 device_->AddStateChangedCallback(
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800250 base::Bind(&Manager::OnComponentTreeChanged,
251 weak_ptr_factory_.GetWeakPtr()));
252 device_->AddComponentTreeChangedCallback(
253 base::Bind(&Manager::OnComponentTreeChanged,
254 weak_ptr_factory_.GetWeakPtr()));
Vitaly Bukabf4ba652015-05-14 16:57:23 -0700255
Alex Vakulenko0022b752015-10-02 11:09:59 -0700256 device_->AddGcdStateChangedCallback(
257 base::Bind(&Manager::OnGcdStateChanged, weak_ptr_factory_.GetWeakPtr()));
Vitaly Bukae74fe3c2015-05-13 13:48:59 -0700258
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700259 device_->AddPairingChangedCallbacks(
260 base::Bind(&Manager::OnPairingStart, weak_ptr_factory_.GetWeakPtr()),
261 base::Bind(&Manager::OnPairingEnd, weak_ptr_factory_.GetWeakPtr()));
Alex Vakulenkoc662a242015-10-15 13:04:06 -0700262
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800263 CreateServicesForClients();
Vitaly Buka84fd6dd2015-06-09 17:22:18 -0700264}
265
266void Manager::Stop() {
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700267 device_.reset();
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700268#ifdef BUFFET_USE_WIFI_BOOTSTRAPPING
269 web_serv_client_.reset();
270 mdns_client_.reset();
271#endif // BUFFET_USE_WIFI_BOOTSTRAPPING
272 shill_client_.reset();
273 http_client_.reset();
274 config_.reset();
275 task_runner_.reset();
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700276}
277
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800278void Manager::OnTraitDefsChanged() {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800279 NotifyServiceManagerChange({NotificationListener::TRAITS});
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800280}
281
282void Manager::OnComponentTreeChanged() {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800283 NotifyServiceManagerChange({NotificationListener::COMPONENTS});
Vitaly Buka2b30e7a2015-05-27 09:27:08 -0700284}
285
Alex Vakulenko0022b752015-10-02 11:09:59 -0700286void Manager::OnGcdStateChanged(weave::GcdState state) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800287 state_ = weave::EnumToString(state);
288 NotifyServiceManagerChange({NotificationListener::STATE});
289 property_set(weaved::system_properties::kState, state_.c_str());
Vitaly Bukabf4ba652015-05-14 16:57:23 -0700290}
291
Vitaly Buka00b83492015-07-20 00:37:48 -0700292void Manager::OnConfigChanged(const weave::Settings& settings) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800293 std::vector<int> ids;
294 UpdateValue(this, &Manager::cloud_id_, settings.cloud_id,
295 NotificationListener::CLOUD_ID, &ids);
296 UpdateValue(this, &Manager::device_id_, settings.device_id,
297 NotificationListener::DEVICE_ID, &ids);
298 UpdateValue(this, &Manager::device_name_, settings.name,
299 NotificationListener::DEVICE_NAME, &ids);
300 UpdateValue(this, &Manager::device_description_, settings.description,
301 NotificationListener::DEVICE_DESCRIPTION, &ids);
302 UpdateValue(this, &Manager::device_location_, settings.location,
303 NotificationListener::DEVICE_LOCATION, &ids);
304 UpdateValue(this, &Manager::oem_name_, settings.oem_name,
305 NotificationListener::OEM_NAME, &ids);
306 UpdateValue(this, &Manager::model_id_, settings.model_id,
307 NotificationListener::MODEL_ID, &ids);
308 UpdateValue(this, &Manager::model_name_, settings.model_name,
309 NotificationListener::MODEL_NAME, &ids);
310 NotifyServiceManagerChange(ids);
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700311}
312
313void Manager::OnPairingStart(const std::string& session_id,
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700314 weave::PairingType pairing_type,
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700315 const std::vector<uint8_t>& code) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800316 // For now, just overwrite the exposed PairInfo with the most recent pairing
317 // attempt.
318 std::vector<int> ids;
319 UpdateValue(this, &Manager::pairing_session_id_, session_id,
320 NotificationListener::PAIRING_SESSION_ID, &ids);
321 UpdateValue(this, &Manager::pairing_mode_, EnumToString(pairing_type),
322 NotificationListener::PAIRING_MODE, &ids);
323 std::string pairing_code{code.begin(), code.end()};
324 UpdateValue(this, &Manager::pairing_code_, pairing_code,
325 NotificationListener::PAIRING_CODE, &ids);
326 NotifyServiceManagerChange(ids);
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700327}
328
329void Manager::OnPairingEnd(const std::string& session_id) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800330 if (pairing_session_id_ != session_id)
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700331 return;
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800332 std::vector<int> ids;
333 UpdateValue(this, &Manager::pairing_session_id_, "",
334 NotificationListener::PAIRING_SESSION_ID, &ids);
335 UpdateValue(this, &Manager::pairing_mode_, "",
336 NotificationListener::PAIRING_MODE, &ids);
337 UpdateValue(this, &Manager::pairing_code_, "",
338 NotificationListener::PAIRING_CODE, &ids);
339 NotifyServiceManagerChange(ids);
340}
341
342android::binder::Status Manager::connect(
343 const android::sp<android::weave::IWeaveClient>& client) {
344 pending_clients_.push_back(client);
345 if (device_)
346 CreateServicesForClients();
347 return android::binder::Status::ok();
348}
349
350android::binder::Status Manager::registerNotificationListener(
351 const WeaveServiceManagerNotificationListener& listener) {
352 notification_listeners_.insert(listener);
353 android::BinderWrapper::Get()->RegisterForDeathNotifications(
354 android::IInterface::asBinder(listener),
355 base::Bind(&Manager::OnNotificationListenerDestroyed,
356 weak_ptr_factory_.GetWeakPtr(), listener));
357 return android::binder::Status::ok();
358}
359
360android::binder::Status Manager::getCloudId(android::String16* id) {
361 *id = weaved::binder_utils::ToString16(cloud_id_);
362 return android::binder::Status::ok();
363}
364
365android::binder::Status Manager::getDeviceId(android::String16* id) {
366 *id = weaved::binder_utils::ToString16(device_id_);
367 return android::binder::Status::ok();
368}
369
370android::binder::Status Manager::getDeviceName(android::String16* name) {
371 *name = weaved::binder_utils::ToString16(device_name_);
372 return android::binder::Status::ok();
373}
374
375android::binder::Status Manager::getDeviceDescription(
376 android::String16* description) {
377 *description = weaved::binder_utils::ToString16(device_description_);
378 return android::binder::Status::ok();
379}
380
381android::binder::Status Manager::getDeviceLocation(
382 android::String16* location) {
383 *location = weaved::binder_utils::ToString16(device_location_);
384 return android::binder::Status::ok();
385}
386
387android::binder::Status Manager::getOemName(android::String16* name) {
388 *name = weaved::binder_utils::ToString16(oem_name_);
389 return android::binder::Status::ok();
390}
391
392android::binder::Status Manager::getModelName(android::String16* name) {
393 *name = weaved::binder_utils::ToString16(model_name_);
394 return android::binder::Status::ok();
395}
396
397android::binder::Status Manager::getModelId(android::String16* id) {
398 *id = weaved::binder_utils::ToString16(model_id_);
399 return android::binder::Status::ok();
400}
401
402android::binder::Status Manager::getPairingSessionId(android::String16* id) {
403 *id = weaved::binder_utils::ToString16(pairing_session_id_);
404 return android::binder::Status::ok();
405}
406
407android::binder::Status Manager::getPairingMode(android::String16* mode) {
408 *mode = weaved::binder_utils::ToString16(pairing_mode_);
409 return android::binder::Status::ok();
410}
411
412android::binder::Status Manager::getPairingCode(android::String16* code) {
413 *code = weaved::binder_utils::ToString16(pairing_code_);
414 return android::binder::Status::ok();
415}
416
417android::binder::Status Manager::getState(android::String16* state) {
418 *state = weaved::binder_utils::ToString16(state_);
419 return android::binder::Status::ok();
420}
421
422android::binder::Status Manager::getTraits(android::String16* traits) {
423 *traits = weaved::binder_utils::ToString16(device_->GetTraits());
424 return android::binder::Status::ok();
425}
426
427android::binder::Status Manager::getComponents(android::String16* components) {
428 *components = weaved::binder_utils::ToString16(device_->GetComponents());
429 return android::binder::Status::ok();
430}
431
432void Manager::CreateServicesForClients() {
433 CHECK(device_);
434 // For safety, iterate over a copy of |pending_clients_| and clear the
435 // original vector before performing the iterations.
436 std::vector<android::sp<android::weave::IWeaveClient>> pending_clients_copy;
437 std::swap(pending_clients_copy, pending_clients_);
438 for (const auto& client : pending_clients_copy) {
439 android::sp<BinderWeaveService> service =
440 new BinderWeaveService{device_.get(), client};
441 services_.emplace(client, service);
442 client->onServiceConnected(service);
443 android::BinderWrapper::Get()->RegisterForDeathNotifications(
444 android::IInterface::asBinder(client),
445 base::Bind(&Manager::OnClientDisconnected,
446 weak_ptr_factory_.GetWeakPtr(),
447 client));
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700448 }
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800449}
450
451void Manager::OnClientDisconnected(
452 const android::sp<android::weave::IWeaveClient>& client) {
453 services_.erase(client);
454}
455
456void Manager::OnNotificationListenerDestroyed(
457 const WeaveServiceManagerNotificationListener& notification_listener) {
458 notification_listeners_.erase(notification_listener);
459}
460
461void Manager::NotifyServiceManagerChange(
462 const std::vector<int>& notification_ids) {
463 if (notification_ids.empty())
464 return;
465 for (const auto& listener : notification_listeners_)
466 listener->notifyServiceManagerChange(notification_ids);
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700467}
468
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700469} // namespace buffet