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

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: 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
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";
satorux1 2013/06/03 02:26:06 I think we have this in object_proxy.cc. While you
Lei Zhang 2013/06/04 00:35:53 I can do this in a later cleanup CL. I'm trying to
satorux1 2013/06/04 01:09:06 I see. That makes sense.
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
927 PostTaskToDBusThread(FROM_HERE,
928 base::Bind(&Bus::ListenForServiceOwnerChangeInternal,
929 this, service_name, callback));
930 }
931
932 void Bus::ListenForServiceOwnerChangeInternal(
933 const std::string& service_name,
934 const GetServiceOwnerCallback& callback) {
935 AssertOnDBusThread();
936
937 if (!Connect() || !SetUpAsyncOperations())
938 return;
939
940 if (service_owner_changed_listener_map_.size() == 0)
941 CHECK(AddFilterFunction(Bus::OnServiceOwnerChangedFilter, this));
satorux1 2013/06/03 02:26:06 CHECK -> DCHECK. CHECK is rarely used.
Lei Zhang 2013/06/04 00:35:53 Done.
942
943 ServiceOwnerChangedListenerMap::iterator it =
944 service_owner_changed_listener_map_.find(service_name);
945 if (it == service_owner_changed_listener_map_.end()) {
946 // Add a match rule for the new service name.
947 const std::string name_owner_changed_match_rule =
948 base::StringPrintf(kServiceNameOwnerChangeMatchRule,
949 service_name.c_str());
950 ScopedDBusError error;
951 AddMatch(name_owner_changed_match_rule, error.get());
952 if (error.is_set()) {
953 LOG(ERROR) << "Failed to add match rule for " << service_name
954 << ". Got " << error.name() << ": " << error.message();
955 return;
956 }
957
958 it = service_owner_changed_listener_map_.insert(
959 std::make_pair(service_name,
960 std::vector<GetServiceOwnerCallback>())).first;
961 }
962
963 // Check if the callback has already been added.
964 std::vector<GetServiceOwnerCallback>& callbacks = it->second;
965 for (size_t i = 0; i < callbacks.size(); ++i) {
966 if (callbacks[i].Equals(callback))
967 return;
968 }
969 callbacks.push_back(callback);
970 }
971
972 void Bus::UnlistenForServiceOwnerChange(
973 const std::string& service_name,
974 const GetServiceOwnerCallback& callback) {
975 AssertOnOriginThread();
976
977 PostTaskToDBusThread(FROM_HERE,
978 base::Bind(&Bus::UnlistenForServiceOwnerChangeInternal,
979 this, service_name, callback));
980 }
981
982 void Bus::UnlistenForServiceOwnerChangeInternal(
983 const std::string& service_name,
984 const GetServiceOwnerCallback& callback) {
985 AssertOnDBusThread();
986
987 ServiceOwnerChangedListenerMap::iterator it =
988 service_owner_changed_listener_map_.find(service_name);
989 if (it == service_owner_changed_listener_map_.end())
990 return;
991
992 std::vector<GetServiceOwnerCallback>& callbacks = it->second;
993 for (size_t i = 0; i < callbacks.size(); ++i) {
994 if (callbacks[i].Equals(callback)) {
995 callbacks.erase(callbacks.begin() + i);
996 break; // There can be only one.
997 }
998 }
999 if (callbacks.size() > 0)
1000 return;
1001
1002 // Last callback for |service_name| has been removed, remove match rule.
1003 const std::string name_owner_changed_match_rule =
1004 base::StringPrintf(kServiceNameOwnerChangeMatchRule,
1005 service_name.c_str());
1006 ScopedDBusError error;
1007 RemoveMatch(name_owner_changed_match_rule, error.get());
1008 // And remove |service_owner_changed_listener_map_| entry.
1009 service_owner_changed_listener_map_.erase(it);
1010
1011 if (service_owner_changed_listener_map_.size() == 0) {
1012 CHECK(RemoveFilterFunction(Bus::OnServiceOwnerChangedFilter, this));
1013 }
1014 }
1015
911 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) { 1016 dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) {
912 AssertOnDBusThread(); 1017 AssertOnDBusThread();
913 1018
914 // watch will be deleted when raw_watch is removed in OnRemoveWatch(). 1019 // watch will be deleted when raw_watch is removed in OnRemoveWatch().
915 Watch* watch = new Watch(raw_watch); 1020 Watch* watch = new Watch(raw_watch);
916 if (watch->IsReadyToBeWatched()) { 1021 if (watch->IsReadyToBeWatched()) {
917 watch->StartWatching(); 1022 watch->StartWatching();
918 } 1023 }
919 ++num_pending_watches_; 1024 ++num_pending_watches_;
920 return true; 1025 return true;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 if (!on_disconnected_closure_.is_null()) 1098 if (!on_disconnected_closure_.is_null())
994 PostTaskToOriginThread(FROM_HERE, on_disconnected_closure_); 1099 PostTaskToOriginThread(FROM_HERE, on_disconnected_closure_);
995 1100
996 if (!connection) 1101 if (!connection)
997 return; 1102 return;
998 DCHECK(!dbus_connection_get_is_connected(connection)); 1103 DCHECK(!dbus_connection_get_is_connected(connection));
999 1104
1000 ShutdownAndBlock(); 1105 ShutdownAndBlock();
1001 } 1106 }
1002 1107
1108 DBusHandlerResult Bus::OnServiceOwnerChanged(DBusMessage* message) {
1109 DCHECK(message);
1110 AssertOnDBusThread();
1111
1112 // |message| will be unrefed on exit of the function. Increment the
1113 // reference so we can use it in Signal::FromRawMessage() below.
1114 dbus_message_ref(message);
1115 scoped_ptr<Signal> signal(Signal::FromRawMessage(message));
1116
1117 // Confirm the validity of the NameOwnerChanged signal.
1118 if (signal->GetMember() != kNameOwnerChangedSignal ||
1119 signal->GetInterface() != DBUS_INTERFACE_DBUS ||
1120 signal->GetSender() != DBUS_SERVICE_DBUS) {
1121 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1122 }
1123
1124 MessageReader reader(signal.get());
1125 std::string service_name;
1126 std::string old_owner;
1127 std::string new_owner;
1128 if (!reader.PopString(&service_name) ||
1129 !reader.PopString(&old_owner) ||
1130 !reader.PopString(&new_owner)) {
1131 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1132 }
1133
1134 ServiceOwnerChangedListenerMap::const_iterator it =
1135 service_owner_changed_listener_map_.find(service_name);
1136 if (it == service_owner_changed_listener_map_.end())
1137 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1138
1139 const std::vector<GetServiceOwnerCallback>& callbacks = it->second;
1140 for (size_t i = 0; i < callbacks.size(); ++i) {
1141 PostTaskToOriginThread(FROM_HERE,
1142 base::Bind(callbacks[i], new_owner));
1143 }
1144 return DBUS_HANDLER_RESULT_HANDLED;
1145 }
1146
1147 // static
1003 dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) { 1148 dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) {
1004 Bus* self = static_cast<Bus*>(data); 1149 Bus* self = static_cast<Bus*>(data);
1005 return self->OnAddWatch(raw_watch); 1150 return self->OnAddWatch(raw_watch);
1006 } 1151 }
1007 1152
1153 // static
1008 void Bus::OnRemoveWatchThunk(DBusWatch* raw_watch, void* data) { 1154 void Bus::OnRemoveWatchThunk(DBusWatch* raw_watch, void* data) {
1009 Bus* self = static_cast<Bus*>(data); 1155 Bus* self = static_cast<Bus*>(data);
1010 self->OnRemoveWatch(raw_watch); 1156 self->OnRemoveWatch(raw_watch);
1011 } 1157 }
1012 1158
1159 // static
1013 void Bus::OnToggleWatchThunk(DBusWatch* raw_watch, void* data) { 1160 void Bus::OnToggleWatchThunk(DBusWatch* raw_watch, void* data) {
1014 Bus* self = static_cast<Bus*>(data); 1161 Bus* self = static_cast<Bus*>(data);
1015 self->OnToggleWatch(raw_watch); 1162 self->OnToggleWatch(raw_watch);
1016 } 1163 }
1017 1164
1165 // static
1018 dbus_bool_t Bus::OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 1166 dbus_bool_t Bus::OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1019 Bus* self = static_cast<Bus*>(data); 1167 Bus* self = static_cast<Bus*>(data);
1020 return self->OnAddTimeout(raw_timeout); 1168 return self->OnAddTimeout(raw_timeout);
1021 } 1169 }
1022 1170
1171 // static
1023 void Bus::OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 1172 void Bus::OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1024 Bus* self = static_cast<Bus*>(data); 1173 Bus* self = static_cast<Bus*>(data);
1025 self->OnRemoveTimeout(raw_timeout); 1174 self->OnRemoveTimeout(raw_timeout);
1026 } 1175 }
1027 1176
1177 // static
1028 void Bus::OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 1178 void Bus::OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1029 Bus* self = static_cast<Bus*>(data); 1179 Bus* self = static_cast<Bus*>(data);
1030 self->OnToggleTimeout(raw_timeout); 1180 self->OnToggleTimeout(raw_timeout);
1031 } 1181 }
1032 1182
1183 // static
1033 void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection, 1184 void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection,
1034 DBusDispatchStatus status, 1185 DBusDispatchStatus status,
1035 void* data) { 1186 void* data) {
1036 Bus* self = static_cast<Bus*>(data); 1187 Bus* self = static_cast<Bus*>(data);
1037 self->OnDispatchStatusChanged(connection, status); 1188 self->OnDispatchStatusChanged(connection, status);
1038 } 1189 }
1039 1190
1191 // static
1040 DBusHandlerResult Bus::OnConnectionDisconnectedFilter( 1192 DBusHandlerResult Bus::OnConnectionDisconnectedFilter(
1041 DBusConnection* connection, 1193 DBusConnection* connection,
1042 DBusMessage* message, 1194 DBusMessage* message,
1043 void* data) { 1195 void* data) {
1044 if (dbus_message_is_signal(message, 1196 if (dbus_message_is_signal(message,
1045 DBUS_INTERFACE_LOCAL, 1197 DBUS_INTERFACE_LOCAL,
1046 kDisconnectedSignal)) { 1198 kDisconnectedSignal)) {
1047 Bus* self = static_cast<Bus*>(data); 1199 Bus* self = static_cast<Bus*>(data);
1048 self->AssertOnDBusThread();
1049 self->OnConnectionDisconnected(connection); 1200 self->OnConnectionDisconnected(connection);
1050 return DBUS_HANDLER_RESULT_HANDLED; 1201 return DBUS_HANDLER_RESULT_HANDLED;
1051 } 1202 }
1052 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 1203 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1053 } 1204 }
1054 1205
1206 // static
1207 DBusHandlerResult Bus::OnServiceOwnerChangedFilter(
1208 DBusConnection* connection,
1209 DBusMessage* message,
1210 void* data) {
1211 if (dbus_message_is_signal(message,
1212 DBUS_INTERFACE_DBUS,
1213 kNameOwnerChangedSignal)) {
1214 Bus* self = static_cast<Bus*>(data);
1215 return self->OnServiceOwnerChanged(message);
1216 }
1217 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1218 }
1219
1055 } // namespace dbus 1220 } // namespace dbus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698