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

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

Powered by Google App Engine
This is Rietveld 408576698