| OLD | NEW |
| 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/exported_object.h" | 5 #include "dbus/exported_object.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/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 211 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 212 } | 212 } |
| 213 | 213 |
| 214 const base::TimeTicks start_time = base::TimeTicks::Now(); | 214 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 215 if (bus_->HasDBusThread()) { | 215 if (bus_->HasDBusThread()) { |
| 216 // Post a task to run the method in the origin thread. | 216 // Post a task to run the method in the origin thread. |
| 217 bus_->PostTaskToOriginThread(FROM_HERE, | 217 bus_->PostTaskToOriginThread(FROM_HERE, |
| 218 base::Bind(&ExportedObject::RunMethod, | 218 base::Bind(&ExportedObject::RunMethod, |
| 219 this, | 219 this, |
| 220 iter->second, | 220 iter->second, |
| 221 method_call.release(), | 221 base::Passed(&method_call), |
| 222 start_time)); | 222 start_time)); |
| 223 } else { | 223 } else { |
| 224 // If the D-Bus thread is not used, just call the method directly. | 224 // If the D-Bus thread is not used, just call the method directly. |
| 225 MethodCall* released_method_call = method_call.release(); | 225 MethodCall* method = method_call.get(); |
| 226 iter->second.Run(released_method_call, | 226 iter->second.Run(method, |
| 227 base::Bind(&ExportedObject::SendResponse, | 227 base::Bind(&ExportedObject::SendResponse, |
| 228 this, | 228 this, |
| 229 start_time, | 229 start_time, |
| 230 released_method_call)); | 230 base::Passed(&method_call))); |
| 231 } | 231 } |
| 232 | 232 |
| 233 // It's valid to say HANDLED here, and send a method response at a later | 233 // It's valid to say HANDLED here, and send a method response at a later |
| 234 // time from OnMethodCompleted() asynchronously. | 234 // time from OnMethodCompleted() asynchronously. |
| 235 return DBUS_HANDLER_RESULT_HANDLED; | 235 return DBUS_HANDLER_RESULT_HANDLED; |
| 236 } | 236 } |
| 237 | 237 |
| 238 void ExportedObject::RunMethod(MethodCallCallback method_call_callback, | 238 void ExportedObject::RunMethod(MethodCallCallback method_call_callback, |
| 239 MethodCall* method_call, | 239 scoped_ptr<MethodCall> method_call, |
| 240 base::TimeTicks start_time) { | 240 base::TimeTicks start_time) { |
| 241 bus_->AssertOnOriginThread(); | 241 bus_->AssertOnOriginThread(); |
| 242 method_call_callback.Run(method_call, | 242 MethodCall* method = method_call.get(); |
| 243 method_call_callback.Run(method, |
| 243 base::Bind(&ExportedObject::SendResponse, | 244 base::Bind(&ExportedObject::SendResponse, |
| 244 this, | 245 this, |
| 245 start_time, | 246 start_time, |
| 246 method_call)); | 247 base::Passed(&method_call))); |
| 247 } | 248 } |
| 248 | 249 |
| 249 void ExportedObject::SendResponse(base::TimeTicks start_time, | 250 void ExportedObject::SendResponse(base::TimeTicks start_time, |
| 250 MethodCall* method_call, | 251 scoped_ptr<MethodCall> method_call, |
| 251 Response* response) { | 252 scoped_ptr<Response> response) { |
| 252 DCHECK(method_call); | 253 DCHECK(method_call); |
| 253 if (bus_->HasDBusThread()) { | 254 if (bus_->HasDBusThread()) { |
| 254 bus_->PostTaskToDBusThread(FROM_HERE, | 255 bus_->PostTaskToDBusThread(FROM_HERE, |
| 255 base::Bind(&ExportedObject::OnMethodCompleted, | 256 base::Bind(&ExportedObject::OnMethodCompleted, |
| 256 this, | 257 this, |
| 257 method_call, | 258 base::Passed(&method_call), |
| 258 response, | 259 base::Passed(&response), |
| 259 start_time)); | 260 start_time)); |
| 260 } else { | 261 } else { |
| 261 OnMethodCompleted(method_call, response, start_time); | 262 OnMethodCompleted(method_call.Pass(), response.Pass(), start_time); |
| 262 } | 263 } |
| 263 } | 264 } |
| 264 | 265 |
| 265 void ExportedObject::OnMethodCompleted(MethodCall* method_call, | 266 void ExportedObject::OnMethodCompleted(scoped_ptr<MethodCall> method_call, |
| 266 Response* response, | 267 scoped_ptr<Response> response, |
| 267 base::TimeTicks start_time) { | 268 base::TimeTicks start_time) { |
| 268 bus_->AssertOnDBusThread(); | 269 bus_->AssertOnDBusThread(); |
| 269 scoped_ptr<MethodCall> method_call_deleter(method_call); | |
| 270 scoped_ptr<Response> response_deleter(response); | |
| 271 | 270 |
| 272 // Record if the method call is successful, or not. 1 if successful. | 271 // Record if the method call is successful, or not. 1 if successful. |
| 273 UMA_HISTOGRAM_ENUMERATION("DBus.ExportedMethodHandleSuccess", | 272 UMA_HISTOGRAM_ENUMERATION("DBus.ExportedMethodHandleSuccess", |
| 274 response ? 1 : 0, | 273 response ? 1 : 0, |
| 275 kSuccessRatioHistogramMaxValue); | 274 kSuccessRatioHistogramMaxValue); |
| 276 | 275 |
| 277 // Check if the bus is still connected. If the method takes long to | 276 // Check if the bus is still connected. If the method takes long to |
| 278 // complete, the bus may be shut down meanwhile. | 277 // complete, the bus may be shut down meanwhile. |
| 279 if (!bus_->is_connected()) | 278 if (!bus_->is_connected()) |
| 280 return; | 279 return; |
| 281 | 280 |
| 282 if (!response) { | 281 if (!response) { |
| 283 // Something bad happened in the method call. | 282 // Something bad happened in the method call. |
| 284 scoped_ptr<dbus::ErrorResponse> error_response( | 283 scoped_ptr<dbus::ErrorResponse> error_response( |
| 285 ErrorResponse::FromMethodCall( | 284 ErrorResponse::FromMethodCall( |
| 286 method_call, | 285 method_call.get(), |
| 287 DBUS_ERROR_FAILED, | 286 DBUS_ERROR_FAILED, |
| 288 "error occurred in " + method_call->GetMember())); | 287 "error occurred in " + method_call->GetMember())); |
| 289 bus_->Send(error_response->raw_message(), NULL); | 288 bus_->Send(error_response->raw_message(), NULL); |
| 290 return; | 289 return; |
| 291 } | 290 } |
| 292 | 291 |
| 293 // The method call was successful. | 292 // The method call was successful. |
| 294 bus_->Send(response->raw_message(), NULL); | 293 bus_->Send(response->raw_message(), NULL); |
| 295 | 294 |
| 296 // Record time spent to handle the the method call. Don't include failures. | 295 // Record time spent to handle the the method call. Don't include failures. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 309 return self->HandleMessage(connection, raw_message); | 308 return self->HandleMessage(connection, raw_message); |
| 310 } | 309 } |
| 311 | 310 |
| 312 void ExportedObject::OnUnregisteredThunk(DBusConnection *connection, | 311 void ExportedObject::OnUnregisteredThunk(DBusConnection *connection, |
| 313 void* user_data) { | 312 void* user_data) { |
| 314 ExportedObject* self = reinterpret_cast<ExportedObject*>(user_data); | 313 ExportedObject* self = reinterpret_cast<ExportedObject*>(user_data); |
| 315 return self->OnUnregistered(connection); | 314 return self->OnUnregistered(connection); |
| 316 } | 315 } |
| 317 | 316 |
| 318 } // namespace dbus | 317 } // namespace dbus |
| OLD | NEW |