1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4#include "chromeos/dbus/sms_client.h"
5
6#include <map>
7#include <utility>
8
9#include "base/bind.h"
10#include "base/location.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "base/message_loop/message_loop.h"
14#include "base/stl_util.h"
15#include "base/strings/stringprintf.h"
16#include "base/values.h"
17#include "dbus/bus.h"
18#include "dbus/message.h"
19#include "dbus/object_proxy.h"
20#include "dbus/values_util.h"
21#include "third_party/cros_system_api/dbus/service_constants.h"
22
23namespace chromeos {
24
25namespace {
26
27// SMSClient is used to communicate with the
28// org.freedesktop.ModemManager1.SMS service.  All methods should be
29// called from the origin thread (UI thread) which initializes the
30// DBusThreadManager instance.
31class SMSClientImpl : public SMSClient {
32 public:
33  SMSClientImpl() : bus_(NULL), weak_ptr_factory_(this) {}
34
35  virtual ~SMSClientImpl() {}
36
37  // Calls GetAll method.  |callback| is called after the method call succeeds.
38  virtual void GetAll(const std::string& service_name,
39                      const dbus::ObjectPath& object_path,
40                      const GetAllCallback& callback) OVERRIDE {
41    dbus::ObjectProxy *proxy = bus_->GetObjectProxy(service_name, object_path);
42    dbus::MethodCall method_call(dbus::kDBusPropertiesInterface,
43                                 dbus::kDBusPropertiesGetAll);
44    dbus::MessageWriter writer(&method_call);
45    writer.AppendString(modemmanager::kModemManager1SmsInterface);
46    proxy->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
47                       base::Bind(&SMSClientImpl::OnGetAll,
48                                  weak_ptr_factory_.GetWeakPtr(),
49                                  callback));
50  }
51
52 protected:
53  virtual void Init(dbus::Bus* bus) OVERRIDE {
54    bus_ = bus;
55  }
56
57 private:
58  // Handles responses of GetAll method calls.
59  void OnGetAll(const GetAllCallback& callback, dbus::Response* response) {
60    if (!response) {
61      // Must invoke the callback, even if there is no message.
62      base::DictionaryValue empty_dictionary;
63      callback.Run(empty_dictionary);
64      return;
65    }
66    dbus::MessageReader reader(response);
67    scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
68    base::DictionaryValue* dictionary_value = NULL;
69    if (!value.get() || !value->GetAsDictionary(&dictionary_value)) {
70      LOG(WARNING) << "Invalid response: " << response->ToString();
71      base::DictionaryValue empty_dictionary;
72      callback.Run(empty_dictionary);
73      return;
74    }
75    callback.Run(*dictionary_value);
76  }
77
78  dbus::Bus* bus_;
79
80  // Note: This should remain the last member so it'll be destroyed and
81  // invalidate its weak pointers before any other members are destroyed.
82  base::WeakPtrFactory<SMSClientImpl> weak_ptr_factory_;
83
84  DISALLOW_COPY_AND_ASSIGN(SMSClientImpl);
85};
86
87}  // namespace
88
89////////////////////////////////////////////////////////////////////////////////
90// SMSClient
91
92SMSClient::SMSClient() {}
93
94SMSClient::~SMSClient() {}
95
96
97// static
98SMSClient* SMSClient::Create() {
99  return new SMSClientImpl();
100}
101
102}  // namespace chromeos
103