blob: 1323850e2948b69fb0617c3d7cf0e5130e6d6210 [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";
Alex Vakulenko0371fea2016-01-07 14:46:25 -080063const char kBaseComponent[] = "base";
64const char kRebootCommand[] = "base.reboot";
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070065
66bool LoadFile(const base::FilePath& file_path,
67 std::string* data,
Alex Vakulenko41705852015-10-13 10:12:06 -070068 brillo::ErrorPtr* error) {
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070069 if (!base::ReadFileToString(file_path, data)) {
Alex Vakulenko41705852015-10-13 10:12:06 -070070 brillo::errors::system::AddSystemError(error, FROM_HERE, errno);
71 brillo::Error::AddToPrintf(error, FROM_HERE, kErrorDomain, kFileReadError,
72 "Failed to read file '%s'",
73 file_path.value().c_str());
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070074 return false;
75 }
76 return true;
77}
78
Alex Vakulenko3bd3ece2015-12-09 12:29:01 -080079void LoadTraitDefinitions(const BuffetConfig::Options& options,
80 weave::Device* device) {
81 // Load component-specific device trait definitions.
82 base::FilePath dir{options.definitions.Append("traits")};
83 LOG(INFO) << "Looking for trait definitions in " << dir.value();
84 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
85 FILE_PATH_LITERAL("*.json"));
86 std::vector<std::string> result;
87 for (base::FilePath path = enumerator.Next(); !path.empty();
88 path = enumerator.Next()) {
89 LOG(INFO) << "Loading trait definition from " << path.value();
90 std::string json;
91 CHECK(LoadFile(path, &json, nullptr));
92 device->AddTraitDefinitionsFromJson(json);
93 }
94}
95
Alex Vakulenko2915a7b2015-10-07 17:04:00 -070096void LoadCommandDefinitions(const BuffetConfig::Options& options,
97 weave::Device* device) {
98 auto load_packages = [device](const base::FilePath& root,
99 const base::FilePath::StringType& pattern) {
100 base::FilePath dir{root.Append("commands")};
101 LOG(INFO) << "Looking for command schemas in " << dir.value();
102 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
103 pattern);
104 for (base::FilePath path = enumerator.Next(); !path.empty();
105 path = enumerator.Next()) {
106 LOG(INFO) << "Loading command schema from " << path.value();
107 std::string json;
108 CHECK(LoadFile(path, &json, nullptr));
109 device->AddCommandDefinitionsFromJson(json);
110 }
111 };
112 load_packages(options.definitions, FILE_PATH_LITERAL("*.json"));
Alex Vakulenko3bd3ece2015-12-09 12:29:01 -0800113 if (!options.test_definitions.empty())
114 load_packages(options.test_definitions, FILE_PATH_LITERAL("*test.json"));
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700115}
116
117void LoadStateDefinitions(const BuffetConfig::Options& options,
118 weave::Device* device) {
119 // Load component-specific device state definitions.
120 base::FilePath dir{options.definitions.Append("states")};
121 LOG(INFO) << "Looking for state definitions in " << dir.value();
122 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
123 FILE_PATH_LITERAL("*.schema.json"));
124 std::vector<std::string> result;
125 for (base::FilePath path = enumerator.Next(); !path.empty();
126 path = enumerator.Next()) {
127 LOG(INFO) << "Loading state definition from " << path.value();
128 std::string json;
129 CHECK(LoadFile(path, &json, nullptr));
130 device->AddStateDefinitionsFromJson(json);
131 }
132}
133
134void LoadStateDefaults(const BuffetConfig::Options& options,
135 weave::Device* device) {
136 // Load component-specific device state defaults.
137 base::FilePath dir{options.definitions.Append("states")};
138 LOG(INFO) << "Looking for state defaults in " << dir.value();
139 base::FileEnumerator enumerator(dir, false, base::FileEnumerator::FILES,
140 FILE_PATH_LITERAL("*.defaults.json"));
141 std::vector<std::string> result;
142 for (base::FilePath path = enumerator.Next(); !path.empty();
143 path = enumerator.Next()) {
144 LOG(INFO) << "Loading state defaults from " << path.value();
145 std::string json;
146 CHECK(LoadFile(path, &json, nullptr));
147 CHECK(device->SetStatePropertiesFromJson(json, nullptr));
148 }
149}
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700150
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800151// Updates the manager's state property if the new value is different from
152// the current value. In this case also adds the appropriate notification ID
153// to the array to record the state change for clients.
154void UpdateValue(Manager* manager,
155 std::string Manager::* prop,
156 const std::string& new_value,
157 int notification,
158 std::vector<int>* notification_ids) {
159 if (manager->*prop != new_value) {
160 manager->*prop = new_value;
161 notification_ids->push_back(notification);
162 }
163}
164
Alex Vakulenkoecf961a2014-10-28 13:50:16 -0700165} // anonymous namespace
166
Alex Vakulenkoe32375b2015-09-28 08:55:40 -0700167class Manager::TaskRunner : public weave::provider::TaskRunner {
Vitaly Bukae74c8722015-08-13 00:33:00 -0700168 public:
169 void PostDelayedTask(const tracked_objects::Location& from_here,
170 const base::Closure& task,
171 base::TimeDelta delay) override {
Alex Vakulenko41705852015-10-13 10:12:06 -0700172 brillo::MessageLoop::current()->PostDelayedTask(from_here, task, delay);
Vitaly Bukae74c8722015-08-13 00:33:00 -0700173 }
174};
175
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700176Manager::Manager(const Options& options,
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800177 const scoped_refptr<dbus::Bus>& bus)
178 : options_{options}, bus_{bus} {}
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700179
Vitaly Buka91cc7152015-03-20 09:46:57 -0700180Manager::~Manager() {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800181 android::BinderWrapper* binder_wrapper = android::BinderWrapper::Get();
182 for (const auto& listener : notification_listeners_) {
183 binder_wrapper->UnregisterForDeathNotifications(
184 android::IInterface::asBinder(listener));
185 }
186 for (const auto& pair : services_) {
187 binder_wrapper->UnregisterForDeathNotifications(
188 android::IInterface::asBinder(pair.first));
189 }
Vitaly Buka91cc7152015-03-20 09:46:57 -0700190}
Alex Vakulenkoecf961a2014-10-28 13:50:16 -0700191
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700192void Manager::Start(AsyncEventSequencer* sequencer) {
Alex Vakulenko0371fea2016-01-07 14:46:25 -0800193 power_manager_client_.Init();
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700194 RestartWeave(sequencer);
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700195}
196
197void Manager::RestartWeave(AsyncEventSequencer* sequencer) {
198 Stop();
199
Vitaly Bukae74c8722015-08-13 00:33:00 -0700200 task_runner_.reset(new TaskRunner{});
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700201 config_.reset(new BuffetConfig{options_.config_options});
Vitaly Buka00882b72015-08-06 00:32:11 -0700202 http_client_.reset(new HttpTransportClient);
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800203 shill_client_.reset(new ShillClient{bus_,
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700204 options_.device_whitelist,
205 !options_.xmpp_enabled});
Alex Vakulenko0022b752015-10-02 11:09:59 -0700206 weave::provider::HttpServer* http_server{nullptr};
Christopher Wileye925bb32015-08-03 20:09:18 -0700207#ifdef BUFFET_USE_WIFI_BOOTSTRAPPING
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700208 if (!options_.disable_privet) {
Casey Dahlin494b7242015-12-14 11:42:47 -0800209 mdns_client_ = MdnsClient::CreateInstance();
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700210 web_serv_client_.reset(new WebServClient{
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800211 bus_, sequencer,
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700212 base::Bind(&Manager::CreateDevice, weak_ptr_factory_.GetWeakPtr())});
Robert Gindaf86123d2015-09-11 16:10:43 -0700213 bluetooth_client_ = BluetoothClient::CreateInstance();
Alex Vakulenko0022b752015-10-02 11:09:59 -0700214 http_server = web_serv_client_.get();
215
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700216 if (options_.enable_ping) {
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700217 auto ping_handler = base::Bind(
218 [](std::unique_ptr<weave::provider::HttpServer::Request> request) {
Alex Vakulenko41705852015-10-13 10:12:06 -0700219 request->SendReply(brillo::http::status_code::Ok, "Hello, world!",
220 brillo::mime::text::kPlain);
Alex Vakulenko297114c2015-10-12 13:45:43 -0700221 });
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700222 http_server->AddHttpRequestHandler("/privet/ping", ping_handler);
223 http_server->AddHttpsRequestHandler("/privet/ping", ping_handler);
Alex Vakulenko0022b752015-10-02 11:09:59 -0700224 }
Alex Vakulenkof0f55342015-08-18 15:51:40 -0700225 }
Christopher Wileye925bb32015-08-03 20:09:18 -0700226#endif // BUFFET_USE_WIFI_BOOTSTRAPPING
Vitaly Buka7042c582015-07-30 17:02:14 -0700227
Alex Vakulenkobe39e932015-10-09 08:10:36 -0700228 if (!http_server)
229 CreateDevice();
230}
231
232void Manager::CreateDevice() {
233 if (device_)
234 return;
235
Alex Vakulenko0022b752015-10-02 11:09:59 -0700236 device_ = weave::Device::Create(config_.get(), task_runner_.get(),
237 http_client_.get(), shill_client_.get(),
238 mdns_client_.get(), web_serv_client_.get(),
239 shill_client_.get(), bluetooth_client_.get());
Vitaly Buka1175a9b2015-08-15 10:42:17 -0700240
Alex Vakulenko3bd3ece2015-12-09 12:29:01 -0800241 LoadTraitDefinitions(options_.config_options, device_.get());
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700242 LoadCommandDefinitions(options_.config_options, device_.get());
243 LoadStateDefinitions(options_.config_options, device_.get());
244 LoadStateDefaults(options_.config_options, device_.get());
245
Alex Vakulenko0022b752015-10-02 11:09:59 -0700246 device_->AddSettingsChangedCallback(
247 base::Bind(&Manager::OnConfigChanged, weak_ptr_factory_.GetWeakPtr()));
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700248
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800249 device_->AddTraitDefsChangedCallback(
250 base::Bind(&Manager::OnTraitDefsChanged,
251 weak_ptr_factory_.GetWeakPtr()));
Alex Vakulenko0022b752015-10-02 11:09:59 -0700252 device_->AddStateChangedCallback(
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800253 base::Bind(&Manager::OnComponentTreeChanged,
254 weak_ptr_factory_.GetWeakPtr()));
255 device_->AddComponentTreeChangedCallback(
256 base::Bind(&Manager::OnComponentTreeChanged,
257 weak_ptr_factory_.GetWeakPtr()));
Vitaly Bukabf4ba652015-05-14 16:57:23 -0700258
Alex Vakulenko0022b752015-10-02 11:09:59 -0700259 device_->AddGcdStateChangedCallback(
260 base::Bind(&Manager::OnGcdStateChanged, weak_ptr_factory_.GetWeakPtr()));
Vitaly Bukae74fe3c2015-05-13 13:48:59 -0700261
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700262 device_->AddPairingChangedCallbacks(
263 base::Bind(&Manager::OnPairingStart, weak_ptr_factory_.GetWeakPtr()),
264 base::Bind(&Manager::OnPairingEnd, weak_ptr_factory_.GetWeakPtr()));
Alex Vakulenkoc662a242015-10-15 13:04:06 -0700265
Alex Vakulenko0371fea2016-01-07 14:46:25 -0800266 device_->AddCommandHandler(kBaseComponent, kRebootCommand,
267 base::Bind(&Manager::OnRebootDevice,
268 weak_ptr_factory_.GetWeakPtr()));
269
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800270 CreateServicesForClients();
Vitaly Buka84fd6dd2015-06-09 17:22:18 -0700271}
272
273void Manager::Stop() {
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700274 device_.reset();
Alex Vakulenko2915a7b2015-10-07 17:04:00 -0700275#ifdef BUFFET_USE_WIFI_BOOTSTRAPPING
276 web_serv_client_.reset();
277 mdns_client_.reset();
278#endif // BUFFET_USE_WIFI_BOOTSTRAPPING
279 shill_client_.reset();
280 http_client_.reset();
281 config_.reset();
282 task_runner_.reset();
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700283}
284
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800285void Manager::OnTraitDefsChanged() {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800286 NotifyServiceManagerChange({NotificationListener::TRAITS});
Alex Vakulenko14b3e6e2015-12-10 10:01:36 -0800287}
288
289void Manager::OnComponentTreeChanged() {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800290 NotifyServiceManagerChange({NotificationListener::COMPONENTS});
Vitaly Buka2b30e7a2015-05-27 09:27:08 -0700291}
292
Alex Vakulenko0022b752015-10-02 11:09:59 -0700293void Manager::OnGcdStateChanged(weave::GcdState state) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800294 state_ = weave::EnumToString(state);
295 NotifyServiceManagerChange({NotificationListener::STATE});
296 property_set(weaved::system_properties::kState, state_.c_str());
Vitaly Bukabf4ba652015-05-14 16:57:23 -0700297}
298
Vitaly Buka00b83492015-07-20 00:37:48 -0700299void Manager::OnConfigChanged(const weave::Settings& settings) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800300 std::vector<int> ids;
301 UpdateValue(this, &Manager::cloud_id_, settings.cloud_id,
302 NotificationListener::CLOUD_ID, &ids);
303 UpdateValue(this, &Manager::device_id_, settings.device_id,
304 NotificationListener::DEVICE_ID, &ids);
305 UpdateValue(this, &Manager::device_name_, settings.name,
306 NotificationListener::DEVICE_NAME, &ids);
307 UpdateValue(this, &Manager::device_description_, settings.description,
308 NotificationListener::DEVICE_DESCRIPTION, &ids);
309 UpdateValue(this, &Manager::device_location_, settings.location,
310 NotificationListener::DEVICE_LOCATION, &ids);
311 UpdateValue(this, &Manager::oem_name_, settings.oem_name,
312 NotificationListener::OEM_NAME, &ids);
313 UpdateValue(this, &Manager::model_id_, settings.model_id,
314 NotificationListener::MODEL_ID, &ids);
315 UpdateValue(this, &Manager::model_name_, settings.model_name,
316 NotificationListener::MODEL_NAME, &ids);
317 NotifyServiceManagerChange(ids);
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700318}
319
320void Manager::OnPairingStart(const std::string& session_id,
Vitaly Buka0c6dcd22015-07-10 00:12:25 -0700321 weave::PairingType pairing_type,
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700322 const std::vector<uint8_t>& code) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800323 // For now, just overwrite the exposed PairInfo with the most recent pairing
324 // attempt.
325 std::vector<int> ids;
326 UpdateValue(this, &Manager::pairing_session_id_, session_id,
327 NotificationListener::PAIRING_SESSION_ID, &ids);
328 UpdateValue(this, &Manager::pairing_mode_, EnumToString(pairing_type),
329 NotificationListener::PAIRING_MODE, &ids);
330 std::string pairing_code{code.begin(), code.end()};
331 UpdateValue(this, &Manager::pairing_code_, pairing_code,
332 NotificationListener::PAIRING_CODE, &ids);
333 NotifyServiceManagerChange(ids);
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700334}
335
336void Manager::OnPairingEnd(const std::string& session_id) {
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800337 if (pairing_session_id_ != session_id)
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700338 return;
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800339 std::vector<int> ids;
340 UpdateValue(this, &Manager::pairing_session_id_, "",
341 NotificationListener::PAIRING_SESSION_ID, &ids);
342 UpdateValue(this, &Manager::pairing_mode_, "",
343 NotificationListener::PAIRING_MODE, &ids);
344 UpdateValue(this, &Manager::pairing_code_, "",
345 NotificationListener::PAIRING_CODE, &ids);
346 NotifyServiceManagerChange(ids);
347}
348
Alex Vakulenko0371fea2016-01-07 14:46:25 -0800349void Manager::OnRebootDevice(const std::weak_ptr<weave::Command>& cmd) {
350 auto command = cmd.lock();
351 if (!command || !command->Complete({}, nullptr))
352 return;
353
354 task_runner_->PostDelayedTask(
355 FROM_HERE,
356 base::Bind(&Manager::RebootDeviceNow, weak_ptr_factory_.GetWeakPtr()),
357 base::TimeDelta::FromSeconds(2));
358}
359
360void Manager::RebootDeviceNow() {
361 power_manager_client_.Reboot(android::RebootReason::DEFAULT);
362}
363
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800364android::binder::Status Manager::connect(
365 const android::sp<android::weave::IWeaveClient>& client) {
366 pending_clients_.push_back(client);
367 if (device_)
368 CreateServicesForClients();
369 return android::binder::Status::ok();
370}
371
372android::binder::Status Manager::registerNotificationListener(
373 const WeaveServiceManagerNotificationListener& listener) {
374 notification_listeners_.insert(listener);
375 android::BinderWrapper::Get()->RegisterForDeathNotifications(
376 android::IInterface::asBinder(listener),
377 base::Bind(&Manager::OnNotificationListenerDestroyed,
378 weak_ptr_factory_.GetWeakPtr(), listener));
379 return android::binder::Status::ok();
380}
381
382android::binder::Status Manager::getCloudId(android::String16* id) {
383 *id = weaved::binder_utils::ToString16(cloud_id_);
384 return android::binder::Status::ok();
385}
386
387android::binder::Status Manager::getDeviceId(android::String16* id) {
388 *id = weaved::binder_utils::ToString16(device_id_);
389 return android::binder::Status::ok();
390}
391
392android::binder::Status Manager::getDeviceName(android::String16* name) {
393 *name = weaved::binder_utils::ToString16(device_name_);
394 return android::binder::Status::ok();
395}
396
397android::binder::Status Manager::getDeviceDescription(
398 android::String16* description) {
399 *description = weaved::binder_utils::ToString16(device_description_);
400 return android::binder::Status::ok();
401}
402
403android::binder::Status Manager::getDeviceLocation(
404 android::String16* location) {
405 *location = weaved::binder_utils::ToString16(device_location_);
406 return android::binder::Status::ok();
407}
408
409android::binder::Status Manager::getOemName(android::String16* name) {
410 *name = weaved::binder_utils::ToString16(oem_name_);
411 return android::binder::Status::ok();
412}
413
414android::binder::Status Manager::getModelName(android::String16* name) {
415 *name = weaved::binder_utils::ToString16(model_name_);
416 return android::binder::Status::ok();
417}
418
419android::binder::Status Manager::getModelId(android::String16* id) {
420 *id = weaved::binder_utils::ToString16(model_id_);
421 return android::binder::Status::ok();
422}
423
424android::binder::Status Manager::getPairingSessionId(android::String16* id) {
425 *id = weaved::binder_utils::ToString16(pairing_session_id_);
426 return android::binder::Status::ok();
427}
428
429android::binder::Status Manager::getPairingMode(android::String16* mode) {
430 *mode = weaved::binder_utils::ToString16(pairing_mode_);
431 return android::binder::Status::ok();
432}
433
434android::binder::Status Manager::getPairingCode(android::String16* code) {
435 *code = weaved::binder_utils::ToString16(pairing_code_);
436 return android::binder::Status::ok();
437}
438
439android::binder::Status Manager::getState(android::String16* state) {
440 *state = weaved::binder_utils::ToString16(state_);
441 return android::binder::Status::ok();
442}
443
444android::binder::Status Manager::getTraits(android::String16* traits) {
445 *traits = weaved::binder_utils::ToString16(device_->GetTraits());
446 return android::binder::Status::ok();
447}
448
449android::binder::Status Manager::getComponents(android::String16* components) {
450 *components = weaved::binder_utils::ToString16(device_->GetComponents());
451 return android::binder::Status::ok();
452}
453
454void Manager::CreateServicesForClients() {
455 CHECK(device_);
456 // For safety, iterate over a copy of |pending_clients_| and clear the
457 // original vector before performing the iterations.
458 std::vector<android::sp<android::weave::IWeaveClient>> pending_clients_copy;
459 std::swap(pending_clients_copy, pending_clients_);
460 for (const auto& client : pending_clients_copy) {
461 android::sp<BinderWeaveService> service =
462 new BinderWeaveService{device_.get(), client};
463 services_.emplace(client, service);
464 client->onServiceConnected(service);
465 android::BinderWrapper::Get()->RegisterForDeathNotifications(
466 android::IInterface::asBinder(client),
467 base::Bind(&Manager::OnClientDisconnected,
468 weak_ptr_factory_.GetWeakPtr(),
469 client));
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700470 }
Alex Vakulenkoae29f7d2015-12-21 16:30:37 -0800471}
472
473void Manager::OnClientDisconnected(
474 const android::sp<android::weave::IWeaveClient>& client) {
475 services_.erase(client);
476}
477
478void Manager::OnNotificationListenerDestroyed(
479 const WeaveServiceManagerNotificationListener& notification_listener) {
480 notification_listeners_.erase(notification_listener);
481}
482
483void Manager::NotifyServiceManagerChange(
484 const std::vector<int>& notification_ids) {
485 if (notification_ids.empty())
486 return;
487 for (const auto& listener : notification_listeners_)
488 listener->notifyServiceManagerChange(notification_ids);
Vitaly Buka7b3ba792015-06-09 17:01:54 -0700489}
490
Christopher Wiley4b5f04c2014-03-27 14:45:37 -0700491} // namespace buffet