зеркало из https://github.com/mozilla/gecko-dev.git
Bug 906019: Implemented non-blocking GetDefaultAdapterPathInternal, r=echou,gyeh
GetDefaultAdapterPathInternal used two blocking DBus operations, namely 'DefaultAdapter' and 'GetProperties'. The latter one depends on the result of the former one. The be non-blocking, GetDefaultAdapterPathInternal first make a non-blocking 'DefaultAdapter' call. Once received, the reply handler non-blockingly calls 'GetProperties' with the values received for 'DefaultAdapter', and put itself in place as this call's reply handler. For this second reply, it finally schedules the Bluetooth reply runnable. --HG-- extra : rebase_source : aa0872a5db69c928ca25723952fe2928ef52d107
This commit is contained in:
Родитель
482dd7c30b
Коммит
88b10d29d8
|
@ -1789,46 +1789,119 @@ BluetoothDBusService::IsEnabledInternal()
|
||||||
return mEnabled;
|
return mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultAdapterPropertiesRunnable : public nsRunnable
|
class DefaultAdapterPathReplyHandler : public DBusReplyHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DefaultAdapterPropertiesRunnable(BluetoothReplyRunnable* aRunnable)
|
DefaultAdapterPathReplyHandler(BluetoothReplyRunnable* aRunnable)
|
||||||
: mRunnable(dont_AddRef(aRunnable))
|
: mRunnable(aRunnable)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult Run()
|
void Handle(DBusMessage* aReply) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread()); // DBus thread
|
||||||
|
|
||||||
BluetoothValue v;
|
if (!aReply || (dbus_message_get_type(aReply) == DBUS_MESSAGE_TYPE_ERROR)) {
|
||||||
nsAutoString replyError;
|
const char* errStr = "Timeout in DefaultAdapterPathReplyHandler";
|
||||||
if (!GetDefaultAdapterPath(v, replyError)) {
|
if (aReply) {
|
||||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
errStr = dbus_message_get_error_name(aReply);
|
||||||
return NS_ERROR_FAILURE;
|
if (!errStr) {
|
||||||
|
errStr = "Bluetooth DBus Error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DispatchBluetoothReply(mRunnable, BluetoothValue(),
|
||||||
|
NS_ConvertUTF8toUTF16(errStr));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusError err;
|
bool success;
|
||||||
dbus_error_init(&err);
|
nsAutoString replyError;
|
||||||
|
|
||||||
nsString objectPath = v.get_nsString();
|
if (mAdapterPath.IsEmpty()) {
|
||||||
v = InfallibleTArray<BluetoothNamedValue>();
|
success = HandleDefaultAdapterPathReply(aReply, replyError);
|
||||||
if (!GetPropertiesInternal(objectPath, DBUS_ADAPTER_IFACE, v)) {
|
} else {
|
||||||
NS_WARNING("Getting properties failed!");
|
success = HandleGetPropertiesReply(aReply, replyError);
|
||||||
return NS_ERROR_FAILURE;
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
DispatchBluetoothReply(mRunnable, BluetoothValue(), replyError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool HandleDefaultAdapterPathReply(DBusMessage* aReply,
|
||||||
|
nsAString& aReplyError)
|
||||||
|
{
|
||||||
|
BluetoothValue value;
|
||||||
|
DBusError error;
|
||||||
|
dbus_error_init(&error);
|
||||||
|
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread()); // DBus thread
|
||||||
|
|
||||||
|
UnpackObjectPathMessage(aReply, &error, value, aReplyError);
|
||||||
|
|
||||||
|
if (!aReplyError.IsEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAdapterPath = value.get_nsString();
|
||||||
|
|
||||||
|
// Acquire another reference to this reply handler
|
||||||
|
nsRefPtr<DefaultAdapterPathReplyHandler> handler = this;
|
||||||
|
|
||||||
|
nsRefPtr<RawDBusConnection> threadConnection = gThreadConnection;
|
||||||
|
|
||||||
|
if (!threadConnection.get()) {
|
||||||
|
aReplyError = NS_LITERAL_STRING("DBus connection has been closed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = dbus_func_args_async(threadConnection->GetConnection(), 1000,
|
||||||
|
DefaultAdapterPathReplyHandler::Callback,
|
||||||
|
handler.get(),
|
||||||
|
NS_ConvertUTF16toUTF8(mAdapterPath).get(),
|
||||||
|
DBUS_ADAPTER_IFACE, "GetProperties",
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
if (!success) {
|
||||||
|
aReplyError = NS_LITERAL_STRING("dbus_func_args_async failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.forget();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HandleGetPropertiesReply(DBusMessage* aReply,
|
||||||
|
nsAutoString& aReplyError)
|
||||||
|
{
|
||||||
|
BluetoothValue value;
|
||||||
|
DBusError error;
|
||||||
|
dbus_error_init(&error);
|
||||||
|
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread()); // DBus thread
|
||||||
|
|
||||||
|
bool success = UnpackPropertiesMessage(aReply, &error, value,
|
||||||
|
DBUS_ADAPTER_IFACE);
|
||||||
|
if (!success) {
|
||||||
|
aReplyError = NS_ConvertUTF8toUTF16(error.message);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to manually attach the path to the rest of the elements
|
// We have to manually attach the path to the rest of the elements
|
||||||
v.get_ArrayOfBluetoothNamedValue().AppendElement(
|
value.get_ArrayOfBluetoothNamedValue().AppendElement(
|
||||||
BluetoothNamedValue(NS_LITERAL_STRING("Path"), objectPath));
|
BluetoothNamedValue(NS_LITERAL_STRING("Path"), mAdapterPath));
|
||||||
|
|
||||||
DispatchBluetoothReply(mRunnable, v, replyError);
|
// Dispatch result
|
||||||
|
DispatchBluetoothReply(mRunnable, value, aReplyError);
|
||||||
|
|
||||||
return NS_OK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||||
|
nsString mAdapterPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -1843,14 +1916,18 @@ BluetoothDBusService::GetDefaultAdapterPathInternal(
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
|
nsRefPtr<DefaultAdapterPathReplyHandler> handler =
|
||||||
nsRefPtr<nsRunnable> func(new DefaultAdapterPropertiesRunnable(runnable));
|
new DefaultAdapterPathReplyHandler(aRunnable);
|
||||||
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
|
bool success = dbus_func_args_async(mConnection, 1000,
|
||||||
NS_WARNING("Cannot dispatch firmware loading task!");
|
DefaultAdapterPathReplyHandler::Callback,
|
||||||
return NS_ERROR_FAILURE;
|
handler.get(),
|
||||||
}
|
"/",
|
||||||
|
DBUS_MANAGER_IFACE, "DefaultAdapter",
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
handler.forget();
|
||||||
|
|
||||||
runnable.forget();
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче