already_AddRefed<Promise> BluetoothMapRequestHandle::ReplyToFolderListing(long aMasId, const nsAString& aFolderlists, ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject()); if (!global) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsRefPtr<Promise> promise = Promise::Create(global, aRv); NS_ENSURE_TRUE(!aRv.Failed(), nullptr); BluetoothService* bs = BluetoothService::Get(); if (!bs) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } if (XRE_GetProcessType() == GeckoProcessType_Default) { // In-process reply bs->ReplyToMapFolderListing(aMasId, aFolderlists, new BluetoothVoidReplyRunnable(nullptr, promise)); } else { ContentChild *cc = ContentChild::GetSingleton(); if (!cc) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } bs->ReplyToMapFolderListing(aMasId, aFolderlists, new BluetoothVoidReplyRunnable(nullptr, promise)); } return promise.forget(); }
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aWindow, const BluetoothValue& aValue) : DOMEventTargetHelper(aWindow) , BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER) , mJsUuids(nullptr) , mJsDeviceAddresses(nullptr) , mDiscoverable(false) , mDiscovering(false) , mPairable(false) , mPowered(false) , mIsRooted(false) { MOZ_ASSERT(aWindow); const InfallibleTArray<BluetoothNamedValue>& values = aValue.get_ArrayOfBluetoothNamedValue(); for (uint32_t i = 0; i < values.Length(); ++i) { SetPropertyByValue(values[i]); } BluetoothService* bs = BluetoothService::Get(); NS_ENSURE_TRUE_VOID(bs); bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this); }
BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aWindow, const nsAString& aAdapterPath, const BluetoothValue& aValue) : DOMEventTargetHelper(aWindow) , BluetoothPropertyContainer(BluetoothObjectType::TYPE_DEVICE) , mJsUuids(nullptr) , mJsServices(nullptr) , mAdapterPath(aAdapterPath) , mConnected(false) , mPaired(false) , mIsRooted(false) { MOZ_ASSERT(aWindow); const InfallibleTArray<BluetoothNamedValue>& values = aValue.get_ArrayOfBluetoothNamedValue(); for (uint32_t i = 0; i < values.Length(); ++i) { SetPropertyByValue(values[i]); } BluetoothService* bs = BluetoothService::Get(); NS_ENSURE_TRUE_VOID(bs); bs->RegisterBluetoothSignalHandler(mAddress, this); }
bool Execute() override { BluetoothService* bs = BluetoothService::Get(); if (NS_WARN_IF(!bs)) { return false; } BluetoothUuid appUuid; if (NS_FAILED(StringToUuid(mServer->mAppUuid, appUuid))) { return false; } BluetoothUuid uuid; mDescriptor->GetUuid(uuid); bs->GattServerAddDescriptorInternal( appUuid, mService->GetServiceHandle(), mCharacteristic->GetCharacteristicHandle(), uuid, mDescriptor->GetPermissions(), GetReply()); return true; }
bool BluetoothProfileController::IsBtServiceAvailable() const { BluetoothService* bs = BluetoothService::Get(); return (bs && bs->IsEnabled() && !bs->IsToggling()); }
already_AddRefed<Promise> BluetoothGattServer::SendResponse(const nsAString& aAddress, uint16_t aStatus, int32_t aRequestId, ErrorResult& aRv) { nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject()); if (!global) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } RefPtr<Promise> promise = Promise::Create(global, aRv); NS_ENSURE_TRUE(!aRv.Failed(), nullptr); BluetoothUuid appUuid; BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(StringToUuid(mAppUuid, appUuid)), promise, NS_ERROR_DOM_OPERATION_ERR); BluetoothAddress address; BT_ENSURE_TRUE_REJECT( NS_SUCCEEDED(StringToAddress(aAddress, address)), promise, NS_ERROR_INVALID_ARG); BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE); RequestData* requestData; mRequestMap.Get(aRequestId, &requestData); BT_ENSURE_TRUE_REJECT(requestData, promise, NS_ERROR_UNEXPECTED); BluetoothGattResponse response; memset(&response, 0, sizeof(response)); response.mHandle = requestData->mHandle; if (requestData->mCharacteristic) { const nsTArray<uint8_t>& value = requestData->mCharacteristic->GetValue(); response.mLength = value.Length(); memcpy(&response.mValue, value.Elements(), response.mLength); } else if (requestData->mDescriptor) { const nsTArray<uint8_t>& value = requestData->mDescriptor->GetValue(); response.mLength = value.Length(); memcpy(&response.mValue, value.Elements(), response.mLength); } else { MOZ_ASSERT_UNREACHABLE( "There should be at least one characteristic or descriptor in the " "request data."); promise->MaybeReject(NS_ERROR_INVALID_ARG); return promise.forget(); } BluetoothService* bs = BluetoothService::Get(); BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE); bs->GattServerSendResponseInternal( appUuid, address, aStatus, aRequestId, response, new BluetoothVoidReplyRunnable(nullptr, promise)); return promise.forget(); }
BluetoothManager::~BluetoothManager() { BluetoothService* bs = BluetoothService::Get(); NS_ENSURE_TRUE_VOID(bs); bs->UnregisterBluetoothSignalHandler(mPath, this); }
BluetoothManager::~BluetoothManager() { BluetoothService* bs = BluetoothService::Get(); NS_ENSURE_TRUE_VOID(bs); bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this); }
void BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState) { MOZ_ASSERT(NS_IsMainThread()); BT_LOGR("BT_STATE: %d", aState); sAdapterEnabled = aState; if (!sAdapterEnabled) { static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = { BluetoothHfpManager::DeinitHfpInterface, BluetoothA2dpManager::DeinitA2dpInterface, BluetoothGattManager::DeinitGattInterface }; // Return error if BluetoothService is unavailable BluetoothService* bs = BluetoothService::Get(); NS_ENSURE_TRUE_VOID(bs); // Cleanup static adapter properties and notify adapter. sAdapterBdAddress.Truncate(); sAdapterBdName.Truncate(); InfallibleTArray<BluetoothNamedValue> props; BT_APPEND_NAMED_VALUE(props, "Name", sAdapterBdName); BT_APPEND_NAMED_VALUE(props, "Address", sAdapterBdAddress); if (sAdapterDiscoverable) { sAdapterDiscoverable = false; BT_APPEND_NAMED_VALUE(props, "Discoverable", false); } if (sAdapterDiscovering) { sAdapterDiscovering = false; BT_APPEND_NAMED_VALUE(props, "Discovering", false); } bs->DistributeSignal(NS_LITERAL_STRING("PropertyChanged"), NS_LITERAL_STRING(KEY_ADAPTER), BluetoothValue(props)); // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF. nsRefPtr<ProfileDeinitResultHandler> res = new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager)); for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) { sDeinitManager[i](res); } } BluetoothService::AcknowledgeToggleBt(sAdapterEnabled); if (sAdapterEnabled) { // Bluetooth just enabled, clear profile controllers and runnable arrays. sControllerArray.Clear(); sChangeDiscoveryRunnableArray.Clear(); sSetPropertyRunnableArray.Clear(); sGetDeviceRunnableArray.Clear(); sFetchUuidsRunnableArray.Clear(); sBondingRunnableArray.Clear(); sUnbondingRunnableArray.Clear(); sPairingNameTable.Clear(); // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., it should // be connectable and non-discoverable. NS_ENSURE_TRUE_VOID(sBtInterface); sBtInterface->SetAdapterProperty( BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false), new SetAdapterPropertyDiscoverableResultHandler()); // Trigger BluetoothOppManager to listen BluetoothOppManager* opp = BluetoothOppManager::Get(); if (!opp || !opp->Listen()) { BT_LOGR("Fail to start BluetoothOppManager listening"); } } // Resolve promise if existed if (!sChangeAdapterStateRunnableArray.IsEmpty()) { DispatchReplySuccess(sChangeAdapterStateRunnableArray[0]); sChangeAdapterStateRunnableArray.RemoveElementAt(0); } }
nsresult BluetoothManager::HandleMozsettingChanged(const PRUnichar* aData) { // The string that we're interested in will be a JSON string that looks like: // {"key":"bluetooth.enabled","value":true} nsresult rv; nsIScriptContext* sc = GetContextForEventHandlers(&rv); if (NS_FAILED(rv)) { return NS_ERROR_UNEXPECTED; } JSContext *cx = sc->GetNativeContext(); if (!cx) { return NS_OK; } // In the following [if] blocks, NS_OK will be returned even if JS_* functions // return false. That's because this function gets called whenever mozSettings // changes, so that we'll receive signals we're not interested in and it would // be one of the reasons for making JS_* functions return false. nsDependentString dataStr(aData); JS::Value val; if (!JS_ParseJSON(cx, dataStr.get(), dataStr.Length(), &val)) { return NS_OK; } if (!val.isObject()) { return NS_OK; } JSObject &obj(val.toObject()); JS::Value key; if (!JS_GetProperty(cx, &obj, "key", &key)) { return NS_OK; } if (!key.isString()) { return NS_OK; } JSBool match; if (!JS_StringEqualsAscii(cx, key.toString(), "bluetooth.enabled", &match)) { return NS_OK; } if (!match) { return NS_OK; } JS::Value value; if (!JS_GetProperty(cx, &obj, "value", &value)) { return NS_OK; } if (!value.isBoolean()) { return NS_OK; } BluetoothService* bs = BluetoothService::Get(); if (!bs) { NS_WARNING("BluetoothService not available!"); return NS_ERROR_FAILURE; } bool enabled = value.toBoolean(); nsCOMPtr<nsIRunnable> resultTask = new ToggleBtResultTask(this, enabled); if (enabled) { if (NS_FAILED(bs->Start(resultTask))) { return NS_ERROR_FAILURE; } } else { if (NS_FAILED(bs->Stop(resultTask))) { return NS_ERROR_FAILURE; } } return NS_OK; }