Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1285)

Side by Side Diff: dbus/bus.cc

Issue 15741025: Linux/CrOS: Retry connecting to mtpd. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: address nits Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « dbus/bus.h ('k') | dbus/bus_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "dbus/bus.h" 5 #include "dbus/bus.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/stringprintf.h"
12 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
13 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
14 #include "base/time.h" 15 #include "base/time.h"
15 #include "dbus/exported_object.h" 16 #include "dbus/exported_object.h"
17 #include "dbus/message.h"
16 #include "dbus/object_manager.h" 18 #include "dbus/object_manager.h"
17 #include "dbus/object_path.h" 19 #include "dbus/object_path.h"
18 #include "dbus/object_proxy.h" 20 #include "dbus/object_proxy.h"
19 #include "dbus/scoped_dbus_error.h" 21 #include "dbus/scoped_dbus_error.h"
20 22
21 namespace dbus { 23 namespace dbus {
22 24
23 namespace { 25 namespace {
24 26
25 const char kDisconnectedSignal[] = "Disconnected"; 27 const char kDisconnectedSignal[] = "Disconnected";
26 const char kDisconnectedMatchRule[] = 28 const char kDisconnectedMatchRule[] =
27 "type='signal', path='/org/freedesktop/DBus/Local'," 29 "type='signal', path='/org/freedesktop/DBus/Local',"
28 "interface='org.freedesktop.DBus.Local', member='Disconnected'"; 30 "interface='org.freedesktop.DBus.Local', member='Disconnected'";
29 31
32 // The NameOwnerChanged member in org.freedesktop.DBus
33 const char kNameOwnerChangedSignal[] = "NameOwnerChanged";
34
35 // The match rule used to filter for changes to a given service name owner.
36 const char kServiceNameOwnerChangeMatchRule[] =
37 "type='signal',interface='org.freedesktop.DBus',"
38 "member='NameOwnerChanged',path='/org/freedesktop/DBus',"
39 "sender='org.freedesktop.DBus',arg0='%s'";
40
30 // The class is used for watching the file descriptor used for D-Bus 41 // The class is used for watching the file descriptor used for D-Bus
31 // communication. 42 // communication.
32 class Watch : public base::MessagePumpLibevent::Watcher { 43 class Watch : public base::MessagePumpLibevent::Watcher {
33 public: 44 public:
34 explicit Watch(DBusWatch* watch) 45 explicit Watch(DBusWatch* watch)
35 : raw_watch_(watch) { 46 : raw_watch_(watch) {
36 dbus_watch_set_data(raw_watch_, this, NULL); 47 dbus_watch_set_data(raw_watch_, this, NULL);
37 } 48 }
38 49
39 virtual ~Watch() { 50 virtual ~Watch() {
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 void Bus::GetServiceOwnerInternal(const std::string& service_name, 912 void Bus::GetServiceOwnerInternal(const std::string& service_name,
902 const GetServiceOwnerCallback& callback) { 913 const GetServiceOwnerCallback& callback) {
903 AssertOnDBusThread(); 914 AssertOnDBusThread();
904 915
905 std::string service_owner; 916 std::string service_owner;
906 if (Connect()) 917 if (Connect())
907 service_owner = GetServiceOwnerAndBlock(service_name, SUPPRESS_ERRORS); 918 service_owner = GetServiceOwnerAndBlock(service_name, SUPPRESS_ERRORS);
908 PostTaskToOriginThread(FROM_HERE, base::Bind(callback, service_owner)); 919 PostTaskToOriginThread(FROM_HERE, base::Bind(callback, service_owner));
909 } 920 }
910 921
922 void Bus::ListenForServiceOwnerChange(
923 const std::string& service_name,
924 const GetServiceOwnerCallback& callback) {
925 AssertOnOriginThread();
926 DCHECK(!service_name.empty());
927 DCHECK(!callback.is_null());
928
929 PostTaskToDBusThread(FROM_HERE,
930 base::Bind(&Bus::ListenForServiceOwnerChangeInternal,
931 this, service_name, callback));
932 }
933
934 void Bus::ListenForServiceOwnerChangeInternal(
935 const std::string& service_name,
936 const GetServiceOwnerCallback& callback) {
937 AssertOnDBusThread();
938 DCHECK(!service_name.empty());
939 DCHECK(!callback.is_null());
940
941 if (!Connect() || !SetUpAsyncOperations())
942 return;
943
944 if (service_owner_changed_listener_map_.empty()) {
945 bool filter_added =
946 AddFilterFunction(Bus::OnServiceOwnerChangedFilter, this);
947 DCHECK(filter_added);
948 }
949
950 ServiceOwnerChangedListenerMap::iterator it =
951 service_owner_changed_listener_map_.find(service_name);
952 if (it == service_owner_changed_listener_map_.end()) {
953 // Add a match rule for the new service name.
954 const std::string name_owner_changed_match_rule =
955 base::StringPrintf(kServiceNameOwnerChangeMatchRule,
956 service_name.c_str());
957 ScopedDBusError error;
958 AddMatch(name_owner_changed_match_rule, error.get());
959 if (error.is_set()) {
960 LOG(ERROR) << "Failed to add match rule for " << service_name
961 << ". Got " << error.name() << ": " << error.message();
962 return;
963 }
964
965 service_owner_changed_listener_map_[service_name].push_back(callback);
966 return;
967 }
968
969 // Check if the callback has already been added.
970 std::vector<GetServiceOwnerCallback>& callbacks = it->second;
971 for (size_t i = 0; i < callbacks.size(); ++i) {
972 if (callbacks[i].Equals(callback))
973 return;
974 }
975 callbacks.push_back(callback);
976 }
977
978 void Bus::UnlistenForServiceOwnerChange(
979 const std::string& service_name,
980 const GetServiceOwnerCallback& callback) {
981 AssertOnOriginThread();
982 DCHECK(!service_name.empty());
983 DCHECK(!callback.is_null());
984
985 PostTaskToDBusThread(FROM_HERE,
986 base::Bind(&Bus::UnlistenForServiceOwnerChangeInternal,
987 this, service_name, callback));
988 }
989
990 void Bus::UnlistenForServiceOwnerChangeInternal(
991 const std::string& service_name,
992 const GetServiceOwnerCallback& callback) {
993 AssertOnDBusThread();
994 DCHECK(!service_name.empty());
995 DCHECK(!callback.is_null());
996
997 ServiceOwnerChangedListenerMap::iterator it =
998 service_owner_changed_listener_map_.find(service_name);
999 if (it == service_owner_changed_listener_map_.end())
1000 return;
1001
1002 std::vector<GetServiceOwnerCallback>& callbacks = it->second;
1003 for (size_t i = 0; i < callbacks.size(); ++i) {
1004 if (callbacks[i].Equals(callback)) {
1005 callbacks.erase(callbacks.begin() + i);
1006 break; // There can be only one.
1007 }
1008 }
1009 if (!callbacks.empty())
1010 return;
1011
1012 // Last callback for |service_name| has been removed, remove match rule.
1013 const std::string name_owner_changed_match_rule =
1014 base::StringPrintf(kServiceNameOwnerChangeMatchRule,
1015 service_name.c_str());
1016 ScopedDBusError error;
1017 RemoveMatch(name_owner_changed_match_rule, error.get());
1018 // And remove |service_owner_changed_listener_map_| entry.
1019 service_owner_changed_listener_map_.erase(it);
1020
1021 if (service_owner_changed_listener_map_.empty()) {
1022 bool filter_removed =
1023 RemoveFilterFunction(Bus::OnServiceOwnerChangedFilter, this);
1024 DCHECK(filter_removed);
1025 }
1026 }
1027
911 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) { 1028 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) {
912 AssertOnDBusThread(); 1029 AssertOnDBusThread();
913 1030
914 // watch will be deleted when raw_watch is removed in OnRemoveWatch(). 1031 // watch will be deleted when raw_watch is removed in OnRemoveWatch().
915 Watch* watch = new Watch(raw_watch); 1032 Watch* watch = new Watch(raw_watch);
916 if (watch->IsReadyToBeWatched()) { 1033 if (watch->IsReadyToBeWatched()) {
917 watch->StartWatching(); 1034 watch->StartWatching();
918 } 1035 }
919 ++num_pending_watches_; 1036 ++num_pending_watches_;
920 return true; 1037 return true;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 if (!on_disconnected_closure_.is_null()) 1110 if (!on_disconnected_closure_.is_null())
994 PostTaskToOriginThread(FROM_HERE, on_disconnected_closure_); 1111 PostTaskToOriginThread(FROM_HERE, on_disconnected_closure_);
995 1112
996 if (!connection) 1113 if (!connection)
997 return; 1114 return;
998 DCHECK(!dbus_connection_get_is_connected(connection)); 1115 DCHECK(!dbus_connection_get_is_connected(connection));
999 1116
1000 ShutdownAndBlock(); 1117 ShutdownAndBlock();
1001 } 1118 }
1002 1119
1120 void Bus::OnServiceOwnerChanged(DBusMessage* message) {
1121 DCHECK(message);
1122 AssertOnDBusThread();
1123
1124 // |message| will be unrefed on exit of the function. Increment the
1125 // reference so we can use it in Signal::FromRawMessage() below.
1126 dbus_message_ref(message);
1127 scoped_ptr<Signal> signal(Signal::FromRawMessage(message));
1128
1129 // Confirm the validity of the NameOwnerChanged signal.
1130 if (signal->GetMember() != kNameOwnerChangedSignal ||
1131 signal->GetInterface() != DBUS_INTERFACE_DBUS ||
1132 signal->GetSender() != DBUS_SERVICE_DBUS) {
1133 return;
1134 }
1135
1136 MessageReader reader(signal.get());
1137 std::string service_name;
1138 std::string old_owner;
1139 std::string new_owner;
1140 if (!reader.PopString(&service_name) ||
1141 !reader.PopString(&old_owner) ||
1142 !reader.PopString(&new_owner)) {
1143 return;
1144 }
1145
1146 ServiceOwnerChangedListenerMap::const_iterator it =
1147 service_owner_changed_listener_map_.find(service_name);
1148 if (it == service_owner_changed_listener_map_.end())
1149 return;
1150
1151 const std::vector<GetServiceOwnerCallback>& callbacks = it->second;
1152 for (size_t i = 0; i < callbacks.size(); ++i) {
1153 PostTaskToOriginThread(FROM_HERE,
1154 base::Bind(callbacks[i], new_owner));
1155 }
1156 }
1157
1158 // static
1003 dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) { 1159 dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) {
1004 Bus* self = static_cast<Bus*>(data); 1160 Bus* self = static_cast<Bus*>(data);
1005 return self->OnAddWatch(raw_watch); 1161 return self->OnAddWatch(raw_watch);
1006 } 1162 }
1007 1163
1164 // static
1008 void Bus::OnRemoveWatchThunk(DBusWatch* raw_watch, void* data) { 1165 void Bus::OnRemoveWatchThunk(DBusWatch* raw_watch, void* data) {
1009 Bus* self = static_cast<Bus*>(data); 1166 Bus* self = static_cast<Bus*>(data);
1010 self->OnRemoveWatch(raw_watch); 1167 self->OnRemoveWatch(raw_watch);
1011 } 1168 }
1012 1169
1170 // static
1013 void Bus::OnToggleWatchThunk(DBusWatch* raw_watch, void* data) { 1171 void Bus::OnToggleWatchThunk(DBusWatch* raw_watch, void* data) {
1014 Bus* self = static_cast<Bus*>(data); 1172 Bus* self = static_cast<Bus*>(data);
1015 self->OnToggleWatch(raw_watch); 1173 self->OnToggleWatch(raw_watch);
1016 } 1174 }
1017 1175
1176 // static
1018 dbus_bool_t Bus::OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 1177 dbus_bool_t Bus::OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1019 Bus* self = static_cast<Bus*>(data); 1178 Bus* self = static_cast<Bus*>(data);
1020 return self->OnAddTimeout(raw_timeout); 1179 return self->OnAddTimeout(raw_timeout);
1021 } 1180 }
1022 1181
1182 // static
1023 void Bus::OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 1183 void Bus::OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1024 Bus* self = static_cast<Bus*>(data); 1184 Bus* self = static_cast<Bus*>(data);
1025 self->OnRemoveTimeout(raw_timeout); 1185 self->OnRemoveTimeout(raw_timeout);
1026 } 1186 }
1027 1187
1188 // static
1028 void Bus::OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 1189 void Bus::OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1029 Bus* self = static_cast<Bus*>(data); 1190 Bus* self = static_cast<Bus*>(data);
1030 self->OnToggleTimeout(raw_timeout); 1191 self->OnToggleTimeout(raw_timeout);
1031 } 1192 }
1032 1193
1194 // static
1033 void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection, 1195 void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection,
1034 DBusDispatchStatus status, 1196 DBusDispatchStatus status,
1035 void* data) { 1197 void* data) {
1036 Bus* self = static_cast<Bus*>(data); 1198 Bus* self = static_cast<Bus*>(data);
1037 self->OnDispatchStatusChanged(connection, status); 1199 self->OnDispatchStatusChanged(connection, status);
1038 } 1200 }
1039 1201
1202 // static
1040 DBusHandlerResult Bus::OnConnectionDisconnectedFilter( 1203 DBusHandlerResult Bus::OnConnectionDisconnectedFilter(
1041 DBusConnection* connection, 1204 DBusConnection* connection,
1042 DBusMessage* message, 1205 DBusMessage* message,
1043 void* data) { 1206 void* data) {
1044 if (dbus_message_is_signal(message, 1207 if (dbus_message_is_signal(message,
1045 DBUS_INTERFACE_LOCAL, 1208 DBUS_INTERFACE_LOCAL,
1046 kDisconnectedSignal)) { 1209 kDisconnectedSignal)) {
1047 Bus* self = static_cast<Bus*>(data); 1210 Bus* self = static_cast<Bus*>(data);
1048 self->AssertOnDBusThread();
1049 self->OnConnectionDisconnected(connection); 1211 self->OnConnectionDisconnected(connection);
1050 return DBUS_HANDLER_RESULT_HANDLED; 1212 return DBUS_HANDLER_RESULT_HANDLED;
1051 } 1213 }
1052 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 1214 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1053 } 1215 }
1054 1216
1217 // static
1218 DBusHandlerResult Bus::OnServiceOwnerChangedFilter(
1219 DBusConnection* connection,
1220 DBusMessage* message,
1221 void* data) {
1222 if (dbus_message_is_signal(message,
1223 DBUS_INTERFACE_DBUS,
1224 kNameOwnerChangedSignal)) {
1225 Bus* self = static_cast<Bus*>(data);
1226 self->OnServiceOwnerChanged(message);
1227 }
1228 // Always return unhandled to let others, e.g. ObjectProxies, handle the same
1229 // signal.
1230 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1231 }
1232
1055 } // namespace dbus 1233 } // namespace dbus
OLDNEW
« no previous file with comments | « dbus/bus.h ('k') | dbus/bus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698