mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1186307 - StructuredCloneHelper in workers.postMessage(), r=smaug (0d3c817afa) - Bug 1183824 - Remove NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED) warning from nsFrameMessageManager::DispatchAsyncMessageInternal. r=smaug (64dfd50f7f) - Bug 1167189: Use a size annotation on the OOM abort. r=bholley (5e7fb331a0) - missing crash reporter (47f183fab4) - Bug 1137151: Marked destructor of |nsClipboard| as protected, r=mwu (5655bf8862) - Bug 1194497 - Convert a few remaining PRUnichar to char16_t. r=roc (1554ffcec2) - Bug 952456 - Part 1: Implement gonk/nsClipboard for rich text and raw image. r=fabrice (419381f7af) - Bug 1198795 - ipc/StructuredCloneUtils should be merged with StructuredCloneHelper, r=smaug (02183262bd) - Bug 1201806 - part 1 - Remove OwningSerializedStructuredCloneBuffer and use StructuredCloneIPCHelper everywhere in IPC code, r=smaug (6dc69151b4) - Bug 1201806 - part 2 - nsStructuredCloneContainer should use StructuredCloneIPCHelper, r=smaug (b6ebaa8e95) - Bug 1202028 - Implement range based for loops for SavedFrame stacks. r=terrence (57c198910c) - missing bit of Bug 1106264 (fa67f8ab56) - Bug 1168806: Configurable I/O thread for socket IPC classes, r=kmachulis (213a8fb2b9) - Bug 1159209: Remove template parameters from |DataSocketIO|, r=kmachulis (0d658c5cf8) - Bug 1168806: Configurable consumer thread for socket IPC classes, r=kmachulis (ee054dd6b0) - Bug 1167207: Add |BluetoothDaemonConnectionConsumer|, r=shuang (b8b89290df) - Bug 1154281: Remove |UnixSocketConsumer| and its helpers, r=kmachulis (d40430b10f) - Bug 1166638: Add |StreamSocketConsumer|, r=kmachulis (59b5c1abf3) - Bug 1166638: Add |ListenSocketConsumer|, r=kmachulis (d119bcaa2a) - Bug 1168806: Use 'consumer thread' in socket interface, r=kmachulis (65d232d21c) - Bug 1170466: Inherit |ConnectionOrientedSocketIO| from |UnixSocketWatcher|, r=kmachulis (b91d0c624a) - Bug 1170466: Share socket I/O methods in |ConnectionOrientedSocketIO|, r=kmachulis (108fb6696e) - Bug 1170466: Implement accept and connect in |ConnectionOrientedSocketIO|, r=kmachulis (590b3b4617) - Bug 1172479: Replace |nsIThread| by |MessageLoop| in socket I/O code, r=kmachulis (618073dcef) - Bug 1203426 - Rename StructuredCloneIPCHelper to StructuredCloneData, r=smaug (dc31124113) - Bug 1167392 - Change nsFrameMessageManager::mParentManager to a smart pointer. r=ehsan (98d60c0398) - Bug 1186843 - Always cache delayed scripts in message manager (b0ab501959) - Bug 1189550 - In parent process, cpmm.initialProcessData should be same as ppmm.initialProcessData (r=smaug) (7a8ab62432) - Bug 1196057 - Use channel->Open2() in dom/base/nsFrameMessageManager.cpp (r=sicking) (a032d483d6) - missing parts of Bug 1132072 - Tab switch refactoring (r=mconley) (e6fbbb722a) - Bug 1175736 - Implement the iframe referrer attribute. r=ckerschb, r=bz (a5fc4e683b) - Bug 1171017: Rename |BluetoothDaemonConnectionConsumer| to |DaemonSocketConsumer|, r=shuang (0af5957609) - Bug 1170993: Manage socket buffers in sub-classes of |UnixSocketBuffer|, r=kmachulis (960de8be45) - Bug 1171017: Rename |BluetoothDaemonPDUConsumer| to |DaemonSocketIOConsumer|, r=shuang (eea1681ab8) - Bug 1171100 - Fix incorrect logic of handling Bluetooth Gatt Responses in daemon backend. r=tzimmermann (c385364d1e) - Bug 1171866 - Remove ReversedUuidToString; f=tzimmermann, r=jocelyn (9b58176c39) - Bug 1171017: Rename |BluetoothSocketPDU| to |DaemonSocketPDU|, r=shuang (ce1bbd9d4a) - Bug 1171017: Rename |BluetoothDaemonConnectionIO| to |DaemonSocketIO|, r=shuang (00f2a38220) - Bug 1171017: Rename |BluetoothDaemonConnection| to |DaemonSocket|, r=shuang (b3c3522719) - Bug 1171017: Move classes from ipc/bluetooth to ipc/hal, r=shuang (047714aee4) - Bug 1171994: Add |RilSocket| and |RilSocketConsumer|, r=htsai (276211bbb7) - Bug 1171994: Forward received RIL socket I/O via |WorkerCrossThreadDispatcher|, r=htsai (7825d1c837) - Bug 1185478: Add leak checks to socket I/O classes (40e2c01ce4) - Bug 1185478: Remove strong references from socket I/O class to socket classes (6fa94f34ff) - Bug 1163912: Set |Type| property of BluetoothDevice a initial value during LeScan; f=elin, r=jocelyn (bda66689ed) - Bug 1166215 - Cast 'BluetoothTypeOfDevice' to uint32_t before the BT signal is distributed to BluetoothAdapter. r=joliu (d38ad4e55f) - Bug 1170086 - Fix the parameter type of DispatchReplyError() in StartLeScan result handler. r=joliu (a24e23e02f) - Bug 1161956 - Fix crashes while using GATT client functions. r=jocelyn (cebfb8c700) - Bug 1171868 - Remove GeneratePathFromGattId(aId, aPath, aUuidStr); r=jocelyn (0eac291b3c) - Bug 1161945 - Fix empty characteristics and descriptors after searching services. f=elin, r=jocelyn (a0d816fee4) - Bug 1164387 - Use |btgatt_client_interface_t.get_device_type| to get the device type. r=jocelyn (c7b5c97a00) - Bug 1173139 - Reorder global creation on workers, r=khuey. (acb79ae54e) - Bug 1170071 - Part 1: Revise BluetoothGattInterface, result handler, and interface helper for daemon support of gatt server. r=shuang (0ad0c9244e) - Bug 1170071 - Part 2: Add helpers for Bluetooth daemon GATT server support. r=shuang (46a4062579) - Bug 1170071 - Part 3: Add gatt server support to GATT module for Bluetooth daemon. r=shuang (71d80aabea) - Bug 1170071 - Part 4: Add Gatt server interfaces for Bluetooth daemon. r=shuang (a556aaf048) - Bug 1187230: Convert Bluetooth to use daemon runnables, r=shuang (9be6501225) - Bug 1204382: Add #include for nsIInputStream.h to MediaParent.cpp, to fix a build error in --disable-webrtc builds. r=jib (8b20e934)
This commit is contained in:
@@ -39,9 +39,16 @@ function makeTimelineTest(frameScriptName, url) {
|
||||
|
||||
/* Open a URL for a timeline test. */
|
||||
function timelineTestOpenUrl(url) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
window.focus();
|
||||
window.focus();
|
||||
|
||||
let tabSwitchPromise = new Promise((resolve, reject) => {
|
||||
window.gBrowser.addEventListener("TabSwitchDone", function listener() {
|
||||
window.gBrowser.removeEventListener("TabSwitchDone", listener);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
let loadPromise = new Promise(function(resolve, reject) {
|
||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
||||
let linkedBrowser = tab.linkedBrowser;
|
||||
|
||||
@@ -50,4 +57,6 @@ function timelineTestOpenUrl(url) {
|
||||
resolve(tab);
|
||||
}, true);
|
||||
});
|
||||
|
||||
return Promise.all([tabSwitchPromise, loadPromise]).then(([_, tab]) => tab);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ PostMessageEvent::PostMessageEvent(nsGlobalWindow* aSource,
|
||||
nsGlobalWindow* aTargetWindow,
|
||||
nsIPrincipal* aProvidedPrincipal,
|
||||
bool aTrustedCaller)
|
||||
: StructuredCloneHelper(CloningSupported, TransferringSupported),
|
||||
: StructuredCloneHelper(CloningSupported, TransferringSupported,
|
||||
SameProcessSameThread),
|
||||
mSource(aSource),
|
||||
mCallerOrigin(aCallerOrigin),
|
||||
mTargetWindow(aTargetWindow),
|
||||
@@ -113,8 +114,11 @@ PostMessageEvent::Run()
|
||||
false /*cancelable */, messageData, mCallerOrigin,
|
||||
EmptyString(), mSource);
|
||||
|
||||
nsTArray<nsRefPtr<MessagePortBase>> ports;
|
||||
TakeTransferredPorts(ports);
|
||||
|
||||
event->SetPorts(new MessagePortList(static_cast<dom::Event*>(event.get()),
|
||||
GetTransferredPorts()));
|
||||
ports));
|
||||
|
||||
// We can't simply call dispatchEvent on the window because doing so ends
|
||||
// up flipping the trusted bit on the event, and we don't want that to
|
||||
|
||||
@@ -14,11 +14,24 @@
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/StructuredClone.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/MessagePortBinding.h"
|
||||
#include "mozilla/dom/PMessagePort.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/WebCryptoCommon.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "MultipartBlobImpl.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsIRemoteBlob.h"
|
||||
#include "nsQueryObject.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -142,11 +155,7 @@ bool
|
||||
StructuredCloneHelperInternal::Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
MOZ_ASSERT(!mBuffer, "Double Write is not allowed");
|
||||
MOZ_ASSERT(!mShutdownCalled, "This method cannot be called after Shutdown.");
|
||||
|
||||
mBuffer = new JSAutoStructuredCloneBuffer(&gCallbacks, this);
|
||||
return mBuffer->write(aCx, aValue, &gCallbacks, this);
|
||||
return Write(aCx, aValue, JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -158,7 +167,13 @@ StructuredCloneHelperInternal::Write(JSContext* aCx,
|
||||
MOZ_ASSERT(!mShutdownCalled, "This method cannot be called after Shutdown.");
|
||||
|
||||
mBuffer = new JSAutoStructuredCloneBuffer(&gCallbacks, this);
|
||||
return mBuffer->write(aCx, aValue, aTransfer, &gCallbacks, this);
|
||||
|
||||
if (!mBuffer->write(aCx, aValue, aTransfer, &gCallbacks, this)) {
|
||||
mBuffer = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -208,15 +223,21 @@ StructuredCloneHelperInternal::FreeTransferCallback(uint32_t aTag,
|
||||
// StructuredCloneHelper class
|
||||
|
||||
StructuredCloneHelper::StructuredCloneHelper(CloningSupport aSupportsCloning,
|
||||
TransferringSupport aSupportsTransferring)
|
||||
TransferringSupport aSupportsTransferring,
|
||||
ContextSupport aContext)
|
||||
: mSupportsCloning(aSupportsCloning == CloningSupported)
|
||||
, mSupportsTransferring(aSupportsTransferring == TransferringSupported)
|
||||
, mContext(aContext)
|
||||
, mParent(nullptr)
|
||||
#ifdef DEBUG
|
||||
, mCreationThread(NS_GetCurrentThread())
|
||||
#endif
|
||||
{}
|
||||
|
||||
StructuredCloneHelper::~StructuredCloneHelper()
|
||||
{
|
||||
Shutdown();
|
||||
MOZ_ASSERT(mTransferredPorts.IsEmpty());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -233,8 +254,21 @@ StructuredCloneHelper::Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aTransfer,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT_IF(mContext == SameProcessSameThread,
|
||||
mCreationThread == NS_GetCurrentThread());
|
||||
|
||||
if (!StructuredCloneHelperInternal::Write(aCx, aValue, aTransfer)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mContext != SameProcessSameThread) {
|
||||
for (uint32_t i = 0, len = mBlobImplArray.Length(); i < len; ++i) {
|
||||
if (!mBlobImplArray[i]->MayBeClonedToOtherThreads()) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +278,9 @@ StructuredCloneHelper::Read(nsISupports* aParent,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT_IF(mContext == SameProcessSameThread,
|
||||
mCreationThread == NS_GetCurrentThread());
|
||||
|
||||
mozilla::AutoRestore<nsISupports*> guard(mParent);
|
||||
mParent = aParent;
|
||||
|
||||
@@ -280,6 +317,9 @@ StructuredCloneHelper::ReadFromBuffer(nsISupports* aParent,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT_IF(mContext == SameProcessSameThread,
|
||||
mCreationThread == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ASSERT(!mBuffer, "ReadFromBuffer() must be called without a Write().");
|
||||
MOZ_ASSERT(aBuffer);
|
||||
|
||||
@@ -297,6 +337,9 @@ void
|
||||
StructuredCloneHelper::MoveBufferDataToArray(FallibleTArray<uint8_t>& aArray,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT_IF(mContext == SameProcessSameThread,
|
||||
mCreationThread == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ASSERT(mBuffer, "MoveBuffer() cannot be called without a Write().");
|
||||
|
||||
if (NS_WARN_IF(!aArray.SetLength(BufferSize(), mozilla::fallible))) {
|
||||
@@ -324,6 +367,346 @@ StructuredCloneHelper::FreeBuffer(uint64_t* aBuffer,
|
||||
JS_ClearStructuredClone(aBuffer, aBufferLength, &gCallbacks, this, false);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Recursive!
|
||||
already_AddRefed<BlobImpl>
|
||||
EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl,
|
||||
PBackgroundChild* aManager = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
|
||||
if (!aManager) {
|
||||
aManager = BackgroundChild::GetForCurrentThread();
|
||||
MOZ_ASSERT(aManager);
|
||||
}
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = aBlobImpl;
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>* subBlobImpls =
|
||||
aBlobImpl->GetSubBlobImpls();
|
||||
|
||||
if (!subBlobImpls || !subBlobImpls->Length()) {
|
||||
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl)) {
|
||||
// Always make sure we have a blob from an actor we can use on this
|
||||
// thread.
|
||||
BlobChild* blobChild = BlobChild::GetOrCreate(aManager, blobImpl);
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
blobImpl = blobChild->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
DebugOnly<bool> isMutable;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
|
||||
MOZ_ASSERT(!isMutable);
|
||||
} else {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
|
||||
}
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
const uint32_t subBlobCount = subBlobImpls->Length();
|
||||
MOZ_ASSERT(subBlobCount);
|
||||
|
||||
nsTArray<nsRefPtr<BlobImpl>> newSubBlobImpls;
|
||||
newSubBlobImpls.SetLength(subBlobCount);
|
||||
|
||||
bool newBlobImplNeeded = false;
|
||||
|
||||
for (uint32_t index = 0; index < subBlobCount; index++) {
|
||||
const nsRefPtr<BlobImpl>& subBlobImpl = subBlobImpls->ElementAt(index);
|
||||
MOZ_ASSERT(subBlobImpl);
|
||||
|
||||
nsRefPtr<BlobImpl>& newSubBlobImpl = newSubBlobImpls[index];
|
||||
|
||||
newSubBlobImpl = EnsureBlobForBackgroundManager(subBlobImpl, aManager);
|
||||
MOZ_ASSERT(newSubBlobImpl);
|
||||
|
||||
if (subBlobImpl != newSubBlobImpl) {
|
||||
newBlobImplNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (newBlobImplNeeded) {
|
||||
nsString contentType;
|
||||
blobImpl->GetType(contentType);
|
||||
|
||||
if (blobImpl->IsFile()) {
|
||||
nsString name;
|
||||
blobImpl->GetName(name);
|
||||
|
||||
blobImpl = new MultipartBlobImpl(newSubBlobImpls, name, contentType);
|
||||
} else {
|
||||
blobImpl = new MultipartBlobImpl(newSubBlobImpls, contentType);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
|
||||
}
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ReadBlob(JSContext* aCx,
|
||||
uint32_t aIndex,
|
||||
StructuredCloneHelper* aHelper)
|
||||
{
|
||||
MOZ_ASSERT(aHelper);
|
||||
MOZ_ASSERT(aIndex < aHelper->BlobImpls().Length());
|
||||
nsRefPtr<BlobImpl> blobImpl = aHelper->BlobImpls()[aIndex];
|
||||
|
||||
blobImpl = EnsureBlobForBackgroundManager(blobImpl);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
// nsRefPtr<File> needs to go out of scope before toObjectOrNull() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
// can GC (because in some cases it can!), and a return statement with a
|
||||
// JSObject* type means that JSObject* is on the stack as a raw pointer
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<Blob> blob = Blob::Create(aHelper->ParentDuringRead(), blobImpl);
|
||||
if (!ToJSValue(aCx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
bool
|
||||
WriteBlob(JSStructuredCloneWriter* aWriter,
|
||||
Blob* aBlob,
|
||||
StructuredCloneHelper* aHelper)
|
||||
{
|
||||
MOZ_ASSERT(aWriter);
|
||||
MOZ_ASSERT(aBlob);
|
||||
MOZ_ASSERT(aHelper);
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = EnsureBlobForBackgroundManager(aBlob->Impl());
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
// We store the position of the blobImpl in the array as index.
|
||||
if (JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
|
||||
aHelper->BlobImpls().Length())) {
|
||||
aHelper->BlobImpls().AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the WriteFileList for the format.
|
||||
JSObject*
|
||||
ReadFileList(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
uint32_t aCount,
|
||||
StructuredCloneHelper* aHelper)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aReader);
|
||||
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<FileList> fileList = new FileList(aHelper->ParentDuringRead());
|
||||
|
||||
uint32_t tag, offset;
|
||||
// Offset is the index of the blobImpl from which we can find the blobImpl
|
||||
// for this FileList.
|
||||
if (!JS_ReadUint32Pair(aReader, &tag, &offset)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(tag == 0);
|
||||
|
||||
// |aCount| is the number of BlobImpls to use from the |offset|.
|
||||
for (uint32_t i = 0; i < aCount; ++i) {
|
||||
uint32_t index = offset + i;
|
||||
MOZ_ASSERT(index < aHelper->BlobImpls().Length());
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = aHelper->BlobImpls()[index];
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
nsRefPtr<File> file = File::Create(aHelper->ParentDuringRead(), blobImpl);
|
||||
if (!fileList->Append(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ToJSValue(aCx, fileList, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
// The format of the FileList serialization is:
|
||||
// - pair of ints: SCTAG_DOM_FILELIST, Length of the FileList
|
||||
// - pair of ints: 0, The offset of the BlobImpl array
|
||||
bool
|
||||
WriteFileList(JSStructuredCloneWriter* aWriter,
|
||||
FileList* aFileList,
|
||||
StructuredCloneHelper* aHelper)
|
||||
{
|
||||
MOZ_ASSERT(aWriter);
|
||||
MOZ_ASSERT(aFileList);
|
||||
MOZ_ASSERT(aHelper);
|
||||
|
||||
// A FileList is serialized writing the X number of elements and the offset
|
||||
// from mBlobImplArray. The Read will take X elements from mBlobImplArray
|
||||
// starting from the offset.
|
||||
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_FILELIST,
|
||||
aFileList->Length()) ||
|
||||
!JS_WriteUint32Pair(aWriter, 0,
|
||||
aHelper->BlobImpls().Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aFileList->Length(); ++i) {
|
||||
aHelper->BlobImpls().AppendElement(aFileList->Item(i)->Impl());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read the WriteFormData for the format.
|
||||
JSObject*
|
||||
ReadFormData(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
uint32_t aCount,
|
||||
StructuredCloneHelper* aHelper)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aReader);
|
||||
MOZ_ASSERT(aHelper);
|
||||
|
||||
// See the serialization of the FormData for the format.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<nsFormData> formData =
|
||||
new nsFormData(aHelper->ParentDuringRead());
|
||||
|
||||
Optional<nsAString> thirdArg;
|
||||
for (uint32_t i = 0; i < aCount; ++i) {
|
||||
nsAutoString name;
|
||||
if (!ReadString(aReader, name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t tag, indexOrLengthOfString;
|
||||
if (!JS_ReadUint32Pair(aReader, &tag, &indexOrLengthOfString)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (tag == SCTAG_DOM_BLOB) {
|
||||
MOZ_ASSERT(indexOrLengthOfString < aHelper->BlobImpls().Length());
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl =
|
||||
aHelper->BlobImpls()[indexOrLengthOfString];
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
nsRefPtr<File> file =
|
||||
File::Create(aHelper->ParentDuringRead(), blobImpl);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
formData->Append(name, *file, thirdArg);
|
||||
} else {
|
||||
MOZ_ASSERT(tag == 0);
|
||||
|
||||
nsAutoString value;
|
||||
value.SetLength(indexOrLengthOfString);
|
||||
size_t charSize = sizeof(nsString::char_type);
|
||||
if (!JS_ReadBytes(aReader, (void*) value.BeginWriting(),
|
||||
indexOrLengthOfString * charSize)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
formData->Append(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ToJSValue(aCx, formData, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
// The format of the FormData serialization is:
|
||||
// - pair of ints: SCTAG_DOM_FORMDATA, Length of the FormData elements
|
||||
// - for each Element element:
|
||||
// - name string
|
||||
// - if it's a blob:
|
||||
// - pair of ints: SCTAG_DOM_BLOB, index of the BlobImpl in the array
|
||||
// mBlobImplArray.
|
||||
// - else:
|
||||
// - pair of ints: 0, string length
|
||||
// - value string
|
||||
bool
|
||||
WriteFormData(JSStructuredCloneWriter* aWriter,
|
||||
nsFormData* aFormData,
|
||||
StructuredCloneHelper* aHelper)
|
||||
{
|
||||
MOZ_ASSERT(aWriter);
|
||||
MOZ_ASSERT(aFormData);
|
||||
MOZ_ASSERT(aHelper);
|
||||
|
||||
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_FORMDATA,
|
||||
aFormData->Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS Closure final
|
||||
{
|
||||
JSStructuredCloneWriter* mWriter;
|
||||
StructuredCloneHelper* mHelper;
|
||||
|
||||
public:
|
||||
Closure(JSStructuredCloneWriter* aWriter,
|
||||
StructuredCloneHelper* aHelper)
|
||||
: mWriter(aWriter),
|
||||
mHelper(aHelper)
|
||||
{ }
|
||||
|
||||
static bool
|
||||
Write(const nsString& aName, bool isFile, const nsString& aValue,
|
||||
File* aFile, void* aClosure)
|
||||
{
|
||||
Closure* closure = static_cast<Closure*>(aClosure);
|
||||
if (!WriteString(closure->mWriter, aName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isFile) {
|
||||
BlobImpl* blobImpl = aFile->Impl();
|
||||
if (!JS_WriteUint32Pair(closure->mWriter, SCTAG_DOM_BLOB,
|
||||
closure->mHelper->BlobImpls().Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
closure->mHelper->BlobImpls().AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t charSize = sizeof(nsString::char_type);
|
||||
if (!JS_WriteUint32Pair(closure->mWriter, 0, aValue.Length()) ||
|
||||
!JS_WriteBytes(closure->mWriter, aValue.get(),
|
||||
aValue.Length() * charSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Closure closure(aWriter, aHelper);
|
||||
return aFormData->ForEach(Closure::Write, &closure);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
JSObject*
|
||||
StructuredCloneHelper::ReadCallback(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
@@ -333,59 +716,25 @@ StructuredCloneHelper::ReadCallback(JSContext* aCx,
|
||||
MOZ_ASSERT(mSupportsCloning);
|
||||
|
||||
if (aTag == SCTAG_DOM_BLOB) {
|
||||
MOZ_ASSERT(aIndex < mBlobImplArray.Length());
|
||||
nsRefPtr<BlobImpl> blobImpl = mBlobImplArray[aIndex];
|
||||
|
||||
// nsRefPtr<File> needs to go out of scope before toObjectOrNull() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
// can GC (because in some cases it can!), and a return statement with a
|
||||
// JSObject* type means that JSObject* is on the stack as a raw pointer
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<Blob> blob = Blob::Create(mParent, blobImpl);
|
||||
if (!ToJSValue(aCx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
return ReadBlob(aCx, aIndex, this);
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_FILELIST) {
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<FileList> fileList = new FileList(mParent);
|
||||
return ReadFileList(aCx, aReader, aIndex, this);
|
||||
}
|
||||
|
||||
// |aIndex| is the number of BlobImpls to use from |offset|.
|
||||
uint32_t tag, offset;
|
||||
if (!JS_ReadUint32Pair(aReader, &tag, &offset)) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(tag == 0);
|
||||
if (aTag == SCTAG_DOM_IMAGEDATA) {
|
||||
return ReadStructuredCloneImageData(aCx, aReader);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aIndex; ++i) {
|
||||
uint32_t index = offset + i;
|
||||
MOZ_ASSERT(index < mBlobImplArray.Length());
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = mBlobImplArray[index];
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
nsRefPtr<File> file = File::Create(mParent, blobImpl);
|
||||
if (!fileList->Append(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ToJSValue(aCx, fileList, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
if (aTag == SCTAG_DOM_FORMDATA) {
|
||||
return ReadFormData(aCx, aReader, aIndex, this);
|
||||
}
|
||||
|
||||
if (aTag == SCTAG_DOM_IMAGEBITMAP) {
|
||||
MOZ_ASSERT(mContext == SameProcessSameThread ||
|
||||
mContext == SameProcessDifferentThread);
|
||||
|
||||
// Get the current global object.
|
||||
// This can be null.
|
||||
nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(mParent);
|
||||
@@ -410,40 +759,37 @@ StructuredCloneHelper::WriteCallback(JSContext* aCx,
|
||||
{
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
if (JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
|
||||
mBlobImplArray.Length())) {
|
||||
mBlobImplArray.AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return WriteBlob(aWriter, blob, this);
|
||||
}
|
||||
}
|
||||
|
||||
// See if this is a FileList object.
|
||||
{
|
||||
FileList* fileList = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FileList, aObj, fileList))) {
|
||||
// A FileList is serialized writing the X number of elements and the offset
|
||||
// from mBlobImplArray. The Read will take X elements from mBlobImplArray
|
||||
// starting from the offset.
|
||||
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_FILELIST,
|
||||
fileList->Length()) ||
|
||||
!JS_WriteUint32Pair(aWriter, 0,
|
||||
mBlobImplArray.Length())) {
|
||||
return false;
|
||||
}
|
||||
return WriteFileList(aWriter, fileList, this);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < fileList->Length(); ++i) {
|
||||
mBlobImplArray.AppendElement(fileList->Item(i)->Impl());
|
||||
}
|
||||
// See if this is a ImageData object.
|
||||
{
|
||||
ImageData* imageData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, aObj, imageData))) {
|
||||
return WriteStructuredCloneImageData(aCx, aWriter, imageData);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
// See if this is a FormData object.
|
||||
{
|
||||
nsFormData* formData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FormData, aObj, formData))) {
|
||||
return WriteFormData(aWriter, formData, this);
|
||||
}
|
||||
}
|
||||
|
||||
// See if this is an ImageBitmap object.
|
||||
{
|
||||
if (mContext == SameProcessSameThread ||
|
||||
mContext == SameProcessDifferentThread) {
|
||||
ImageBitmap* imageBitmap = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, aObj, imageBitmap))) {
|
||||
return ImageBitmap::WriteStructuredClone(aWriter,
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include "nsISupports.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "nsIThread.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
namespace layers {
|
||||
@@ -81,6 +85,11 @@ public:
|
||||
bool Read(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue);
|
||||
|
||||
bool HasBeenWritten() const
|
||||
{
|
||||
return !!mBuffer;
|
||||
}
|
||||
|
||||
uint64_t* BufferData() const
|
||||
{
|
||||
MOZ_ASSERT(mBuffer, "Write() has never been called.");
|
||||
@@ -120,12 +129,24 @@ public:
|
||||
TransferringNotSupported
|
||||
};
|
||||
|
||||
enum ContextSupport
|
||||
{
|
||||
SameProcessSameThread,
|
||||
SameProcessDifferentThread,
|
||||
DifferentProcess
|
||||
};
|
||||
|
||||
// If cloning is supported, this object will clone objects such as Blobs,
|
||||
// FileList, ImageData, etc.
|
||||
// If transferring is supported, we will transfer MessagePorts and in the
|
||||
// future other transferrable objects.
|
||||
// The ContextSupport is useful to know where the cloned/transferred data can
|
||||
// be read and written. Additional checks about the nature of the objects
|
||||
// will be done based on this context value because not all the objects can
|
||||
// be sent between threads or processes.
|
||||
explicit StructuredCloneHelper(CloningSupport aSupportsCloning,
|
||||
TransferringSupport aSupportsTransferring);
|
||||
TransferringSupport aSupportsTransferring,
|
||||
ContextSupport aContextSupport);
|
||||
virtual ~StructuredCloneHelper();
|
||||
|
||||
// Normally you should just use Write() and Read().
|
||||
@@ -150,28 +171,6 @@ public:
|
||||
void MoveBufferDataToArray(FallibleTArray<uint8_t>& aArray,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// If you receive a buffer from IPC, you can use this method to retrieve a
|
||||
// JS::Value. It can happen that you want to pre-populate the array of Blobs
|
||||
// and/or the PortIdentifiers.
|
||||
void ReadFromBuffer(nsISupports* aParent,
|
||||
JSContext* aCx,
|
||||
uint64_t* aBuffer,
|
||||
size_t aBufferLength,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv);
|
||||
|
||||
void ReadFromBuffer(nsISupports* aParent,
|
||||
JSContext* aCx,
|
||||
uint64_t* aBuffer,
|
||||
size_t aBufferLength,
|
||||
uint32_t aAlgorithmVersion,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv);
|
||||
|
||||
// Use this method to free a buffer generated by MoveToBuffer().
|
||||
void FreeBuffer(uint64_t* aBuffer,
|
||||
size_t aBufferLength);
|
||||
|
||||
bool HasClonedDOMObjects() const
|
||||
{
|
||||
return !mBlobImplArray.IsEmpty() ||
|
||||
@@ -184,10 +183,19 @@ public:
|
||||
return mBlobImplArray;
|
||||
}
|
||||
|
||||
const nsTArray<nsRefPtr<MessagePortBase>>& GetTransferredPorts() const
|
||||
nsISupports* ParentDuringRead() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
// This must be called if the transferring has ports generated by Read().
|
||||
// MessagePorts are not thread-safe and they must be retrieved in the thread
|
||||
// where they are created.
|
||||
void TakeTransferredPorts(nsTArray<nsRefPtr<MessagePortBase>>& aPorts)
|
||||
{
|
||||
MOZ_ASSERT(mSupportsTransferring);
|
||||
return mTransferredPorts;
|
||||
MOZ_ASSERT(aPorts.IsEmpty());
|
||||
aPorts.SwapElements(mTransferredPorts);
|
||||
}
|
||||
|
||||
nsTArray<MessagePortIdentifier>& PortIdentifiers()
|
||||
@@ -230,9 +238,32 @@ public:
|
||||
JS::TransferableOwnership aOwnership,
|
||||
void* aContent,
|
||||
uint64_t aExtraData) override;
|
||||
private:
|
||||
protected:
|
||||
// If you receive a buffer from IPC, you can use this method to retrieve a
|
||||
// JS::Value. It can happen that you want to pre-populate the array of Blobs
|
||||
// and/or the PortIdentifiers.
|
||||
void ReadFromBuffer(nsISupports* aParent,
|
||||
JSContext* aCx,
|
||||
uint64_t* aBuffer,
|
||||
size_t aBufferLength,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv);
|
||||
|
||||
void ReadFromBuffer(nsISupports* aParent,
|
||||
JSContext* aCx,
|
||||
uint64_t* aBuffer,
|
||||
size_t aBufferLength,
|
||||
uint32_t aAlgorithmVersion,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv);
|
||||
|
||||
// Use this method to free a buffer generated by MoveToBuffer().
|
||||
void FreeBuffer(uint64_t* aBuffer,
|
||||
size_t aBufferLength);
|
||||
|
||||
bool mSupportsCloning;
|
||||
bool mSupportsTransferring;
|
||||
ContextSupport mContext;
|
||||
|
||||
// Useful for the structured clone algorithm:
|
||||
|
||||
@@ -256,6 +287,10 @@ private:
|
||||
// are able to reconnect the new transferred ports with the other
|
||||
// MessageChannel ports.
|
||||
nsTArray<MessagePortIdentifier> mPortIdentifiers;
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIThread> mCreationThread;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
|
||||
@@ -46,6 +46,8 @@ enum StructuredCloneTags {
|
||||
|
||||
SCTAG_DOM_RTC_CERTIFICATE,
|
||||
|
||||
SCTAG_DOM_FORMDATA,
|
||||
|
||||
SCTAG_DOM_MAX
|
||||
};
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "mozilla/layers/CompositorChild.h"
|
||||
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPopupManager.h"
|
||||
@@ -374,7 +374,19 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
||||
}
|
||||
}
|
||||
|
||||
loadInfo->SetReferrerPolicy(mOwnerContent->OwnerDoc()->GetReferrerPolicy());
|
||||
// get referrer policy for this iframe:
|
||||
// first load document wide policy, then
|
||||
// load iframe referrer attribute if enabled in preferences
|
||||
// per element referrer overrules document wide referrer if enabled
|
||||
net::ReferrerPolicy referrerPolicy = mOwnerContent->OwnerDoc()->GetReferrerPolicy();
|
||||
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
|
||||
if (iframe) {
|
||||
net::ReferrerPolicy iframeReferrerPolicy = iframe->GetReferrerPolicy();
|
||||
if (iframeReferrerPolicy != net::RP_Unset) {
|
||||
referrerPolicy = iframeReferrerPolicy;
|
||||
}
|
||||
}
|
||||
loadInfo->SetReferrerPolicy(referrerPolicy);
|
||||
|
||||
// Default flags:
|
||||
int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
|
||||
@@ -2367,7 +2379,7 @@ public:
|
||||
nsAsyncMessageToChild(JSContext* aCx,
|
||||
nsFrameLoader* aFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
@@ -2394,7 +2406,7 @@ public:
|
||||
bool
|
||||
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
@@ -2744,6 +2756,10 @@ nsFrameLoader::RequestNotifyLayerTreeReady()
|
||||
return mRemoteBrowser->RequestNotifyLayerTreeReady() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!mOwnerContent) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsRefPtr<AsyncEventDispatcher> event =
|
||||
new AsyncEventDispatcher(mOwnerContent,
|
||||
NS_LITERAL_STRING("MozLayerTreeReady"),
|
||||
@@ -2760,6 +2776,10 @@ nsFrameLoader::RequestNotifyLayerTreeCleared()
|
||||
return mRemoteBrowser->RequestNotifyLayerTreeCleared() ? NS_OK : NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!mOwnerContent) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsRefPtr<AsyncEventDispatcher> event =
|
||||
new AsyncEventDispatcher(mOwnerContent,
|
||||
NS_LITERAL_STRING("MozLayerTreeCleared"),
|
||||
|
||||
@@ -41,9 +41,12 @@ namespace dom {
|
||||
class ContentParent;
|
||||
class PBrowserParent;
|
||||
class TabParent;
|
||||
struct StructuredCloneData;
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
class StructuredCloneData;
|
||||
} // namespace ipc
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameParent;
|
||||
} // namespace layout
|
||||
@@ -86,7 +89,7 @@ public:
|
||||
bool aRunInGlobalScope) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
mozilla::dom::ipc::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool CheckPermission(const nsAString& aPermission) override;
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
#include "mozilla/dom/ProcessGlobal.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/dom/DOMStringList.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "nsPrintfCString.h"
|
||||
@@ -47,6 +47,10 @@
|
||||
#include "nsQueryObject.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
@@ -137,6 +141,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameMessageManager)
|
||||
tmp->mListeners.EnumerateRead(CycleCollectorTraverseListeners,
|
||||
static_cast<void*>(&cb));
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
@@ -151,6 +156,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFrameMessageManager)
|
||||
Disconnect(false);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentManager)
|
||||
tmp->mInitialProcessData.setNull();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
@@ -270,13 +276,14 @@ struct DataBlobs<Child>
|
||||
template<ActorFlavorEnum Flavor>
|
||||
static bool
|
||||
BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType* aManager,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||
buffer.data = aData.mData;
|
||||
buffer.dataLength = aData.mDataLength;
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = aData.mClosure.mBlobImpls;
|
||||
buffer.data = aData.Data();
|
||||
buffer.dataLength = aData.DataLength();
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = aData.BlobImpls();
|
||||
|
||||
if (!blobImpls.IsEmpty()) {
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
InfallibleTArray<ProtocolType*>& blobList = DataBlobs<Flavor>::Blobs(aClonedData);
|
||||
@@ -296,7 +303,7 @@ BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType*
|
||||
|
||||
bool
|
||||
MessageManagerCallback::BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Parent>(aParent, aData, aClonedData);
|
||||
@@ -304,25 +311,26 @@ MessageManagerCallback::BuildClonedMessageDataForParent(nsIContentParent* aParen
|
||||
|
||||
bool
|
||||
MessageManagerCallback::BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Child>(aChild, aData, aClonedData);
|
||||
}
|
||||
|
||||
template<ActorFlavorEnum Flavor>
|
||||
static StructuredCloneData
|
||||
UnpackClonedMessageData(const ClonedMessageData& aData)
|
||||
static void
|
||||
UnpackClonedMessageData(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
const SerializedStructuredCloneBuffer& buffer = aData.data();
|
||||
const SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aData);
|
||||
StructuredCloneData cloneData;
|
||||
cloneData.mData = buffer.data;
|
||||
cloneData.mDataLength = buffer.dataLength;
|
||||
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aClonedData);
|
||||
|
||||
aData.UseExternalData(buffer.data, buffer.dataLength);
|
||||
|
||||
if (!blobs.IsEmpty()) {
|
||||
uint32_t length = blobs.Length();
|
||||
cloneData.mClosure.mBlobImpls.SetCapacity(length);
|
||||
aData.BlobImpls().SetCapacity(length);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
auto* blob =
|
||||
static_cast<typename BlobTraits<Flavor>::BlobType*>(blobs[i]);
|
||||
@@ -331,22 +339,23 @@ UnpackClonedMessageData(const ClonedMessageData& aData)
|
||||
nsRefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
cloneData.mClosure.mBlobImpls.AppendElement(blobImpl);
|
||||
aData.BlobImpls().AppendElement(blobImpl);
|
||||
}
|
||||
}
|
||||
return cloneData;
|
||||
}
|
||||
|
||||
StructuredCloneData
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForParent(const ClonedMessageData& aData)
|
||||
void
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForParent(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
return UnpackClonedMessageData<Parent>(aData);
|
||||
UnpackClonedMessageData<Parent>(aClonedData, aData);
|
||||
}
|
||||
|
||||
StructuredCloneData
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aData)
|
||||
void
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
return UnpackClonedMessageData<Child>(aData);
|
||||
UnpackClonedMessageData<Child>(aClonedData, aData);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -509,16 +518,9 @@ nsFrameMessageManager::LoadScript(const nsAString& aURL,
|
||||
bool aRunInGlobalScope)
|
||||
{
|
||||
if (aAllowDelayedLoad) {
|
||||
if (IsGlobal() || IsBroadcaster()) {
|
||||
// Cache for future windows or frames
|
||||
mPendingScripts.AppendElement(aURL);
|
||||
mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
|
||||
} else if (!mCallback) {
|
||||
// We're frame message manager, which isn't connected yet.
|
||||
mPendingScripts.AppendElement(aURL);
|
||||
mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
|
||||
return NS_OK;
|
||||
}
|
||||
// Cache for future windows or frames
|
||||
mPendingScripts.AppendElement(aURL);
|
||||
mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
|
||||
}
|
||||
|
||||
if (mCallback) {
|
||||
@@ -643,15 +645,18 @@ JSONCreator(const char16_t* aBuf, uint32_t aLen, void* aData)
|
||||
|
||||
static bool
|
||||
GetParamsForMessage(JSContext* aCx,
|
||||
const JS::Value& aData,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
StructuredCloneClosure& aClosure)
|
||||
const JS::Value& aValue,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
// First try to use structured clone on the whole thing.
|
||||
JS::RootedValue v(aCx, aData);
|
||||
if (WriteStructuredClone(aCx, v, aBuffer, aClosure)) {
|
||||
JS::RootedValue v(aCx, aValue);
|
||||
ErrorResult rv;
|
||||
aData.Write(aCx, v, rv);
|
||||
if (!rv.Failed()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
rv.SuppressException();
|
||||
JS_ClearPendingException(aCx);
|
||||
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
@@ -679,9 +684,14 @@ GetParamsForMessage(JSContext* aCx,
|
||||
NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const char16_t*>(json.get()),
|
||||
json.Length(), &val), false);
|
||||
|
||||
return WriteStructuredClone(aCx, val, aBuffer, aClosure);
|
||||
}
|
||||
aData.Write(aCx, val, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// nsISyncMessageSender
|
||||
|
||||
@@ -736,29 +746,25 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||
}
|
||||
|
||||
StructuredCloneData data;
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (aArgc >= 2 &&
|
||||
!GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
|
||||
if (aArgc >= 2 && !GetParamsForMessage(aCx, aJSON, data)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
data.mData = buffer.data();
|
||||
data.mDataLength = buffer.nbytes();
|
||||
|
||||
JS::Rooted<JSObject*> objects(aCx);
|
||||
if (aArgc >= 3 && aObjects.isObject()) {
|
||||
objects = &aObjects.toObject();
|
||||
}
|
||||
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer> retval;
|
||||
nsTArray<StructuredCloneData> retval;
|
||||
|
||||
sSendingSyncMessage |= aIsSync;
|
||||
bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects,
|
||||
bool ok = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects,
|
||||
aPrincipal, &retval, aIsSync);
|
||||
if (aIsSync) {
|
||||
sSendingSyncMessage = false;
|
||||
}
|
||||
|
||||
if (!rv) {
|
||||
if (!ok) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -768,8 +774,9 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
JS::Rooted<JS::Value> ret(aCx);
|
||||
if (!JS_ReadStructuredClone(aCx, retval[i].data, retval[i].dataLength,
|
||||
JS_STRUCTURED_CLONE_VERSION, &ret, nullptr, nullptr)) {
|
||||
ErrorResult rv;
|
||||
retval[i].Read(aCx, &ret, rv);
|
||||
if (rv.Failed()) {
|
||||
MOZ_ASSERT(false, "Unable to read structured clone in SendMessage");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@@ -785,7 +792,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
||||
nsresult
|
||||
nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
@@ -798,7 +805,10 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
||||
if (!mCallback) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@@ -814,10 +824,7 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||
uint8_t aArgc)
|
||||
{
|
||||
StructuredCloneData data;
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
|
||||
if (aArgc >= 2 &&
|
||||
!GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
|
||||
if (aArgc >= 2 && !GetParamsForMessage(aCx, aJSON, data)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
@@ -826,9 +833,6 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||
objects = &aObjects.toObject();
|
||||
}
|
||||
|
||||
data.mData = buffer.data();
|
||||
data.mDataLength = buffer.nbytes();
|
||||
|
||||
return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects,
|
||||
aPrincipal);
|
||||
}
|
||||
@@ -1058,10 +1062,10 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
nsIFrameLoader* aTargetFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
return ReceiveMessage(aTarget, aTargetFrameLoader, mClosed, aMessage, aIsSync,
|
||||
aCloneData, aCpows, aPrincipal, aRetVal);
|
||||
@@ -1073,10 +1077,10 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
bool aTargetClosed,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
|
||||
mListeners.Get(aMessage);
|
||||
@@ -1157,10 +1161,14 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
JS::Rooted<JS::Value> cpowsv(cx, JS::ObjectValue(*cpows));
|
||||
|
||||
JS::Rooted<JS::Value> json(cx, JS::NullValue());
|
||||
if (aCloneData && aCloneData->mDataLength &&
|
||||
!ReadStructuredClone(cx, *aCloneData, &json)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_OK;
|
||||
if (aCloneData && aCloneData->DataLength()) {
|
||||
ErrorResult rv;
|
||||
aCloneData->Read(cx, &json, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
JS::Rooted<JSString*> jsMessage(cx,
|
||||
JS_NewUCStringCopyN(cx,
|
||||
@@ -1251,8 +1259,11 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
continue;
|
||||
}
|
||||
if (aRetVal) {
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (!buffer.write(cx, rval)) {
|
||||
ErrorResult rv;
|
||||
StructuredCloneData* data = aRetVal->AppendElement();
|
||||
data->Write(cx, rval, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
aRetVal->RemoveElementAt(aRetVal->Length() - 1);
|
||||
nsString msg = aMessage + NS_LITERAL_STRING(": message reply cannot be cloned. Are you trying to send an XPCOM object?");
|
||||
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
@@ -1266,9 +1277,6 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
JS_ClearPendingException(cx);
|
||||
continue;
|
||||
}
|
||||
|
||||
OwningSerializedStructuredCloneBuffer* data = aRetVal->AppendElement();
|
||||
buffer.steal(&data->data, &data->dataLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1423,6 +1431,14 @@ nsFrameMessageManager::GetInitialProcessData(JSContext* aCx, JS::MutableHandleVa
|
||||
init.setObject(*obj);
|
||||
}
|
||||
|
||||
if (!mChrome && XRE_IsParentProcess()) {
|
||||
// This is the cpmm in the parent process. We should use the same object as the ppmm.
|
||||
nsCOMPtr<nsIGlobalProcessScriptLoader> ppmm =
|
||||
do_GetService("@mozilla.org/parentprocessmessagemanager;1");
|
||||
ppmm->GetInitialProcessData(aCx, &init);
|
||||
mInitialProcessData = init;
|
||||
}
|
||||
|
||||
if (!JS_WrapValue(aCx, &init)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -1736,7 +1752,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
|
||||
NS_NewChannel(getter_AddRefs(channel),
|
||||
uri,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER);
|
||||
|
||||
if (!channel) {
|
||||
@@ -1744,7 +1760,8 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> input;
|
||||
channel->Open(getter_AddRefs(input));
|
||||
rv = channel->Open2(getter_AddRefs(input));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
nsString dataString;
|
||||
char16_t* dataStringBuf = nullptr;
|
||||
size_t dataStringLength = 0;
|
||||
@@ -1871,7 +1888,7 @@ class nsAsyncMessageToSameProcessChild : public nsSameProcessAsyncMessageBase,
|
||||
public:
|
||||
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
@@ -1913,7 +1930,7 @@ public:
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
@@ -1967,10 +1984,10 @@ public:
|
||||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
@@ -1996,7 +2013,7 @@ public:
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
@@ -2026,7 +2043,7 @@ class nsAsyncMessageToSameProcessParent : public nsSameProcessAsyncMessageBase,
|
||||
public:
|
||||
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
@@ -2058,10 +2075,10 @@ public:
|
||||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override
|
||||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
@@ -2078,7 +2095,7 @@ public:
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
@@ -2155,7 +2172,6 @@ NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
|
||||
NS_ENSURE_TRUE(global->Init(), NS_ERROR_UNEXPECTED);
|
||||
global.forget(aResult);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
@@ -2185,7 +2201,7 @@ nsFrameMessageManager::MarkForCC()
|
||||
|
||||
nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
@@ -2193,10 +2209,13 @@ nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
mCpows(aCx, aCpows),
|
||||
mPrincipal(aPrincipal)
|
||||
{
|
||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
if (!mData.Copy(aData)) {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncMessageOOM"),
|
||||
NS_ConvertUTF16toUTF8(aMessage));
|
||||
#endif
|
||||
NS_ABORT_OOM(aData.DataLength());
|
||||
}
|
||||
mClosure = aData.mClosure;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2205,15 +2224,10 @@ nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
|
||||
nsFrameMessageManager* aManager)
|
||||
{
|
||||
if (aManager) {
|
||||
StructuredCloneData data;
|
||||
data.mData = mData.data();
|
||||
data.mDataLength = mData.nbytes();
|
||||
data.mClosure = mClosure;
|
||||
|
||||
SameProcessCpowHolder cpows(mRuntime, mCpows);
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = aManager;
|
||||
mm->ReceiveMessage(aTarget, aTargetFrameLoader, mMessage, false, &data, &cpows,
|
||||
mPrincipal, nullptr);
|
||||
mm->ReceiveMessage(aTarget, aTargetFrameLoader, mMessage, false, &mData,
|
||||
&cpows, mPrincipal, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,15 +28,12 @@
|
||||
#include "js/RootingAPI.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/jsipc/CpowHolder.h"
|
||||
|
||||
class nsIFrameLoader;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct OwningSerializedStructuredCloneBuffer;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class nsIContentParent;
|
||||
@@ -57,9 +54,6 @@ enum MessageManagerFlags {
|
||||
|
||||
class MessageManagerCallback
|
||||
{
|
||||
protected:
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
|
||||
public:
|
||||
virtual ~MessageManagerCallback() {}
|
||||
|
||||
@@ -70,10 +64,10 @@ public:
|
||||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
return true;
|
||||
@@ -81,7 +75,7 @@ public:
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
@@ -116,15 +110,18 @@ public:
|
||||
|
||||
protected:
|
||||
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData);
|
||||
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData);
|
||||
};
|
||||
|
||||
StructuredCloneData UnpackClonedMessageDataForParent(const ClonedMessageData& aData);
|
||||
StructuredCloneData UnpackClonedMessageDataForChild(const ClonedMessageData& aData);
|
||||
void UnpackClonedMessageDataForParent(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData);
|
||||
|
||||
void UnpackClonedMessageDataForChild(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData);
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace dom
|
||||
@@ -166,8 +163,7 @@ class nsFrameMessageManager final : public nsIContentFrameMessageManager,
|
||||
public nsIProcessChecker
|
||||
{
|
||||
friend class mozilla::dom::MessageManagerReporter;
|
||||
typedef mozilla::dom::StructuredCloneData StructuredCloneData;
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
public:
|
||||
nsFrameMessageManager(mozilla::dom::ipc::MessageManagerCallback* aCallback,
|
||||
nsFrameMessageManager* aParentManager,
|
||||
@@ -196,9 +192,9 @@ public:
|
||||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync, const StructuredCloneData* aCloneData,
|
||||
bool aIsSync, StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal);
|
||||
nsTArray<StructuredCloneData>* aRetVal);
|
||||
|
||||
void AddChildManager(nsFrameMessageManager* aManager);
|
||||
void RemoveChildManager(nsFrameMessageManager* aManager)
|
||||
@@ -223,7 +219,7 @@ public:
|
||||
uint8_t aArgc);
|
||||
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
void RemoveFromParent();
|
||||
@@ -264,9 +260,9 @@ private:
|
||||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
bool aTargetClosed, const nsAString& aMessage,
|
||||
bool aIsSync, const StructuredCloneData* aCloneData,
|
||||
bool aIsSync, StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal);
|
||||
nsTArray<StructuredCloneData>* aRetVal);
|
||||
|
||||
NS_IMETHOD LoadScript(const nsAString& aURL,
|
||||
bool aAllowDelayedLoad,
|
||||
@@ -291,7 +287,7 @@ protected:
|
||||
bool mDisconnected;
|
||||
mozilla::dom::ipc::MessageManagerCallback* mCallback;
|
||||
nsAutoPtr<mozilla::dom::ipc::MessageManagerCallback> mOwnedCallback;
|
||||
nsFrameMessageManager* mParentManager;
|
||||
nsRefPtr<nsFrameMessageManager> mParentManager;
|
||||
nsTArray<nsString> mPendingScripts;
|
||||
nsTArray<bool> mPendingScriptsGlobalStates;
|
||||
JS::Heap<JS::Value> mInitialProcessData;
|
||||
@@ -329,14 +325,12 @@ private:
|
||||
*/
|
||||
class nsSameProcessAsyncMessageBase
|
||||
{
|
||||
typedef mozilla::dom::StructuredCloneClosure StructuredCloneClosure;
|
||||
|
||||
public:
|
||||
typedef mozilla::dom::StructuredCloneData StructuredCloneData;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
|
||||
nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
@@ -348,8 +342,7 @@ private:
|
||||
|
||||
JSRuntime* mRuntime;
|
||||
nsString mMessage;
|
||||
JSAutoStructuredCloneBuffer mData;
|
||||
StructuredCloneClosure mClosure;
|
||||
StructuredCloneData mData;
|
||||
JS::PersistentRooted<JSObject*> mCpows;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
@@ -18,21 +18,18 @@
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "js/StructuredClone.h"
|
||||
|
||||
using mozilla::dom::StructuredCloneData;
|
||||
using mozilla::dom::StructuredCloneClosure;
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
|
||||
bool
|
||||
nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
@@ -55,7 +52,7 @@ public:
|
||||
nsAsyncMessageToParent(JSContext* aCx,
|
||||
nsInProcessTabChildGlobal* aTabChild,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal),
|
||||
@@ -75,7 +72,7 @@ public:
|
||||
bool
|
||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ class nsInProcessTabChildGlobal : public mozilla::DOMEventTargetHelper,
|
||||
public nsSupportsWeakReference,
|
||||
public mozilla::dom::ipc::MessageManagerCallback
|
||||
{
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
|
||||
public:
|
||||
nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
|
||||
@@ -83,14 +83,14 @@ public:
|
||||
*/
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "xpcpublic.h"
|
||||
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@@ -31,23 +30,19 @@ NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsStructuredCloneContainer::nsStructuredCloneContainer()
|
||||
: StructuredCloneHelper(CloningSupported, TransferringNotSupported)
|
||||
, mState(eNotInitialized) , mData(nullptr), mSize(0), mVersion(0)
|
||||
: mVersion(0)
|
||||
{
|
||||
}
|
||||
|
||||
nsStructuredCloneContainer::~nsStructuredCloneContainer()
|
||||
{
|
||||
if (mData) {
|
||||
free(mData);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
|
||||
JSContext* aCx)
|
||||
{
|
||||
if (mState != eNotInitialized) {
|
||||
if (DataLength()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -57,7 +52,7 @@ nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
mState = eInitializedFromJSVal;
|
||||
mVersion = JS_STRUCTURED_CLONE_VERSION;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -66,7 +61,7 @@ nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
|
||||
uint32_t aFormatVersion,
|
||||
JSContext* aCx)
|
||||
{
|
||||
if (mState != eNotInitialized) {
|
||||
if (DataLength()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -76,15 +71,11 @@ nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
|
||||
nsresult rv = Base64Decode(data, binaryData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Copy the string's data into our own buffer.
|
||||
mData = (uint64_t*) malloc(binaryData.Length());
|
||||
NS_ENSURE_STATE(mData);
|
||||
memcpy(mData, binaryData.get(), binaryData.Length());
|
||||
if (!CopyExternalData(binaryData.get(), binaryData.Length())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mSize = binaryData.Length();
|
||||
mVersion = aFormatVersion;
|
||||
|
||||
mState = eInitializedFromBase64;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -95,21 +86,10 @@ nsStructuredCloneContainer::DeserializeToJsval(JSContext* aCx,
|
||||
aValue.setNull();
|
||||
JS::Rooted<JS::Value> jsStateObj(aCx);
|
||||
|
||||
if (mState == eInitializedFromJSVal) {
|
||||
ErrorResult rv;
|
||||
Read(nullptr, aCx, &jsStateObj, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mState == eInitializedFromBase64);
|
||||
MOZ_ASSERT(mData);
|
||||
|
||||
ErrorResult rv;
|
||||
ReadFromBuffer(nullptr, aCx, mData, mSize, mVersion, &jsStateObj, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
ErrorResult rv;
|
||||
Read(aCx, &jsStateObj, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
aValue.set(jsStateObj);
|
||||
@@ -123,7 +103,7 @@ nsStructuredCloneContainer::DeserializeToVariant(JSContext* aCx,
|
||||
NS_ENSURE_ARG_POINTER(aData);
|
||||
*aData = nullptr;
|
||||
|
||||
if (mState == eNotInitialized) {
|
||||
if (!DataLength()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -150,29 +130,15 @@ nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
|
||||
{
|
||||
aOut.Truncate();
|
||||
|
||||
if (mState == eNotInitialized) {
|
||||
if (!DataLength()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint64_t* data;
|
||||
size_t size;
|
||||
|
||||
if (mState == eInitializedFromJSVal) {
|
||||
if (HasClonedDOMObjects()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
data = BufferData();
|
||||
size = BufferSize();
|
||||
} else {
|
||||
MOZ_ASSERT(mState == eInitializedFromBase64);
|
||||
MOZ_ASSERT(mData);
|
||||
|
||||
data = mData;
|
||||
size = mSize;
|
||||
if (HasClonedDOMObjects()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoCString binaryData(reinterpret_cast<char*>(data), size);
|
||||
nsAutoCString binaryData(reinterpret_cast<char*>(Data()), DataLength());
|
||||
nsAutoCString base64Data;
|
||||
nsresult rv = Base64Encode(binaryData, base64Data);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@@ -188,22 +154,11 @@ nsStructuredCloneContainer::GetSerializedNBytes(uint64_t* aSize)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSize);
|
||||
|
||||
if (mState == eNotInitialized) {
|
||||
if (!DataLength()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mState == eInitializedFromJSVal) {
|
||||
*aSize = BufferSize();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eInitializedFromBase64);
|
||||
|
||||
// mSize is a size_t, while aSize is a uint64_t. We rely on an implicit cast
|
||||
// here so that we'll get a compile error if a size_t-to-uint64_t cast is
|
||||
// narrowing.
|
||||
*aSize = mSize;
|
||||
|
||||
*aSize = DataLength();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -212,16 +167,10 @@ nsStructuredCloneContainer::GetFormatVersion(uint32_t* aFormatVersion)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFormatVersion);
|
||||
|
||||
if (mState == eNotInitialized) {
|
||||
if (!DataLength()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mState == eInitializedFromJSVal) {
|
||||
*aFormatVersion = JS_STRUCTURED_CLONE_VERSION;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eInitializedFromBase64);
|
||||
*aFormatVersion = mVersion;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
|
||||
#define NS_STRUCTUREDCLONECONTAINER_CONTRACTID \
|
||||
"@mozilla.org/docshell/structured-clone-container;1"
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
class nsStructuredCloneContainer final
|
||||
: public nsIStructuredCloneContainer
|
||||
, public mozilla::dom::StructuredCloneHelper
|
||||
, public mozilla::dom::ipc::StructuredCloneData
|
||||
{
|
||||
public:
|
||||
nsStructuredCloneContainer();
|
||||
@@ -34,16 +34,6 @@ class nsStructuredCloneContainer final
|
||||
private:
|
||||
~nsStructuredCloneContainer();
|
||||
|
||||
enum {
|
||||
eNotInitialized = 0,
|
||||
eInitializedFromJSVal,
|
||||
eInitializedFromBase64,
|
||||
} mState;
|
||||
|
||||
uint64_t* mData;
|
||||
|
||||
// This needs to be size_t rather than a PR-type so it matches the JS API.
|
||||
size_t mSize;
|
||||
uint32_t mVersion;
|
||||
};
|
||||
|
||||
|
||||
@@ -812,4 +812,5 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g'
|
||||
[test_window_element_enumeration.html]
|
||||
[test_referrer_redirect.html]
|
||||
[test_postMessages.html]
|
||||
support-files = worker_postMessages.js
|
||||
[test_window_proto.html]
|
||||
|
||||
@@ -278,6 +278,51 @@ function test_windowToIframeURL(url) {
|
||||
document.body.appendChild(ifr);
|
||||
}
|
||||
|
||||
// PostMessage for Workers
|
||||
function test_workers() {
|
||||
info("Testing Workers");
|
||||
|
||||
var resolve;
|
||||
|
||||
var w = new Worker('worker_postMessages.js');
|
||||
w.postMessage('workers');
|
||||
w.onmessage = function(e) {
|
||||
is(e.data, 'ok', "Worker ready!");
|
||||
|
||||
w.onmessage = function(e) {
|
||||
if (!resolve) {
|
||||
ok(false, "Unexpected message!");
|
||||
return;
|
||||
}
|
||||
|
||||
let tmp = resolve;
|
||||
resolve = null;
|
||||
tmp({ data: e.data, ports: e.ports });
|
||||
}
|
||||
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
try {
|
||||
w.postMessage(what, ports);
|
||||
} catch(e) {
|
||||
resolve = null;
|
||||
rr();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
finished: function() {
|
||||
onmessage = null;
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// PostMessage for BroadcastChannel
|
||||
function test_broadcastChannel() {
|
||||
info("Testing broadcastChannel");
|
||||
@@ -320,6 +365,52 @@ function test_broadcastChannel() {
|
||||
});
|
||||
}
|
||||
|
||||
// PostMessage for BroadcastChannel in workers
|
||||
function test_broadcastChannel_inWorkers() {
|
||||
info("Testing broadcastChannel in Workers");
|
||||
|
||||
var bc = new BroadcastChannel('postMessagesTest_inWorkers');
|
||||
var resolve;
|
||||
|
||||
var w = new Worker('worker_postMessages.js');
|
||||
w.postMessage('broadcastChannel');
|
||||
w.onmessage = function(e) {
|
||||
is(e.data, 'ok', "Worker ready!");
|
||||
|
||||
w.onmessage = function(e) {
|
||||
if (!resolve) {
|
||||
ok(false, "Unexpected message!");
|
||||
return;
|
||||
}
|
||||
|
||||
let tmp = resolve;
|
||||
resolve = null;
|
||||
tmp({ data: e.data, ports: e.ports });
|
||||
}
|
||||
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: false,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
if (ports.length) {
|
||||
rr();
|
||||
return;
|
||||
}
|
||||
|
||||
resolve = r;
|
||||
bc.postMessage(what);
|
||||
});
|
||||
},
|
||||
|
||||
finished: function() {
|
||||
onmessage = null;
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// PostMessage for MessagePort
|
||||
function test_messagePort() {
|
||||
info("Testing messagePort");
|
||||
@@ -360,6 +451,52 @@ function test_messagePort() {
|
||||
});
|
||||
}
|
||||
|
||||
// PostMessage for MessagePort in Workers
|
||||
function test_messagePort_inWorkers() {
|
||||
info("Testing messagePort in workers");
|
||||
|
||||
var mc = new MessageChannel();
|
||||
var resolve;
|
||||
|
||||
var w = new Worker('worker_postMessages.js');
|
||||
w.postMessage('messagePort', [ mc.port2 ]);
|
||||
w.onmessage = function(e) {
|
||||
is(e.data, 'ok', "Worker ready!");
|
||||
|
||||
w.onmessage = function(e) {
|
||||
if (!resolve) {
|
||||
ok(false, "Unexpected message!");
|
||||
return;
|
||||
}
|
||||
|
||||
let tmp = resolve;
|
||||
resolve = null;
|
||||
tmp({ data: e.data, ports: e.ports });
|
||||
}
|
||||
|
||||
runTests({
|
||||
clonableObjects: true,
|
||||
transferableObjects: true,
|
||||
send: function(what, ports) {
|
||||
return new Promise(function(r, rr) {
|
||||
resolve = r;
|
||||
try {
|
||||
mc.port1.postMessage(what, ports);
|
||||
} catch(e) {
|
||||
resolve = null;
|
||||
rr();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
finished: function() {
|
||||
onmessage = null;
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var tests = [
|
||||
create_fileList,
|
||||
|
||||
@@ -367,11 +504,13 @@ var tests = [
|
||||
test_windowToIframe,
|
||||
test_windowToCrossOriginIframe,
|
||||
|
||||
test_workers,
|
||||
|
||||
test_broadcastChannel,
|
||||
// TODO BroadcastChannel in worker
|
||||
test_broadcastChannel_inWorkers,
|
||||
|
||||
test_messagePort,
|
||||
// TODO MessagePort in worker
|
||||
test_messagePort_inWorkers,
|
||||
];
|
||||
|
||||
function next() {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
function test_workers() {
|
||||
onmessage = function(e) {
|
||||
postMessage(e.data, e.ports);
|
||||
}
|
||||
}
|
||||
|
||||
function test_broadcastChannel() {
|
||||
var bc = new BroadcastChannel('postMessagesTest_inWorkers');
|
||||
bc.onmessage = function(e) {
|
||||
postMessage(e.data);
|
||||
}
|
||||
}
|
||||
|
||||
function test_messagePort(port) {
|
||||
port.onmessage = function(e) {
|
||||
postMessage(e.data, e.ports);
|
||||
}
|
||||
}
|
||||
|
||||
onmessage = function(e) {
|
||||
if (e.data == 'workers') {
|
||||
test_workers();
|
||||
postMessage('ok');
|
||||
} else if (e.data == 'broadcastChannel') {
|
||||
test_broadcastChannel();
|
||||
postMessage('ok');
|
||||
} else if (e.data == 'messagePort') {
|
||||
test_messagePort(e.ports[0]);
|
||||
postMessage('ok');
|
||||
} else {
|
||||
postMessage('ko');
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,12 @@ BluetoothGattClientInterface::BluetoothGattClientInterface()
|
||||
BluetoothGattClientInterface::~BluetoothGattClientInterface()
|
||||
{ }
|
||||
|
||||
BluetoothGattServerInterface::BluetoothGattServerInterface()
|
||||
{ }
|
||||
|
||||
BluetoothGattServerInterface::~BluetoothGattServerInterface()
|
||||
{ }
|
||||
|
||||
BluetoothGattInterface::BluetoothGattInterface()
|
||||
{ }
|
||||
|
||||
|
||||
@@ -687,7 +687,8 @@ public:
|
||||
const nsAString& aBdAddr,
|
||||
int aAttributeHandle,
|
||||
int aOffset,
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
int aLength,
|
||||
const uint8_t* aValue,
|
||||
bool aNeedResponse,
|
||||
bool aIsPrepareWrite)
|
||||
{ }
|
||||
@@ -788,7 +789,7 @@ public:
|
||||
virtual void DeregisterNotification() { }
|
||||
|
||||
virtual void ReadRemoteRssi() { }
|
||||
virtual void GetDeviceType() { }
|
||||
virtual void GetDeviceType(BluetoothTypeOfDevice type) { }
|
||||
virtual void SetAdvData() { }
|
||||
virtual void TestCommand() { }
|
||||
|
||||
@@ -796,16 +797,11 @@ protected:
|
||||
virtual ~BluetoothGattClientResultHandler() { }
|
||||
};
|
||||
|
||||
class BluetoothGattServerResultHandler
|
||||
class BluetoothGattServerResultHandler : public BluetoothGattResultHandler
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothGattServerResultHandler)
|
||||
|
||||
virtual void OnError(BluetoothStatus aStatus)
|
||||
{
|
||||
BT_WARNING("Received error code %d", (int)aStatus);
|
||||
}
|
||||
|
||||
virtual void RegisterServer() { }
|
||||
virtual void UnregisterServer() { }
|
||||
|
||||
@@ -1048,6 +1044,7 @@ public:
|
||||
virtual void Cleanup(BluetoothGattResultHandler* aRes) = 0;
|
||||
|
||||
virtual BluetoothGattClientInterface* GetBluetoothGattClientInterface() = 0;
|
||||
virtual BluetoothGattServerInterface* GetBluetoothGattServerInterface() = 0;
|
||||
|
||||
protected:
|
||||
BluetoothGattInterface();
|
||||
|
||||
@@ -687,6 +687,185 @@ private:
|
||||
Tin5 mArg5;
|
||||
};
|
||||
|
||||
template <typename ObjectWrapper, typename Res,
|
||||
typename Tin1, typename Tin2, typename Tin3,
|
||||
typename Tin4, typename Tin5, typename Tin6,
|
||||
typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
|
||||
typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6>
|
||||
class BluetoothNotificationRunnable6 : public nsRunnable
|
||||
{
|
||||
public:
|
||||
typedef typename ObjectWrapper::ObjectType ObjectType;
|
||||
typedef BluetoothNotificationRunnable6<ObjectWrapper, Res,
|
||||
Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6>
|
||||
SelfType;
|
||||
|
||||
template <typename InitOp>
|
||||
static already_AddRefed<SelfType> Create(
|
||||
Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6),
|
||||
const InitOp& aInitOp)
|
||||
{
|
||||
nsRefPtr<SelfType> runnable(new SelfType(aMethod));
|
||||
if (NS_FAILED(runnable->Init(aInitOp))) {
|
||||
return nullptr;
|
||||
}
|
||||
return runnable.forget();
|
||||
}
|
||||
|
||||
template <typename InitOp>
|
||||
static void
|
||||
Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6),
|
||||
const InitOp& aInitOp)
|
||||
{
|
||||
nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
|
||||
if (!runnable) {
|
||||
BT_WARNING("BluetoothNotificationRunnable6::Create failed");
|
||||
return;
|
||||
}
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ObjectType* obj = ObjectWrapper::GetInstance();
|
||||
if (!obj) {
|
||||
BT_WARNING("Notification handler not initialized");
|
||||
} else {
|
||||
((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothNotificationRunnable6(
|
||||
Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6))
|
||||
: mMethod(aMethod)
|
||||
{
|
||||
MOZ_ASSERT(mMethod);
|
||||
}
|
||||
|
||||
template<typename InitOp>
|
||||
nsresult
|
||||
Init(const InitOp& aInitOp)
|
||||
{
|
||||
nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
|
||||
Tin1 mArg1;
|
||||
Tin2 mArg2;
|
||||
Tin3 mArg3;
|
||||
Tin4 mArg4;
|
||||
Tin5 mArg5;
|
||||
Tin6 mArg6;
|
||||
};
|
||||
|
||||
template <typename ObjectWrapper, typename Res,
|
||||
typename Tin1, typename Tin2, typename Tin3,
|
||||
typename Tin4, typename Tin5, typename Tin6,
|
||||
typename Tin7, typename Tin8, typename Tin9,
|
||||
typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
|
||||
typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6,
|
||||
typename Arg7=Tin7, typename Arg8=Tin8, typename Arg9=Tin9>
|
||||
class BluetoothNotificationRunnable9 : public nsRunnable
|
||||
{
|
||||
public:
|
||||
typedef typename ObjectWrapper::ObjectType ObjectType;
|
||||
typedef BluetoothNotificationRunnable9<ObjectWrapper, Res,
|
||||
Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, Tin9,
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> SelfType;
|
||||
|
||||
template <typename InitOp>
|
||||
static already_AddRefed<SelfType> Create(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9),
|
||||
const InitOp& aInitOp)
|
||||
{
|
||||
nsRefPtr<SelfType> runnable(new SelfType(aMethod));
|
||||
if (NS_FAILED(runnable->Init(aInitOp))) {
|
||||
return nullptr;
|
||||
}
|
||||
return runnable.forget();
|
||||
}
|
||||
|
||||
template <typename InitOp>
|
||||
static void
|
||||
Dispatch(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9),
|
||||
const InitOp& aInitOp)
|
||||
{
|
||||
nsRefPtr<SelfType> runnable = Create(aMethod, aInitOp);
|
||||
if (!runnable) {
|
||||
BT_WARNING("BluetoothNotificationRunnable8::Create failed");
|
||||
return;
|
||||
}
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
|
||||
}
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ObjectType* obj = ObjectWrapper::GetInstance();
|
||||
if (!obj) {
|
||||
BT_WARNING("Notification handler not initialized");
|
||||
} else {
|
||||
((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4,
|
||||
mArg5, mArg6, mArg7, mArg8, mArg9);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothNotificationRunnable9(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9))
|
||||
: mMethod(aMethod)
|
||||
{
|
||||
MOZ_ASSERT(mMethod);
|
||||
}
|
||||
|
||||
template<typename InitOp>
|
||||
nsresult
|
||||
Init(const InitOp& aInitOp)
|
||||
{
|
||||
nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4,
|
||||
mArg5, mArg6, mArg7, mArg8, mArg9);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Res (ObjectType::*mMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
|
||||
Tin1 mArg1;
|
||||
Tin2 mArg2;
|
||||
Tin3 mArg3;
|
||||
Tin4 mArg4;
|
||||
Tin5 mArg5;
|
||||
Tin6 mArg6;
|
||||
Tin7 mArg7;
|
||||
Tin8 mArg8;
|
||||
Tin9 mArg9;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Init operators
|
||||
//
|
||||
|
||||
@@ -42,17 +42,6 @@ UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
|
||||
aString.AssignLiteral(uuidStr);
|
||||
}
|
||||
|
||||
void
|
||||
ReversedUuidToString(const BluetoothUuid& aUuid, nsAString& aString)
|
||||
{
|
||||
BluetoothUuid uuid;
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
uuid.mUuid[i] = aUuid.mUuid[15 - i];
|
||||
}
|
||||
|
||||
UuidToString(uuid, aString);
|
||||
}
|
||||
|
||||
void
|
||||
StringToUuid(const char* aString, BluetoothUuid& aUuid)
|
||||
{
|
||||
@@ -98,24 +87,16 @@ GenerateUuid(nsAString &aUuidString)
|
||||
aUuidString.Assign(Substring(uuidString, 1, NSID_LENGTH - 3));
|
||||
}
|
||||
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath,
|
||||
nsAString& aUuidStr)
|
||||
{
|
||||
ReversedUuidToString(aId.mUuid, aUuidStr);
|
||||
|
||||
aPath.Assign(aUuidStr);
|
||||
aPath.AppendLiteral("_");
|
||||
aPath.AppendInt(aId.mInstanceId);
|
||||
}
|
||||
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath)
|
||||
{
|
||||
nsString uuidStr;
|
||||
GeneratePathFromGattId(aId, aPath, uuidStr);
|
||||
UuidToString(aId.mUuid, uuidStr);
|
||||
|
||||
aPath.Assign(uuidStr);
|
||||
aPath.AppendLiteral("_");
|
||||
aPath.AppendInt(aId.mInstanceId);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -29,19 +29,6 @@ class BluetoothValue;
|
||||
void
|
||||
UuidToString(const BluetoothUuid& aUuid, nsAString& aString);
|
||||
|
||||
/**
|
||||
* Convert BluetoothUuid object in a reversed byte order to
|
||||
* xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string.
|
||||
* Bluedroid stack reports the BluetoothUuid in a reversed byte order for
|
||||
* GATT service, characteristic, descriptor uuids.
|
||||
*
|
||||
* Note: This utility function is used by gecko internal only to convert
|
||||
* BluetoothUuid in a reversed byte order created by bluetooth stack to uuid
|
||||
* string representation.
|
||||
*/
|
||||
void
|
||||
ReversedUuidToString(const BluetoothUuid& aUuid, nsAString& aString);
|
||||
|
||||
/**
|
||||
* Convert xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string to BluetoothUuid object.
|
||||
*
|
||||
@@ -63,18 +50,6 @@ GenerateUuid(nsAString &aUuidString);
|
||||
// Generate bluetooth signal path from GattId
|
||||
//
|
||||
|
||||
/**
|
||||
* Generate bluetooth signal path and UUID string from a GattId.
|
||||
*
|
||||
* @param aId [in] GattId value to convert.
|
||||
* @param aPath [out] Bluetooth signal path generated from aId.
|
||||
* @param aUuidStr [out] UUID string generated from aId.
|
||||
*/
|
||||
void
|
||||
GeneratePathFromGattId(const BluetoothGattId& aId,
|
||||
nsAString& aPath,
|
||||
nsAString& aUuidStr);
|
||||
|
||||
/**
|
||||
* Generate bluetooth signal path from a GattId.
|
||||
*
|
||||
|
||||
@@ -27,7 +27,7 @@ BluetoothDaemonA2dpModule::SetNotificationHandler(
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonA2dpModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
BluetoothDaemonA2dpModule::Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothA2dpResultHandler* aRes)
|
||||
{
|
||||
aRes->AddRef(); // Keep reference for response
|
||||
@@ -35,11 +35,11 @@ BluetoothDaemonA2dpModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData)
|
||||
BluetoothDaemonA2dpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonA2dpModule::* const HandleOp[])(
|
||||
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&, void*) = {
|
||||
const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
|
||||
INIT_ARRAY_AT(0, &BluetoothDaemonA2dpModule::HandleRsp),
|
||||
INIT_ARRAY_AT(1, &BluetoothDaemonA2dpModule::HandleNtf),
|
||||
};
|
||||
@@ -61,7 +61,7 @@ BluetoothDaemonA2dpModule::ConnectCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(new BluetoothDaemonPDU(SERVICE_ID,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(SERVICE_ID,
|
||||
OPCODE_CONNECT,
|
||||
6)); // Address
|
||||
nsresult rv = PackPDU(
|
||||
@@ -83,7 +83,7 @@ BluetoothDaemonA2dpModule::DisconnectCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(new BluetoothDaemonPDU(SERVICE_ID,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(SERVICE_ID,
|
||||
OPCODE_DISCONNECT,
|
||||
6)); // Address
|
||||
nsresult rv = PackPDU(
|
||||
@@ -104,8 +104,8 @@ BluetoothDaemonA2dpModule::DisconnectCmd(
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::ErrorRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothA2dpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothA2dpResultHandler* aRes)
|
||||
{
|
||||
ErrorRunnable::Dispatch(
|
||||
aRes, &BluetoothA2dpResultHandler::OnError, UnpackPDUInitOp(aPDU));
|
||||
@@ -113,7 +113,7 @@ BluetoothDaemonA2dpModule::ErrorRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::ConnectRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothA2dpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -122,7 +122,7 @@ BluetoothDaemonA2dpModule::ConnectRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::DisconnectRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothA2dpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -131,12 +131,12 @@ BluetoothDaemonA2dpModule::DisconnectRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::HandleRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonA2dpModule::* const HandleRsp[])(
|
||||
const BluetoothDaemonPDUHeader&,
|
||||
BluetoothDaemonPDU&,
|
||||
const DaemonSocketPDUHeader&,
|
||||
DaemonSocketPDU&,
|
||||
BluetoothA2dpResultHandler*) = {
|
||||
INIT_ARRAY_AT(OPCODE_ERROR,
|
||||
&BluetoothDaemonA2dpModule::ErrorRsp),
|
||||
@@ -186,14 +186,14 @@ class BluetoothDaemonA2dpModule::ConnectionStateInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
ConnectionStateInitOp(BluetoothDaemonPDU& aPDU)
|
||||
ConnectionStateInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (BluetoothA2dpConnectionState& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read state */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::ConnectionStateNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
ConnectionStateNotification::Dispatch(
|
||||
&BluetoothA2dpNotificationHandler::ConnectionStateNotification,
|
||||
@@ -226,7 +226,7 @@ class BluetoothDaemonA2dpModule::AudioStateInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
AudioStateInitOp(BluetoothDaemonPDU& aPDU)
|
||||
AudioStateInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -234,7 +234,7 @@ public:
|
||||
operator () (BluetoothA2dpAudioState& aArg1,
|
||||
nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read state */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -255,7 +255,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::AudioStateNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
AudioStateNotification::Dispatch(
|
||||
&BluetoothA2dpNotificationHandler::AudioStateNotification,
|
||||
@@ -267,14 +267,14 @@ class BluetoothDaemonA2dpModule::AudioConfigInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
AudioConfigInitOp(BluetoothDaemonPDU& aPDU)
|
||||
AudioConfigInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (nsString& aArg1, uint32_t aArg2, uint8_t aArg3) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read address */
|
||||
nsresult rv = UnpackPDU(
|
||||
@@ -301,7 +301,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::AudioConfigNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
AudioConfigNotification::Dispatch(
|
||||
&BluetoothA2dpNotificationHandler::AudioConfigNotification,
|
||||
@@ -310,11 +310,11 @@ BluetoothDaemonA2dpModule::AudioConfigNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonA2dpModule::HandleNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonA2dpModule::* const HandleNtf[])(
|
||||
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = {
|
||||
const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
|
||||
INIT_ARRAY_AT(0, &BluetoothDaemonA2dpModule::ConnectionStateNtf),
|
||||
INIT_ARRAY_AT(1, &BluetoothDaemonA2dpModule::AudioStateNtf),
|
||||
#if ANDROID_VERSION >= 21
|
||||
@@ -481,8 +481,8 @@ void
|
||||
BluetoothDaemonA2dpInterface::DispatchError(
|
||||
BluetoothA2dpResultHandler* aRes, BluetoothStatus aStatus)
|
||||
{
|
||||
BluetoothResultRunnable1<BluetoothA2dpResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
DaemonResultRunnable1<BluetoothA2dpResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
aRes, &BluetoothA2dpResultHandler::OnError,
|
||||
ConstantInitOp1<BluetoothStatus>(aStatus));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothInterfaceHelpers.h"
|
||||
#include "mozilla/ipc/DaemonRunnables.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
|
||||
static const int MAX_NUM_CLIENTS;
|
||||
|
||||
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||
virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
|
||||
|
||||
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
uint32_t aMaxNumClients,
|
||||
@@ -52,37 +53,38 @@ public:
|
||||
BluetoothA2dpResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||
nsresult Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothA2dpResultHandler* aRes);
|
||||
|
||||
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
void HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData);
|
||||
|
||||
//
|
||||
// Responses
|
||||
//
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothA2dpResultHandler, void>
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothA2dpResultHandler, void>
|
||||
ResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothA2dpResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothA2dpResultHandler, void, BluetoothStatus, BluetoothStatus>
|
||||
ErrorRunnable;
|
||||
|
||||
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothA2dpResultHandler* aRes);
|
||||
|
||||
void ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ConnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothA2dpResultHandler* aRes);
|
||||
|
||||
void DisconnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void DisconnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothA2dpResultHandler* aRes);
|
||||
|
||||
void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void HandleRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
//
|
||||
@@ -91,40 +93,36 @@ protected:
|
||||
|
||||
class NotificationHandlerWrapper;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothA2dpConnectionState,
|
||||
nsString,
|
||||
BluetoothA2dpConnectionState,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothA2dpConnectionState, nsString,
|
||||
BluetoothA2dpConnectionState, const nsAString&>
|
||||
ConnectionStateNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothA2dpAudioState,
|
||||
nsString,
|
||||
BluetoothA2dpAudioState,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothA2dpAudioState, nsString,
|
||||
BluetoothA2dpAudioState, const nsAString&>
|
||||
AudioStateNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
|
||||
nsString, uint32_t, uint8_t,
|
||||
const nsAString&, uint32_t, uint8_t>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
NotificationHandlerWrapper, void, nsString, uint32_t, uint8_t,
|
||||
const nsAString&, uint32_t, uint8_t>
|
||||
AudioConfigNotification;
|
||||
|
||||
class ConnectionStateInitOp;
|
||||
class AudioStateInitOp;
|
||||
class AudioConfigInitOp;
|
||||
|
||||
void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ConnectionStateNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void AudioStateNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void AudioConfigNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void AudioConfigNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void HandleNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
static BluetoothA2dpNotificationHandler* sNotificationHandler;
|
||||
|
||||
@@ -27,7 +27,7 @@ BluetoothDaemonAvrcpModule::SetNotificationHandler(
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonAvrcpModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
BluetoothDaemonAvrcpModule::Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
if (aRes) {
|
||||
@@ -37,11 +37,11 @@ BluetoothDaemonAvrcpModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData)
|
||||
BluetoothDaemonAvrcpModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonAvrcpModule::* const HandleOp[])(
|
||||
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&, void*) = {
|
||||
const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
|
||||
INIT_ARRAY_AT(0, &BluetoothDaemonAvrcpModule::HandleRsp),
|
||||
INIT_ARRAY_AT(1, &BluetoothDaemonAvrcpModule::HandleNtf),
|
||||
};
|
||||
@@ -63,8 +63,8 @@ BluetoothDaemonAvrcpModule::GetPlayStatusRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_GET_PLAY_STATUS_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_PLAY_STATUS_RSP,
|
||||
1 + // Play status
|
||||
4 + // Duration
|
||||
4)); // Position
|
||||
@@ -88,8 +88,8 @@ BluetoothDaemonAvrcpModule::ListPlayerAppAttrRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_LIST_PLAYER_APP_ATTR_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_LIST_PLAYER_APP_ATTR_RSP,
|
||||
1 + // # Attributes
|
||||
aNumAttr)); // Player attributes
|
||||
|
||||
@@ -113,8 +113,8 @@ BluetoothDaemonAvrcpModule::ListPlayerAppValueRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_LIST_PLAYER_APP_VALUE_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_LIST_PLAYER_APP_VALUE_RSP,
|
||||
1 + // # Values
|
||||
aNumVal)); // Player values
|
||||
|
||||
@@ -138,8 +138,8 @@ BluetoothDaemonAvrcpModule::GetPlayerAppValueRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_GET_PLAYER_APP_VALUE_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_PLAYER_APP_VALUE_RSP,
|
||||
1 + // # Pairs
|
||||
2 * aNumAttrs)); // Attribute-value pairs
|
||||
nsresult rv = PackPDU(
|
||||
@@ -163,8 +163,8 @@ BluetoothDaemonAvrcpModule::GetPlayerAppAttrTextRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_GET_PLAYER_APP_ATTR_TEXT_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_PLAYER_APP_ATTR_TEXT_RSP,
|
||||
0)); // Dynamically allocated
|
||||
nsresult rv = PackPDU(
|
||||
PackConversion<int, uint8_t>(aNumAttr),
|
||||
@@ -187,8 +187,8 @@ BluetoothDaemonAvrcpModule::GetPlayerAppValueTextRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_GET_PLAYER_APP_VALUE_TEXT_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_PLAYER_APP_VALUE_TEXT_RSP,
|
||||
0)); // Dynamically allocated
|
||||
nsresult rv = PackPDU(
|
||||
PackConversion<int, uint8_t>(aNumVal),
|
||||
@@ -211,8 +211,8 @@ BluetoothDaemonAvrcpModule::GetElementAttrRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_GET_ELEMENT_ATTR_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_ELEMENT_ATTR_RSP,
|
||||
0)); // Dynamically allocated
|
||||
nsresult rv = PackPDU(
|
||||
aNumAttr,
|
||||
@@ -234,8 +234,8 @@ BluetoothDaemonAvrcpModule::SetPlayerAppValueRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_SET_PLAYER_APP_VALUE_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_SET_PLAYER_APP_VALUE_RSP,
|
||||
1)); // Status code
|
||||
|
||||
nsresult rv = PackPDU(aRspStatus, *pdu);
|
||||
@@ -258,8 +258,8 @@ BluetoothDaemonAvrcpModule::RegisterNotificationRspCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_REGISTER_NOTIFICATION_RSP,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_REGISTER_NOTIFICATION_RSP,
|
||||
1 + // Event
|
||||
1 + // Type
|
||||
1 + // Data length
|
||||
@@ -284,8 +284,8 @@ BluetoothDaemonAvrcpModule::SetVolumeCmd(uint8_t aVolume,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_SET_VOLUME,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_SET_VOLUME,
|
||||
1)); // Volume
|
||||
|
||||
nsresult rv = PackPDU(aVolume, *pdu);
|
||||
@@ -305,8 +305,8 @@ BluetoothDaemonAvrcpModule::SetVolumeCmd(uint8_t aVolume,
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::ErrorRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ErrorRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::OnError, UnpackPDUInitOp(aPDU));
|
||||
@@ -314,8 +314,8 @@ BluetoothDaemonAvrcpModule::ErrorRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayStatusRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::GetPlayStatusRsp,
|
||||
@@ -324,8 +324,8 @@ BluetoothDaemonAvrcpModule::GetPlayStatusRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::ListPlayerAppAttrRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::ListPlayerAppAttrRsp,
|
||||
@@ -334,8 +334,8 @@ BluetoothDaemonAvrcpModule::ListPlayerAppAttrRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::ListPlayerAppValueRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::ListPlayerAppValueRsp,
|
||||
@@ -344,8 +344,8 @@ BluetoothDaemonAvrcpModule::ListPlayerAppValueRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayerAppValueRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppValueRsp,
|
||||
@@ -354,8 +354,8 @@ BluetoothDaemonAvrcpModule::GetPlayerAppValueRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayerAppAttrTextRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppAttrTextRsp,
|
||||
@@ -364,8 +364,8 @@ BluetoothDaemonAvrcpModule::GetPlayerAppAttrTextRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayerAppValueTextRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppValueTextRsp,
|
||||
@@ -374,8 +374,8 @@ BluetoothDaemonAvrcpModule::GetPlayerAppValueTextRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetElementAttrRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::GetElementAttrRsp,
|
||||
@@ -384,8 +384,8 @@ BluetoothDaemonAvrcpModule::GetElementAttrRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::SetPlayerAppValueRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::SetPlayerAppValueRsp,
|
||||
@@ -394,8 +394,8 @@ BluetoothDaemonAvrcpModule::SetPlayerAppValueRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::RegisterNotificationRspRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::RegisterNotificationRsp,
|
||||
@@ -404,8 +404,8 @@ BluetoothDaemonAvrcpModule::RegisterNotificationRspRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::SetVolumeRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::SetVolume,
|
||||
@@ -414,12 +414,12 @@ BluetoothDaemonAvrcpModule::SetVolumeRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::HandleRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonAvrcpModule::* const HandleRsp[])(
|
||||
const BluetoothDaemonPDUHeader&,
|
||||
BluetoothDaemonPDU&,
|
||||
const DaemonSocketPDUHeader&,
|
||||
DaemonSocketPDU&,
|
||||
BluetoothAvrcpResultHandler*) = {
|
||||
INIT_ARRAY_AT(OPCODE_ERROR,
|
||||
&BluetoothDaemonAvrcpModule::ErrorRsp),
|
||||
@@ -485,14 +485,14 @@ class BluetoothDaemonAvrcpModule::RemoteFeatureInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
RemoteFeatureInitOp(BluetoothDaemonPDU& aPDU)
|
||||
RemoteFeatureInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (nsString& aArg1, unsigned long& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read address */
|
||||
nsresult rv = UnpackPDU(
|
||||
@@ -515,7 +515,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::RemoteFeatureNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
RemoteFeatureNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::RemoteFeatureNotification,
|
||||
@@ -524,7 +524,7 @@ BluetoothDaemonAvrcpModule::RemoteFeatureNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayStatusNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
GetPlayStatusNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::GetPlayStatusNotification,
|
||||
@@ -533,7 +533,7 @@ BluetoothDaemonAvrcpModule::GetPlayStatusNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::ListPlayerAppAttrNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
ListPlayerAppAttrNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::ListPlayerAppAttrNotification,
|
||||
@@ -542,7 +542,7 @@ BluetoothDaemonAvrcpModule::ListPlayerAppAttrNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::ListPlayerAppValuesNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
ListPlayerAppValuesNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::ListPlayerAppValuesNotification,
|
||||
@@ -554,7 +554,7 @@ class BluetoothDaemonAvrcpModule::GetPlayerAppValueInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
GetPlayerAppValueInitOp(BluetoothDaemonPDU& aPDU)
|
||||
GetPlayerAppValueInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -562,7 +562,7 @@ public:
|
||||
operator () (uint8_t& aArg1,
|
||||
nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read number of attributes */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -583,7 +583,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayerAppValueNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
GetPlayerAppValueNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::GetPlayerAppValueNotification,
|
||||
@@ -595,7 +595,7 @@ class BluetoothDaemonAvrcpModule::GetPlayerAppAttrsTextInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
GetPlayerAppAttrsTextInitOp(BluetoothDaemonPDU& aPDU)
|
||||
GetPlayerAppAttrsTextInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -603,7 +603,7 @@ public:
|
||||
operator () (uint8_t& aArg1,
|
||||
nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read number of attributes */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -624,7 +624,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayerAppAttrsTextNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
GetPlayerAppAttrsTextNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::GetPlayerAppAttrsTextNotification,
|
||||
@@ -636,7 +636,7 @@ class BluetoothDaemonAvrcpModule::GetPlayerAppValuesTextInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
GetPlayerAppValuesTextInitOp(BluetoothDaemonPDU& aPDU)
|
||||
GetPlayerAppValuesTextInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -644,7 +644,7 @@ public:
|
||||
operator () (uint8_t& aArg1, uint8_t& aArg2,
|
||||
nsAutoArrayPtr<uint8_t>& aArg3) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read attribute */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -670,7 +670,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetPlayerAppValuesTextNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
GetPlayerAppValuesTextNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::GetPlayerAppValuesTextNotification,
|
||||
@@ -679,7 +679,7 @@ BluetoothDaemonAvrcpModule::GetPlayerAppValuesTextNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::SetPlayerAppValueNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
SetPlayerAppValueNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::SetPlayerAppValueNotification,
|
||||
@@ -691,7 +691,7 @@ class BluetoothDaemonAvrcpModule::GetElementAttrInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
GetElementAttrInitOp(BluetoothDaemonPDU& aPDU)
|
||||
GetElementAttrInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -699,7 +699,7 @@ public:
|
||||
operator () (uint8_t& aArg1,
|
||||
nsAutoArrayPtr<BluetoothAvrcpMediaAttribute>& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read number of attributes */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -720,7 +720,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::GetElementAttrNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
GetElementAttrNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::GetElementAttrNotification,
|
||||
@@ -729,7 +729,7 @@ BluetoothDaemonAvrcpModule::GetElementAttrNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::RegisterNotificationNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
RegisterNotificationNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::RegisterNotificationNotification,
|
||||
@@ -739,7 +739,7 @@ BluetoothDaemonAvrcpModule::RegisterNotificationNtf(
|
||||
#if ANDROID_VERSION >= 19
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::VolumeChangeNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
VolumeChangeNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::VolumeChangeNotification,
|
||||
@@ -751,14 +751,14 @@ class BluetoothDaemonAvrcpModule::PassthroughCmdInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
PassthroughCmdInitOp(BluetoothDaemonPDU& aPDU)
|
||||
PassthroughCmdInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (int& aArg1, int& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, UnpackConversion<uint8_t, int>(aArg1));
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -775,7 +775,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::PassthroughCmdNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
PassthroughCmdNotification::Dispatch(
|
||||
&BluetoothAvrcpNotificationHandler::PassthroughCmdNotification,
|
||||
@@ -785,11 +785,11 @@ BluetoothDaemonAvrcpModule::PassthroughCmdNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonAvrcpModule::HandleNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonAvrcpModule::* const HandleNtf[])(
|
||||
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = {
|
||||
const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
|
||||
#if ANDROID_VERSION >= 19
|
||||
INIT_ARRAY_AT(0, &BluetoothDaemonAvrcpModule::RemoteFeatureNtf),
|
||||
INIT_ARRAY_AT(1, &BluetoothDaemonAvrcpModule::GetPlayStatusNtf),
|
||||
@@ -1089,8 +1089,8 @@ void
|
||||
BluetoothDaemonAvrcpInterface::DispatchError(
|
||||
BluetoothAvrcpResultHandler* aRes, BluetoothStatus aStatus)
|
||||
{
|
||||
BluetoothResultRunnable1<BluetoothAvrcpResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
DaemonResultRunnable1<BluetoothAvrcpResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
aRes, &BluetoothAvrcpResultHandler::OnError,
|
||||
ConstantInitOp1<BluetoothStatus>(aStatus));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothInterfaceHelpers.h"
|
||||
#include "mozilla/ipc/DaemonRunnables.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
|
||||
static const int MAX_NUM_CLIENTS;
|
||||
|
||||
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||
virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
|
||||
|
||||
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
uint32_t aMaxNumClients,
|
||||
@@ -116,69 +117,70 @@ public:
|
||||
nsresult SetVolumeCmd(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||
nsresult Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
void HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData);
|
||||
|
||||
//
|
||||
// Responses
|
||||
//
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothAvrcpResultHandler, void>
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothAvrcpResultHandler, void>
|
||||
ResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothAvrcpResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothAvrcpResultHandler, void, BluetoothStatus, BluetoothStatus>
|
||||
ErrorRunnable;
|
||||
|
||||
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void GetPlayStatusRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void GetPlayStatusRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void ListPlayerAppAttrRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ListPlayerAppAttrRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void ListPlayerAppValueRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ListPlayerAppValueRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void GetPlayerAppValueRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void GetPlayerAppValueRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void GetPlayerAppAttrTextRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void GetPlayerAppAttrTextRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void GetPlayerAppValueTextRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void GetPlayerAppValueTextRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void GetElementAttrRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void GetElementAttrRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void SetPlayerAppValueRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void SetPlayerAppValueRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void RegisterNotificationRspRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void RegisterNotificationRspRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void SetVolumeRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void SetVolumeRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void HandleRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
//
|
||||
@@ -187,57 +189,61 @@ protected:
|
||||
|
||||
class NotificationHandlerWrapper;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
nsString, unsigned long,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, nsString, unsigned long,
|
||||
const nsAString&>
|
||||
RemoteFeatureNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable0<
|
||||
NotificationHandlerWrapper, void>
|
||||
GetPlayStatusNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable0<
|
||||
NotificationHandlerWrapper, void>
|
||||
ListPlayerAppAttrNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
BluetoothAvrcpPlayerAttribute>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, BluetoothAvrcpPlayerAttribute>
|
||||
ListPlayerAppValuesNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, uint8_t,
|
||||
nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
|
||||
uint8_t, const BluetoothAvrcpPlayerAttribute*>
|
||||
GetPlayerAppValueNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, uint8_t,
|
||||
nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
|
||||
uint8_t, const BluetoothAvrcpPlayerAttribute*>
|
||||
GetPlayerAppAttrsTextNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
|
||||
uint8_t, uint8_t,
|
||||
nsAutoArrayPtr<uint8_t>, uint8_t,
|
||||
uint8_t, const uint8_t*>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
NotificationHandlerWrapper, void, uint8_t, uint8_t,
|
||||
nsAutoArrayPtr<uint8_t>, uint8_t, uint8_t, const uint8_t*>
|
||||
GetPlayerAppValuesTextNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
BluetoothAvrcpPlayerSettings,
|
||||
const BluetoothAvrcpPlayerSettings&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, BluetoothAvrcpPlayerSettings,
|
||||
const BluetoothAvrcpPlayerSettings&>
|
||||
SetPlayerAppValueNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
uint8_t, nsAutoArrayPtr<BluetoothAvrcpMediaAttribute>,
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, uint8_t,
|
||||
nsAutoArrayPtr<BluetoothAvrcpMediaAttribute>,
|
||||
uint8_t, const BluetoothAvrcpMediaAttribute*>
|
||||
GetElementAttrNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothAvrcpEvent, uint32_t>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothAvrcpEvent, uint32_t>
|
||||
RegisterNotificationNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
uint8_t, uint8_t>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, uint8_t, uint8_t>
|
||||
VolumeChangeNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
int, int>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, int, int>
|
||||
PassthroughCmdNotification;
|
||||
|
||||
class GetElementAttrInitOp;
|
||||
@@ -247,44 +253,44 @@ protected:
|
||||
class PassthroughCmdInitOp;
|
||||
class RemoteFeatureInitOp;
|
||||
|
||||
void RemoteFeatureNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void RemoteFeatureNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void GetPlayStatusNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void GetPlayStatusNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ListPlayerAppAttrNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ListPlayerAppAttrNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ListPlayerAppValuesNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ListPlayerAppValuesNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void GetPlayerAppValueNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void GetPlayerAppValueNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void GetPlayerAppAttrsTextNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void GetPlayerAppAttrsTextNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void GetPlayerAppValuesTextNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void GetPlayerAppValuesTextNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void SetPlayerAppValueNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void SetPlayerAppValueNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void GetElementAttrNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void GetElementAttrNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void RegisterNotificationNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void RegisterNotificationNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void VolumeChangeNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void VolumeChangeNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void PassthroughCmdNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void PassthroughCmdNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void HandleNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
static BluetoothAvrcpNotificationHandler* sNotificationHandler;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "BluetoothDaemonConnector.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/un.h>
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
@@ -15,10 +16,14 @@ BEGIN_BLUETOOTH_NAMESPACE
|
||||
BluetoothDaemonConnector::BluetoothDaemonConnector(
|
||||
const nsACString& aSocketName)
|
||||
: mSocketName(aSocketName)
|
||||
{ }
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(BluetoothDaemonConnector, UnixSocketConnector);
|
||||
}
|
||||
|
||||
BluetoothDaemonConnector::~BluetoothDaemonConnector()
|
||||
{ }
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(BluetoothDaemonConnector, UnixSocketConnector);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonConnector::CreateSocket(int& aFd) const
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothInterfaceHelpers.h"
|
||||
#include "mozilla/ipc/DaemonRunnables.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -45,13 +46,26 @@ public:
|
||||
OPCODE_CLIENT_READ_REMOTE_RSSI = 0x13,
|
||||
OPCODE_CLIENT_GET_DEVICE_TYPE = 0x14,
|
||||
OPCODE_CLIENT_SET_ADV_DATA = 0x15,
|
||||
OPCODE_CLIENT_TEST_COMMAND = 0x16
|
||||
// TODO: Add server opcodes
|
||||
OPCODE_CLIENT_TEST_COMMAND = 0x16,
|
||||
OPCODE_SERVER_REGISTER = 0x17,
|
||||
OPCODE_SERVER_UNREGISTER = 0x18,
|
||||
OPCODE_SERVER_CONNECT_PERIPHERAL = 0x19,
|
||||
OPCODE_SERVER_DISCONNECT_PERIPHERAL = 0x1a,
|
||||
OPCODE_SERVER_ADD_SERVICE = 0x1b,
|
||||
OPCODE_SERVER_ADD_INCLUDED_SERVICE = 0x1c,
|
||||
OPCODE_SERVER_ADD_CHARACTERISTIC = 0x1d,
|
||||
OPCODE_SERVER_ADD_DESCRIPTOR = 0x1e,
|
||||
OPCODE_SERVER_START_SERVICE = 0x1f,
|
||||
OPCODE_SERVER_STOP_SERVICE = 0x20,
|
||||
OPCODE_SERVER_DELETE_SERVICE = 0x21,
|
||||
OPCODE_SERVER_SEND_INDICATION = 0x22,
|
||||
OPCODE_SERVER_SEND_RESPONSE = 0x23
|
||||
// TODO: Add L support
|
||||
};
|
||||
|
||||
static const int MAX_NUM_CLIENTS;
|
||||
|
||||
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||
virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
|
||||
|
||||
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
uint32_t aMaxNumClients,
|
||||
@@ -208,129 +222,268 @@ public:
|
||||
const BluetoothGattTestParam& aTestParam,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
// TODO: Add server commands
|
||||
/* Register / Unregister */
|
||||
nsresult ServerRegisterCmd(const BluetoothUuid& aUuid,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerUnregisterCmd(int aServerIf,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Connect / Disconnect */
|
||||
nsresult ServerConnectPeripheralCmd(int aServerIf,
|
||||
const nsAString& aBdAddr,
|
||||
bool aIsDirect,
|
||||
BluetoothTransport aTransport,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerDisconnectPeripheralCmd(
|
||||
int aServerIf,
|
||||
const nsAString& aBdAddr,
|
||||
int aConnId,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Add a services / a characteristic / a descriptor */
|
||||
nsresult ServerAddServiceCmd(int aServerIf,
|
||||
const BluetoothGattServiceId& aServiceId,
|
||||
int aNumHandles,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerAddIncludedServiceCmd(int aServerIf,
|
||||
int aServiceHandle,
|
||||
int aIncludedServiceHandle,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerAddCharacteristicCmd(int aServerIf,
|
||||
int aServiceHandle,
|
||||
const BluetoothUuid& aUuid,
|
||||
BluetoothGattCharProp aProperties,
|
||||
BluetoothGattAttrPerm aPermissions,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerAddDescriptorCmd(int aServerIf,
|
||||
int aServiceHandle,
|
||||
const BluetoothUuid& aUuid,
|
||||
BluetoothGattAttrPerm aPermissions,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Start / Stop / Delete a service */
|
||||
nsresult ServerStartServiceCmd(int aServerIf,
|
||||
int aServiceHandle,
|
||||
BluetoothTransport aTransport,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerStopServiceCmd(int aServerIf,
|
||||
int aServiceHandle,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
nsresult ServerDeleteServiceCmd(int aServerIf,
|
||||
int aServiceHandle,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Send an indication or a notification */
|
||||
nsresult ServerSendIndicationCmd(int aServerIf,
|
||||
int aAttributeHandle,
|
||||
int aConnId,
|
||||
int aLength,
|
||||
bool aConfirm,
|
||||
uint8_t* aValue,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Send a response for an incoming indication */
|
||||
nsresult ServerSendResponseCmd(int aConnId,
|
||||
int aTransId,
|
||||
BluetoothGattStatus aStatus,
|
||||
const BluetoothGattResponse& aResponse,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
// TODO: Add L support
|
||||
|
||||
protected:
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||
nsresult Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothGattResultHandler* aRes);
|
||||
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||
nsresult Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
nsresult Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData);
|
||||
|
||||
//
|
||||
// Responses
|
||||
//
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothGattClientResultHandler, void>
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothGattClientResultHandler, void>
|
||||
ClientResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothGattResultHandler, void>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothGattClientResultHandler, void,
|
||||
BluetoothTypeOfDevice, BluetoothTypeOfDevice>
|
||||
ClientGetDeviceTypeResultRunnable;
|
||||
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothGattServerResultHandler, void>
|
||||
ServerResultRunnable;
|
||||
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothGattResultHandler, void>
|
||||
ResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothGattResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothGattResultHandler, void, BluetoothStatus, BluetoothStatus>
|
||||
ErrorRunnable;
|
||||
|
||||
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattResultHandler* aRes);
|
||||
|
||||
void ClientRegisterRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientRegisterRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientUnregisterRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientUnregisterRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientScanRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientScanRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientConnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientDisconnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientDisconnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientListenRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientListenRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientRefreshRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientRefreshRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientSearchServiceRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientSearchServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientGetIncludedServiceRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientGetIncludedServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientGetCharacteristicRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientGetCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientGetDescriptorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientGetDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientReadCharacteristicRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientReadCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientWriteCharacteristicRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientWriteCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientReadDescriptorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientReadDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientWriteDescriptorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientWriteDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientExecuteWriteRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientExecuteWriteRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientRegisterNotificationRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientRegisterNotificationRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientDeregisterNotificationRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientDeregisterNotificationRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientReadRemoteRssiRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientReadRemoteRssiRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientGetDeviceTypeRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientGetDeviceTypeRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientSetAdvDataRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientSetAdvDataRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void ClientTestCommandRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClientTestCommandRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattClientResultHandler* aRes);
|
||||
|
||||
void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void* aUserData);
|
||||
void ServerRegisterRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
// TODO: Add Server responses
|
||||
void ServerUnregisterRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerConnectPeripheralRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerDisconnectPeripheralRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerAddServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerAddIncludedServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerAddCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerAddDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerStartServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerStopServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerDeleteServiceRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerSendIndicationRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
void ServerSendResponseRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
// TODO: Add L support
|
||||
|
||||
void HandleRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
//
|
||||
// Notifications
|
||||
@@ -338,44 +491,44 @@ protected:
|
||||
|
||||
class NotificationHandlerWrapper;
|
||||
class ClientNotificationHandlerWrapper;
|
||||
class ServerNotificationHandlerWrapper;
|
||||
|
||||
// GATT Client Notification
|
||||
typedef BluetoothNotificationRunnable3<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, BluetoothUuid,
|
||||
BluetoothGattStatus, int, const BluetoothUuid&>
|
||||
ClientRegisterNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
nsString, int, BluetoothGattAdvData,
|
||||
const nsAString&, int, const BluetoothGattAdvData&>
|
||||
ClientScanResultNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable4<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, int, nsString,
|
||||
int, BluetoothGattStatus, int, const nsAString&>
|
||||
ClientConnectNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable4<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, int, nsString,
|
||||
int, BluetoothGattStatus, int, const nsAString&>
|
||||
ClientDisconnectNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus>
|
||||
ClientSearchCompleteNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattServiceId,
|
||||
int, const BluetoothGattServiceId&>
|
||||
ClientSearchResultNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable5<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable5<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattServiceId,
|
||||
BluetoothGattId, BluetoothGattCharProp,
|
||||
@@ -383,7 +536,7 @@ protected:
|
||||
const BluetoothGattId&, const BluetoothGattCharProp&>
|
||||
ClientGetCharacteristicNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable5<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable5<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattServiceId,
|
||||
BluetoothGattId, BluetoothGattId,
|
||||
@@ -391,14 +544,14 @@ protected:
|
||||
const BluetoothGattId&, const BluetoothGattId&>
|
||||
ClientGetDescriptorNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable4<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattServiceId, BluetoothGattServiceId,
|
||||
int, BluetoothGattStatus, const BluetoothGattServiceId&,
|
||||
const BluetoothGattServiceId&>
|
||||
ClientGetIncludedServiceNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable5<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable5<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, int, BluetoothGattStatus,
|
||||
BluetoothGattServiceId, BluetoothGattId,
|
||||
@@ -406,112 +559,231 @@ protected:
|
||||
const BluetoothGattServiceId&, const BluetoothGattId&>
|
||||
ClientRegisterNotificationNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattNotifyParam,
|
||||
int, const BluetoothGattNotifyParam&>
|
||||
ClientNotifyNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattReadParam,
|
||||
int, BluetoothGattStatus, const BluetoothGattReadParam&>
|
||||
ClientReadCharacteristicNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattWriteParam,
|
||||
int, BluetoothGattStatus, const BluetoothGattWriteParam&>
|
||||
ClientWriteCharacteristicNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattReadParam,
|
||||
int, BluetoothGattStatus, const BluetoothGattReadParam&>
|
||||
ClientReadDescriptorNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus, BluetoothGattWriteParam,
|
||||
int, BluetoothGattStatus, const BluetoothGattWriteParam&>
|
||||
ClientWriteDescriptorNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, BluetoothGattStatus>
|
||||
ClientExecuteWriteNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable4<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
int, nsString, int, BluetoothGattStatus,
|
||||
int, const nsAString&, int, BluetoothGattStatus>
|
||||
ClientReadRemoteRssiNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
ClientNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int>
|
||||
ClientListenNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, BluetoothUuid,
|
||||
BluetoothGattStatus, int, const BluetoothUuid&>
|
||||
ServerRegisterNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
int, int, bool, nsString,
|
||||
int, int, bool, const nsAString&>
|
||||
ServerConnectionNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, BluetoothGattServiceId, int,
|
||||
BluetoothGattStatus, int, const BluetoothGattServiceId&, int>
|
||||
ServerServiceAddedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, int, int>
|
||||
ServerIncludedServiceAddedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable5<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, BluetoothUuid, int, int,
|
||||
BluetoothGattStatus, int, const BluetoothUuid&, int, int>
|
||||
ServerCharacteristicAddedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable5<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, BluetoothUuid, int, int,
|
||||
BluetoothGattStatus, int, const BluetoothUuid&, int, int>
|
||||
ServerDescriptorAddedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, int>
|
||||
ServerServiceStartedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, int>
|
||||
ServerServiceStoppedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int, int>
|
||||
ServerServiceDeletedNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable6<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
int, int, nsString, int, int, bool,
|
||||
int, int, const nsAString&, int, int, bool>
|
||||
ServerRequestReadNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable9<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
int, int, nsString, int, int, int, nsAutoArrayPtr<uint8_t>, bool, bool,
|
||||
int, int, const nsAString&, int, int, int, const uint8_t*, bool, bool>
|
||||
ServerRequestWriteNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable4<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
int, int, nsString, bool,
|
||||
int, int, const nsAString&, bool>
|
||||
ServerRequestExecuteWriteNotification;
|
||||
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
ServerNotificationHandlerWrapper, void,
|
||||
BluetoothGattStatus, int>
|
||||
ServerResponseConfirmationNotification;
|
||||
|
||||
class ClientScanResultInitOp;
|
||||
class ClientConnectDisconnectInitOp;
|
||||
class ClientReadRemoteRssiInitOp;
|
||||
class ClientGetDeviceTypeInitOp;
|
||||
class ServerConnectionInitOp;
|
||||
class ServerRequestReadInitOp;
|
||||
class ServerRequestWriteInitOp;
|
||||
class ServerRequestExecuteWriteInitOp;
|
||||
|
||||
void ClientRegisterNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientRegisterNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientScanResultNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientScanResultNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientConnectNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientConnectNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientDisconnectNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientDisconnectNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientSearchCompleteNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientSearchCompleteNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientSearchResultNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientSearchResultNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientGetCharacteristicNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientGetCharacteristicNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientGetDescriptorNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientGetDescriptorNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientGetIncludedServiceNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientGetIncludedServiceNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientRegisterNotificationNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientRegisterNotificationNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientNotifyNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientNotifyNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientReadCharacteristicNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientReadCharacteristicNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientWriteCharacteristicNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientWriteCharacteristicNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientReadDescriptorNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientReadDescriptorNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientWriteDescriptorNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientWriteDescriptorNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientExecuteWriteNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientExecuteWriteNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientReadRemoteRssiNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientReadRemoteRssiNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClientListenNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClientListenNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ServerRegisterNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerConnectionNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerServiceAddedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerIncludedServiceAddedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerCharacteristicAddedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerDescriptorAddedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerServiceStartedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerServiceStoppedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerServiceDeletedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerRequestReadNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerRequestWriteNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerRequestExecuteWriteNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ServerResponseConfirmationNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
// TODO: Add L support
|
||||
|
||||
void HandleNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
static BluetoothGattNotificationHandler* sNotificationHandler;
|
||||
@@ -533,6 +805,7 @@ public:
|
||||
void Cleanup(BluetoothGattResultHandler* aRes);
|
||||
|
||||
BluetoothGattClientInterface* GetBluetoothGattClientInterface();
|
||||
BluetoothGattServerInterface* GetBluetoothGattServerInterface();
|
||||
|
||||
private:
|
||||
void DispatchError(BluetoothGattResultHandler* aRes,
|
||||
@@ -678,7 +951,86 @@ private:
|
||||
BluetoothDaemonGattModule* mModule;
|
||||
};
|
||||
|
||||
// TODO: Add GattServerInterface
|
||||
class BluetoothDaemonGattServerInterface final
|
||||
: public BluetoothGattServerInterface
|
||||
{
|
||||
public:
|
||||
BluetoothDaemonGattServerInterface(BluetoothDaemonGattModule* aModule);
|
||||
|
||||
/* Register / Unregister */
|
||||
void RegisterServer(const BluetoothUuid& aUuid,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void UnregisterServer(int aServerIf,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Connect / Disconnect */
|
||||
void ConnectPeripheral(int aServerIf,
|
||||
const nsAString& aBdAddr,
|
||||
bool aIsDirect, /* auto connect */
|
||||
BluetoothTransport aTransport,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void DisconnectPeripheral(int aServerIf,
|
||||
const nsAString& aBdAddr,
|
||||
int aConnId,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Add a services / a characteristic / a descriptor */
|
||||
void AddService(int aServerIf,
|
||||
const BluetoothGattServiceId& aServiceId,
|
||||
int aNumHandles,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void AddIncludedService(int aServerIf,
|
||||
int aServiceHandle,
|
||||
int aIncludedServiceHandle,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void AddCharacteristic(int aServerIf,
|
||||
int aServiceHandle,
|
||||
const BluetoothUuid& aUuid,
|
||||
BluetoothGattCharProp aProperties,
|
||||
BluetoothGattAttrPerm aPermissions,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void AddDescriptor(int aServerIf,
|
||||
int aServiceHandle,
|
||||
const BluetoothUuid& aUuid,
|
||||
BluetoothGattAttrPerm aPermissions,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Start / Stop / Delete a service */
|
||||
void StartService(int aServerIf,
|
||||
int aServiceHandle,
|
||||
BluetoothTransport aTransport,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void StopService(int aServerIf,
|
||||
int aServiceHandle,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
void DeleteService(int aServerIf,
|
||||
int aServiceHandle,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Send an indication or a notification */
|
||||
void SendIndication(
|
||||
int aServerIf,
|
||||
int aAttributeHandle,
|
||||
int aConnId,
|
||||
const nsTArray<uint8_t>& aValue,
|
||||
bool aConfirm, /* true: indication, false: notification */
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
/* Send a response for an incoming indication */
|
||||
void SendResponse(int aConnId,
|
||||
int aTransId,
|
||||
BluetoothGattStatus aStatus,
|
||||
const BluetoothGattResponse& aResponse,
|
||||
BluetoothGattServerResultHandler* aRes);
|
||||
|
||||
|
||||
private:
|
||||
void DispatchError(BluetoothGattServerResultHandler* aRes,
|
||||
BluetoothStatus aStatus);
|
||||
void DispatchError(BluetoothGattServerResultHandler* aRes, nsresult aRv);
|
||||
BluetoothDaemonGattModule* mModule;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@ BluetoothDaemonHandsfreeModule::SetNotificationHandler(
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonHandsfreeModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
BluetoothDaemonHandsfreeModule::Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
aRes->AddRef(); // Keep reference for response
|
||||
@@ -38,11 +38,11 @@ BluetoothDaemonHandsfreeModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData)
|
||||
BluetoothDaemonHandsfreeModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonHandsfreeModule::* const HandleOp[])(
|
||||
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&, void*) = {
|
||||
const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
|
||||
INIT_ARRAY_AT(0, &BluetoothDaemonHandsfreeModule::HandleRsp),
|
||||
INIT_ARRAY_AT(1, &BluetoothDaemonHandsfreeModule::HandleNtf),
|
||||
};
|
||||
@@ -64,8 +64,8 @@ BluetoothDaemonHandsfreeModule::ConnectCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CONNECT,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_CONNECT,
|
||||
6)); // Address
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
@@ -87,8 +87,8 @@ BluetoothDaemonHandsfreeModule::DisconnectCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_DISCONNECT,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_DISCONNECT,
|
||||
6)); // Address
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
@@ -110,8 +110,8 @@ BluetoothDaemonHandsfreeModule::ConnectAudioCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CONNECT_AUDIO,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_CONNECT_AUDIO,
|
||||
6)); // Address
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
@@ -133,8 +133,8 @@ BluetoothDaemonHandsfreeModule::DisconnectAudioCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_DISCONNECT_AUDIO,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_DISCONNECT_AUDIO,
|
||||
6)); // Address
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
@@ -156,8 +156,8 @@ BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_START_VOICE_RECOGNITION,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_START_VOICE_RECOGNITION,
|
||||
6)); // Address (BlueZ 5.25)
|
||||
|
||||
nsresult rv;
|
||||
@@ -182,8 +182,8 @@ BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_STOP_VOICE_RECOGNITION,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_STOP_VOICE_RECOGNITION,
|
||||
6)); // Address (BlueZ 5.25)
|
||||
|
||||
nsresult rv;
|
||||
@@ -209,8 +209,8 @@ BluetoothDaemonHandsfreeModule::VolumeControlCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_VOLUME_CONTROL,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_VOLUME_CONTROL,
|
||||
1 + // Volume type
|
||||
1 + // Volume
|
||||
6)); // Address (BlueZ 5.25)
|
||||
@@ -241,8 +241,8 @@ BluetoothDaemonHandsfreeModule::DeviceStatusNotificationCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_DEVICE_STATUS_NOTIFICATION,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_DEVICE_STATUS_NOTIFICATION,
|
||||
1 + // Network state
|
||||
1 + // Service type
|
||||
1 + // Signal strength
|
||||
@@ -269,8 +269,8 @@ BluetoothDaemonHandsfreeModule::CopsResponseCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_COPS_RESPONSE,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_COPS_RESPONSE,
|
||||
0 + // Dynamically allocated
|
||||
6)); // Address (BlueZ 5.25)
|
||||
|
||||
@@ -302,8 +302,8 @@ BluetoothDaemonHandsfreeModule::CindResponseCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CIND_RESPONSE,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_CIND_RESPONSE,
|
||||
1 + // Service
|
||||
1 + // # Active
|
||||
1 + // # Held
|
||||
@@ -350,8 +350,8 @@ BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_FORMATTED_AT_RESPONSE,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_FORMATTED_AT_RESPONSE,
|
||||
0 + // Dynamically allocated
|
||||
6)); // Address (BlueZ 5.25)
|
||||
|
||||
@@ -380,8 +380,8 @@ BluetoothDaemonHandsfreeModule::AtResponseCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_AT_RESPONSE,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_AT_RESPONSE,
|
||||
1 + // AT Response code
|
||||
1 + // Error code
|
||||
6)); // Address (BlueZ 5.25)
|
||||
@@ -417,8 +417,8 @@ BluetoothDaemonHandsfreeModule::ClccResponseCmd(
|
||||
|
||||
NS_ConvertUTF16toUTF8 number(aNumber);
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CLCC_RESPONSE,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_CLCC_RESPONSE,
|
||||
1 + // Call index
|
||||
1 + // Call direction
|
||||
1 + // Call state
|
||||
@@ -460,8 +460,8 @@ BluetoothDaemonHandsfreeModule::PhoneStateChangeCmd(
|
||||
|
||||
NS_ConvertUTF16toUTF8 number(aNumber);
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_PHONE_STATE_CHANGE,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_PHONE_STATE_CHANGE,
|
||||
1 + // # Active
|
||||
1 + // # Held
|
||||
1 + // Call state
|
||||
@@ -491,8 +491,8 @@ BluetoothDaemonHandsfreeModule::ConfigureWbsCmd(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(
|
||||
new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CONFIGURE_WBS,
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(
|
||||
new DaemonSocketPDU(SERVICE_ID, OPCODE_CONFIGURE_WBS,
|
||||
6 + // Address
|
||||
1)); // Config
|
||||
|
||||
@@ -514,8 +514,8 @@ BluetoothDaemonHandsfreeModule::ConfigureWbsCmd(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ErrorRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, BluetoothHandsfreeResultHandler* aRes)
|
||||
const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ErrorRunnable::Dispatch(
|
||||
aRes, &BluetoothHandsfreeResultHandler::OnError, UnpackPDUInitOp(aPDU));
|
||||
@@ -523,7 +523,7 @@ BluetoothDaemonHandsfreeModule::ErrorRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ConnectRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -532,7 +532,7 @@ BluetoothDaemonHandsfreeModule::ConnectRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::DisconnectRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -541,7 +541,7 @@ BluetoothDaemonHandsfreeModule::DisconnectRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ConnectAudioRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -551,7 +551,7 @@ BluetoothDaemonHandsfreeModule::ConnectAudioRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::DisconnectAudioRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -561,7 +561,7 @@ BluetoothDaemonHandsfreeModule::DisconnectAudioRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::StartVoiceRecognitionRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -571,7 +571,7 @@ BluetoothDaemonHandsfreeModule::StartVoiceRecognitionRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::StopVoiceRecognitionRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -581,7 +581,7 @@ BluetoothDaemonHandsfreeModule::StopVoiceRecognitionRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::VolumeControlRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -591,7 +591,7 @@ BluetoothDaemonHandsfreeModule::VolumeControlRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::DeviceStatusNotificationRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -601,7 +601,7 @@ BluetoothDaemonHandsfreeModule::DeviceStatusNotificationRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::CopsResponseRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -611,7 +611,7 @@ BluetoothDaemonHandsfreeModule::CopsResponseRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::CindResponseRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -621,7 +621,7 @@ BluetoothDaemonHandsfreeModule::CindResponseRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::FormattedAtResponseRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -631,7 +631,7 @@ BluetoothDaemonHandsfreeModule::FormattedAtResponseRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::AtResponseRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -641,7 +641,7 @@ BluetoothDaemonHandsfreeModule::AtResponseRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ClccResponseRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -651,7 +651,7 @@ BluetoothDaemonHandsfreeModule::ClccResponseRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::PhoneStateChangeRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -661,7 +661,7 @@ BluetoothDaemonHandsfreeModule::PhoneStateChangeRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ConfigureWbsRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes)
|
||||
{
|
||||
ResultRunnable::Dispatch(
|
||||
@@ -671,12 +671,12 @@ BluetoothDaemonHandsfreeModule::ConfigureWbsRsp(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::HandleRsp(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonHandsfreeModule::* const HandleRsp[])(
|
||||
const BluetoothDaemonPDUHeader&,
|
||||
BluetoothDaemonPDU&,
|
||||
const DaemonSocketPDUHeader&,
|
||||
DaemonSocketPDU&,
|
||||
BluetoothHandsfreeResultHandler*) = {
|
||||
INIT_ARRAY_AT(OPCODE_ERROR,
|
||||
&BluetoothDaemonHandsfreeModule::ErrorRsp),
|
||||
@@ -752,7 +752,7 @@ class BluetoothDaemonHandsfreeModule::ConnectionStateInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
ConnectionStateInitOp(BluetoothDaemonPDU& aPDU)
|
||||
ConnectionStateInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -760,7 +760,7 @@ public:
|
||||
operator () (BluetoothHandsfreeConnectionState& aArg1,
|
||||
nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read state */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -789,7 +789,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ConnectionStateNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
ConnectionStateNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::ConnectionStateNotification,
|
||||
@@ -801,14 +801,14 @@ class BluetoothDaemonHandsfreeModule::AudioStateInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
AudioStateInitOp(BluetoothDaemonPDU& aPDU)
|
||||
AudioStateInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (BluetoothHandsfreeAudioState& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read state */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -829,7 +829,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::AudioStateNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
AudioStateNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::AudioStateNotification,
|
||||
@@ -841,7 +841,7 @@ class BluetoothDaemonHandsfreeModule::VoiceRecognitionInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
VoiceRecognitionInitOp(BluetoothDaemonPDU& aPDU)
|
||||
VoiceRecognitionInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -849,7 +849,7 @@ public:
|
||||
operator () (BluetoothHandsfreeVoiceRecognitionState& aArg1,
|
||||
nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read state */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -874,7 +874,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
VoiceRecognitionNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification,
|
||||
@@ -886,7 +886,7 @@ class BluetoothDaemonHandsfreeModule::AnswerCallInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
AnswerCallInitOp(BluetoothDaemonPDU& aPDU)
|
||||
AnswerCallInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -910,7 +910,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::AnswerCallNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
AnswerCallNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::AnswerCallNotification,
|
||||
@@ -922,7 +922,7 @@ class BluetoothDaemonHandsfreeModule::HangupCallInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
HangupCallInitOp(BluetoothDaemonPDU& aPDU)
|
||||
HangupCallInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -946,7 +946,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::HangupCallNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
HangupCallNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::HangupCallNotification,
|
||||
@@ -958,7 +958,7 @@ class BluetoothDaemonHandsfreeModule::VolumeInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
VolumeInitOp(BluetoothDaemonPDU& aPDU)
|
||||
VolumeInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -966,7 +966,7 @@ public:
|
||||
operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2,
|
||||
nsString& aArg3) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read volume type */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -997,7 +997,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::VolumeNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
VolumeNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::VolumeNotification,
|
||||
@@ -1009,14 +1009,14 @@ class BluetoothDaemonHandsfreeModule::DialCallInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
DialCallInitOp(BluetoothDaemonPDU& aPDU)
|
||||
DialCallInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (nsString& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv;
|
||||
/* Read address
|
||||
@@ -1045,7 +1045,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::DialCallNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
DialCallNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::DialCallNotification,
|
||||
@@ -1057,14 +1057,14 @@ class BluetoothDaemonHandsfreeModule::DtmfInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
DtmfInitOp(BluetoothDaemonPDU& aPDU)
|
||||
DtmfInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (char& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read tone */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -1089,7 +1089,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::DtmfNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
DtmfNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::DtmfNotification,
|
||||
@@ -1101,14 +1101,14 @@ class BluetoothDaemonHandsfreeModule::NRECInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
NRECInitOp(BluetoothDaemonPDU& aPDU)
|
||||
NRECInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (BluetoothHandsfreeNRECState& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read state */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -1133,7 +1133,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::NRECNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
NRECNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::NRECNotification,
|
||||
@@ -1145,14 +1145,14 @@ class BluetoothDaemonHandsfreeModule::CallHoldInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
CallHoldInitOp(BluetoothDaemonPDU& aPDU)
|
||||
CallHoldInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (BluetoothHandsfreeCallHoldType& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
/* Read type */
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
@@ -1177,7 +1177,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::CallHoldNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
CallHoldNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::CallHoldNotification,
|
||||
@@ -1189,7 +1189,7 @@ class BluetoothDaemonHandsfreeModule::CnumInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
CnumInitOp(BluetoothDaemonPDU& aPDU)
|
||||
CnumInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -1213,7 +1213,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::CnumNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
CnumNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::CnumNotification,
|
||||
@@ -1225,7 +1225,7 @@ class BluetoothDaemonHandsfreeModule::CindInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
CindInitOp(BluetoothDaemonPDU& aPDU)
|
||||
CindInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -1249,7 +1249,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::CindNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
CindNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::CindNotification,
|
||||
@@ -1261,7 +1261,7 @@ class BluetoothDaemonHandsfreeModule::CopsInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
CopsInitOp(BluetoothDaemonPDU& aPDU)
|
||||
CopsInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -1285,7 +1285,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::CopsNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
CopsNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::CopsNotification,
|
||||
@@ -1297,7 +1297,7 @@ class BluetoothDaemonHandsfreeModule::ClccInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
ClccInitOp(BluetoothDaemonPDU& aPDU)
|
||||
ClccInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -1321,7 +1321,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::ClccNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
ClccNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::ClccNotification,
|
||||
@@ -1333,14 +1333,14 @@ class BluetoothDaemonHandsfreeModule::UnknownAtInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
UnknownAtInitOp(BluetoothDaemonPDU& aPDU)
|
||||
UnknownAtInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (nsCString& aArg1, nsString& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv;
|
||||
/* Read address
|
||||
@@ -1369,7 +1369,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::UnknownAtNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
UnknownAtNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::UnknownAtNotification,
|
||||
@@ -1381,7 +1381,7 @@ class BluetoothDaemonHandsfreeModule::KeyPressedInitOp final
|
||||
: private PDUInitOp
|
||||
{
|
||||
public:
|
||||
KeyPressedInitOp(BluetoothDaemonPDU& aPDU)
|
||||
KeyPressedInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -1405,7 +1405,7 @@ public:
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::KeyPressedNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
KeyPressedNotification::Dispatch(
|
||||
&BluetoothHandsfreeNotificationHandler::KeyPressedNotification,
|
||||
@@ -1414,11 +1414,11 @@ BluetoothDaemonHandsfreeModule::KeyPressedNtf(
|
||||
|
||||
void
|
||||
BluetoothDaemonHandsfreeModule::HandleNtf(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonHandsfreeModule::* const HandleNtf[])(
|
||||
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = {
|
||||
const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
|
||||
INIT_ARRAY_AT(0, &BluetoothDaemonHandsfreeModule::ConnectionStateNtf),
|
||||
INIT_ARRAY_AT(1, &BluetoothDaemonHandsfreeModule::AudioStateNtf),
|
||||
INIT_ARRAY_AT(2, &BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf),
|
||||
@@ -1799,8 +1799,8 @@ void
|
||||
BluetoothDaemonHandsfreeInterface::DispatchError(
|
||||
BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus)
|
||||
{
|
||||
BluetoothResultRunnable1<BluetoothHandsfreeResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
DaemonResultRunnable1<BluetoothHandsfreeResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
aRes, &BluetoothHandsfreeResultHandler::OnError,
|
||||
ConstantInitOp1<BluetoothStatus>(aStatus));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothInterfaceHelpers.h"
|
||||
#include "mozilla/ipc/DaemonRunnables.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -41,7 +42,7 @@ public:
|
||||
OPCODE_CONFIGURE_WBS = 0x0f
|
||||
};
|
||||
|
||||
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||
virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
|
||||
|
||||
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
uint32_t aMaxNumClients,
|
||||
@@ -125,89 +126,90 @@ public:
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||
nsresult Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
void HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData);
|
||||
|
||||
//
|
||||
// Responses
|
||||
//
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothHandsfreeResultHandler, void>
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothHandsfreeResultHandler, void>
|
||||
ResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothHandsfreeResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothHandsfreeResultHandler, void, BluetoothStatus, BluetoothStatus>
|
||||
ErrorRunnable;
|
||||
|
||||
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ConnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void DisconnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void DisconnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ConnectAudioRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ConnectAudioRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void DisconnectAudioRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void DisconnectAudioRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void StartVoiceRecognitionRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void StartVoiceRecognitionRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void StopVoiceRecognitionRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void StopVoiceRecognitionRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void VolumeControlRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void VolumeControlRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void DeviceStatusNotificationRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void DeviceStatusNotificationRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void CopsResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void CopsResponseRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void CindResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void CindResponseRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void FormattedAtResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void FormattedAtResponseRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void AtResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void AtResponseRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ClccResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ClccResponseRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void PhoneStateChangeRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void PhoneStateChangeRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ConfigureWbsRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ConfigureWbsRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void HandleRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
//
|
||||
@@ -216,88 +218,76 @@ protected:
|
||||
|
||||
class NotificationHandlerWrapper;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeConnectionState,
|
||||
nsString,
|
||||
BluetoothHandsfreeConnectionState,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothHandsfreeConnectionState,
|
||||
nsString, BluetoothHandsfreeConnectionState, const nsAString&>
|
||||
ConnectionStateNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeAudioState,
|
||||
nsString,
|
||||
BluetoothHandsfreeAudioState,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothHandsfreeAudioState,
|
||||
nsString, BluetoothHandsfreeAudioState, const nsAString&>
|
||||
AudioStateNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeVoiceRecognitionState, nsString,
|
||||
BluetoothHandsfreeVoiceRecognitionState, const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothHandsfreeVoiceRecognitionState,
|
||||
nsString, BluetoothHandsfreeVoiceRecognitionState, const nsAString&>
|
||||
VoiceRecognitionNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
AnswerCallNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
HangupCallNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable3<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeVolumeType, int, nsString,
|
||||
BluetoothHandsfreeVolumeType, int, const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable3<
|
||||
NotificationHandlerWrapper, void, BluetoothHandsfreeVolumeType,
|
||||
int, nsString, BluetoothHandsfreeVolumeType, int, const nsAString&>
|
||||
VolumeNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
nsString, nsString,
|
||||
const nsAString&, const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, nsString, nsString, const nsAString&,
|
||||
const nsAString&>
|
||||
DialCallNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
char, nsString,
|
||||
char, const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, char, nsString, char, const nsAString&>
|
||||
DtmfNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeNRECState, nsString,
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothHandsfreeNRECState, nsString,
|
||||
BluetoothHandsfreeNRECState, const nsAString&>
|
||||
NRECNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeCallHoldType, nsString,
|
||||
BluetoothHandsfreeCallHoldType, const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType,
|
||||
nsString, BluetoothHandsfreeCallHoldType, const nsAString&>
|
||||
CallHoldNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
CnumNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
CindNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
CopsNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
ClccNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
nsCString, nsString,
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable2<
|
||||
NotificationHandlerWrapper, void, nsCString, nsString,
|
||||
const nsACString&, const nsAString&>
|
||||
UnknownAtNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString,
|
||||
const nsAString&>
|
||||
typedef mozilla::ipc::DaemonNotificationRunnable1<
|
||||
NotificationHandlerWrapper, void, nsString, const nsAString&>
|
||||
KeyPressedNotification;
|
||||
|
||||
class ConnectionStateInitOp;
|
||||
@@ -318,56 +308,56 @@ protected:
|
||||
class UnknownAtInitOp;
|
||||
class KeyPressedInitOp;
|
||||
|
||||
void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ConnectionStateNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void AudioStateNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void VoiceRecognitionNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void VoiceRecognitionNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void AnswerCallNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void AnswerCallNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void HangupCallNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void HangupCallNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void VolumeNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void VolumeNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void DialCallNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void DialCallNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void DtmfNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void DtmfNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void NRECNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void NRECNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void CallHoldNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void CallHoldNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void CnumNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void CnumNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void CindNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void CindNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void CopsNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void CopsNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void ClccNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void ClccNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void UnknownAtNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void UnknownAtNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void KeyPressedNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
void KeyPressedNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void HandleNtf(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
static BluetoothHandsfreeNotificationHandler* sNotificationHandler;
|
||||
|
||||
@@ -30,6 +30,21 @@ Convert(bool aIn, uint8_t& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, int32_t& aOut)
|
||||
{
|
||||
static const bool sValue[] = {
|
||||
CONVERT(false, 0x00),
|
||||
CONVERT(true, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sValue))) {
|
||||
aOut = 0;
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sValue[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, BluetoothScanMode& aOut)
|
||||
{
|
||||
@@ -402,6 +417,12 @@ Convert(uint8_t aIn, BluetoothHandsfreeWbsConfig& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothTypeOfDevice& aOut)
|
||||
{
|
||||
return Convert((int32_t)aIn, aOut);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothPropertyType& aOut)
|
||||
{
|
||||
@@ -1070,20 +1091,20 @@ Convert(const ConvertArray<Tin>& aIn, Tout& aOut)
|
||||
//
|
||||
|
||||
nsresult
|
||||
PackPDU(bool aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(bool aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<bool, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAddress& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothAddress& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackArray<uint8_t>(aIn.mAddr, sizeof(aIn.mAddr)), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpAttributeTextPairs& aIn,
|
||||
BluetoothDaemonPDU& aPDU)
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -1119,7 +1140,7 @@ PackPDU(const BluetoothAvrcpAttributeTextPairs& aIn,
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpAttributeValuePairs& aIn,
|
||||
BluetoothDaemonPDU& aPDU)
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -1137,7 +1158,7 @@ PackPDU(const BluetoothAvrcpAttributeValuePairs& aIn,
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpElementAttribute& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothAvrcpElementAttribute& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(PackConversion<uint32_t, uint8_t>(aIn.mId), aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1163,13 +1184,13 @@ PackPDU(const BluetoothAvrcpElementAttribute& aIn, BluetoothDaemonPDU& aPDU)
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpEvent aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothAvrcpEvent aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothAvrcpEvent, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpEventParamPair& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothAvrcpEventParamPair& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@@ -1211,110 +1232,110 @@ PackPDU(const BluetoothAvrcpEventParamPair& aIn, BluetoothDaemonPDU& aPDU)
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpNotification aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothAvrcpNotification aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothAvrcpNotification, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpPlayerAttribute aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothAvrcpPlayerAttribute aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothAvrcpPlayerAttribute, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpStatus aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothAvrcpStatus aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothAvrcpStatus, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothConfigurationParameter& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothConfigurationParameter& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(aIn.mType, aIn.mLength,
|
||||
PackArray<uint8_t>(aIn.mValue.get(), aIn.mLength), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(aIn.mService, aIn.mOpcode, aIn.mLength, aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeAtResponse& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeAtResponse& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeAtResponse, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallAddressType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeCallAddressType& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallAddressType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallDirection& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeCallDirection& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallDirection, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMode& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeCallMode& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallMode, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMptyType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeCallMptyType& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallMptyType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallState& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeCallState& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallState, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeNetworkState& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeNetworkState& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeNetworkState, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeServiceType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeServiceType& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeServiceType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeVolumeType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeVolumeType& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeVolumeType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeWbsConfig& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothHandsfreeWbsConfig& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeWbsConfig, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothNamedValue& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(
|
||||
PackConversion<nsString, BluetoothPropertyType>(aIn.name()), aPDU);
|
||||
@@ -1350,7 +1371,7 @@ PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU)
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothPinCode& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothPinCode& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(aIn.mLength,
|
||||
PackArray<uint8_t>(aIn.mPinCode, sizeof(aIn.mPinCode)),
|
||||
@@ -1358,58 +1379,58 @@ PackPDU(const BluetoothPinCode& aIn, BluetoothDaemonPDU& aPDU)
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothPropertyType aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothPropertyType aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothPropertyType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothSspVariant aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothSspVariant aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothSspVariant, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothScanMode aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothScanMode aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothScanMode, int32_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothServiceName& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothServiceName& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackArray<uint8_t>(aIn.mName, sizeof(aIn.mName)), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothSocketType aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothSocketType aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothSocketType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(ControlPlayStatus aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(ControlPlayStatus aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<ControlPlayStatus, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothTransport aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothTransport aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothTransport, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothUuid& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothUuid& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackArray<uint8_t>(aIn.mUuid, sizeof(aIn.mUuid)), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothGattId& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothGattId& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn.mUuid, aPDU);
|
||||
nsresult rv = PackPDU(PackReversed<BluetoothUuid>(aIn.mUuid), aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -1417,7 +1438,7 @@ PackPDU(const BluetoothGattId& aIn, BluetoothDaemonPDU& aPDU)
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothGattServiceId& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const BluetoothGattServiceId& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn.mId, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1427,13 +1448,13 @@ PackPDU(const BluetoothGattServiceId& aIn, BluetoothDaemonPDU& aPDU)
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothGattAuthReq aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothGattAuthReq aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothGattAuthReq, int32_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothGattWriteType aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(BluetoothGattWriteType aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(PackConversion<BluetoothGattWriteType, int32_t>(aIn), aPDU);
|
||||
}
|
||||
@@ -1443,60 +1464,60 @@ PackPDU(BluetoothGattWriteType aIn, BluetoothDaemonPDU& aPDU)
|
||||
//
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, bool>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, char& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, char>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpAudioState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothA2dpAudioState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothA2dpAudioState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpConnectionState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothA2dpConnectionState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothA2dpConnectionState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAclState& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothAclState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpEvent& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpEvent& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothAvrcpEvent>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpMediaAttribute& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpMediaAttribute& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothAvrcpMediaAttribute>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpPlayerAttribute& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpPlayerAttribute& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothAvrcpPlayerAttribute>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpPlayerSettings& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpPlayerSettings& aOut)
|
||||
{
|
||||
/* Read number of attribute-value pairs */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mNumAttr);
|
||||
@@ -1518,55 +1539,55 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpPlayerSettings& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpRemoteFeature& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpRemoteFeature& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothAvrcpRemoteFeature>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothBondState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothBondState& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothBondState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothTypeOfDevice& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothTypeOfDevice& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<int32_t, BluetoothTypeOfDevice>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeAudioState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeAudioState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeAudioState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeCallHoldType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeConnectionState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeConnectionState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeConnectionState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeNRECState& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeNRECState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeNRECState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU,
|
||||
UnpackPDU(DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeVoiceRecognitionState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
@@ -1575,14 +1596,14 @@ UnpackPDU(BluetoothDaemonPDU& aPDU,
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeVolumeType& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeVolumeType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeVolumeType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothProperty& aOut)
|
||||
{
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mType);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1667,14 +1688,14 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothPropertyType& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothPropertyType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothPropertyType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothRemoteInfo& aOut)
|
||||
{
|
||||
nsresult rv = UnpackPDU(aPDU,
|
||||
UnpackConversion<uint32_t, int>(aOut.mVerMajor));
|
||||
@@ -1689,13 +1710,13 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothScanMode& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothScanMode& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<int32_t, BluetoothScanMode>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothServiceRecord& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothServiceRecord& aOut)
|
||||
{
|
||||
/* unpack UUID */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mUuid);
|
||||
@@ -1712,29 +1733,29 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothServiceRecord& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothSspVariant& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothSspVariant& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothSspVariant>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothStatus& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothStatus& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothStatus>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattStatus& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattStatus& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<int32_t, BluetoothGattStatus>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattId& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattId& aOut)
|
||||
{
|
||||
/* unpack UUID */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mUuid);
|
||||
nsresult rv = UnpackPDU(aPDU, UnpackReversed<BluetoothUuid>(aOut.mUuid));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -1743,7 +1764,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattId& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattServiceId& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattServiceId& aOut)
|
||||
{
|
||||
/* unpack id */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mId);
|
||||
@@ -1755,7 +1776,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattServiceId& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattReadParam& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattReadParam& aOut)
|
||||
{
|
||||
/* unpack service id */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mServiceId);
|
||||
@@ -1792,7 +1813,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattReadParam& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattWriteParam& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattWriteParam& aOut)
|
||||
{
|
||||
/* unpack service id */
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mServiceId);
|
||||
@@ -1814,7 +1835,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattWriteParam& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattNotifyParam& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattNotifyParam& aOut)
|
||||
{
|
||||
|
||||
/* unpack address and convert to nsString */
|
||||
@@ -1851,7 +1872,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattNotifyParam& aOut)
|
||||
return aPDU.Read(aOut.mValue, aOut.mLength);
|
||||
}
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut)
|
||||
{
|
||||
// We get a pointer to the first character in the PDU, a length
|
||||
// of 1 ensures we consume the \0 byte. With 'str' pointing to
|
||||
@@ -1881,7 +1902,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut)
|
||||
{
|
||||
nsDependentCString cstring;
|
||||
|
||||
@@ -1896,7 +1917,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut)
|
||||
{
|
||||
nsDependentCString cstring;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "BluetoothCommon.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/ipc/BluetoothDaemonConnection.h"
|
||||
#include "mozilla/ipc/DaemonSocketPDU.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
@@ -75,14 +75,14 @@ struct BluetoothConfigurationParameter {
|
||||
nsAutoArrayPtr<uint8_t> mValue;
|
||||
};
|
||||
|
||||
struct BluetoothDaemonPDUHeader {
|
||||
BluetoothDaemonPDUHeader()
|
||||
struct DaemonSocketPDUHeader {
|
||||
DaemonSocketPDUHeader()
|
||||
: mService(0x00)
|
||||
, mOpcode(0x00)
|
||||
, mLength(0x00)
|
||||
{ }
|
||||
|
||||
BluetoothDaemonPDUHeader(uint8_t aService, uint8_t aOpcode, uint8_t aLength)
|
||||
DaemonSocketPDUHeader(uint8_t aService, uint8_t aOpcode, uint8_t aLength)
|
||||
: mService(aService)
|
||||
, mOpcode(aOpcode)
|
||||
, mLength(aLength)
|
||||
@@ -119,6 +119,9 @@ struct BluetoothServiceName {
|
||||
nsresult
|
||||
Convert(bool aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, int32_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(bool aIn, BluetoothScanMode& aOut);
|
||||
|
||||
@@ -315,141 +318,141 @@ Convert(BluetoothGattWriteType aIn, int32_t& aOut);
|
||||
// introduce link errors on non-handled data types
|
||||
template <typename T>
|
||||
nsresult
|
||||
PackPDU(T aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(T aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(bool aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(bool aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
inline nsresult
|
||||
PackPDU(uint8_t aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(uint8_t aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return aPDU.Write(aIn);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
PackPDU(uint16_t aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(uint16_t aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return aPDU.Write(aIn);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
PackPDU(int32_t aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(int32_t aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return aPDU.Write(aIn);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
PackPDU(uint32_t aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(uint32_t aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return aPDU.Write(aIn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAddress& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothAddress& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpAttributeTextPairs& aIn,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpAttributeValuePairs& aIn,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpElementAttribute& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothAvrcpElementAttribute& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpEvent aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothAvrcpEvent aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothAvrcpEventParamPair& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothAvrcpEventParamPair& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpNotification aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothAvrcpNotification aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpPlayerAttribute aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothAvrcpPlayerAttribute aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothAvrcpStatus aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothAvrcpStatus aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothConfigurationParameter& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothConfigurationParameter& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeAtResponse& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeAtResponse& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallAddressType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeCallAddressType& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallDirection& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeCallDirection& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMode& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeCallMode& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMptyType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeCallMptyType& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallState& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeCallState& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeNetworkState& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeNetworkState& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeServiceType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeServiceType& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeVolumeType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeVolumeType& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeWbsConfig& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothHandsfreeWbsConfig& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothNamedValue& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothPinCode& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothPinCode& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothPropertyType aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothPropertyType aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothServiceName& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothServiceName& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothSocketType aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothSocketType aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothSspVariant aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothSspVariant aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothScanMode aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothScanMode aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(ControlPlayStatus aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(ControlPlayStatus aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothUuid& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothUuid& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothGattId& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothGattId& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothGattServiceId& aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(const BluetoothGattServiceId& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothGattAuthReq aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothGattAuthReq aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothGattWriteType aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothGattWriteType aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(BluetoothTransport aIn, BluetoothDaemonPDU& aPDU);
|
||||
PackPDU(BluetoothTransport aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
/* |PackConversion| is a helper for packing converted values. Pass
|
||||
* an instance of this structure to |PackPDU| to convert a value from
|
||||
@@ -466,7 +469,7 @@ struct PackConversion {
|
||||
|
||||
template<typename Tin, typename Tout>
|
||||
inline nsresult
|
||||
PackPDU(const PackConversion<Tin, Tout>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const PackConversion<Tin, Tout>& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
Tout out;
|
||||
|
||||
@@ -498,7 +501,7 @@ struct PackArray
|
||||
*/
|
||||
template<typename T>
|
||||
inline nsresult
|
||||
PackPDU(const PackArray<T>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const PackArray<T>& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
for (size_t i = 0; i < aIn.mLength; ++i) {
|
||||
nsresult rv = PackPDU(aIn.mData[i], aPDU);
|
||||
@@ -511,7 +514,7 @@ PackPDU(const PackArray<T>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
/* Write raw bytes in one pass */
|
||||
return aPDU.Write(aIn.mData, aIn.mLength);
|
||||
@@ -519,7 +522,7 @@ PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
PackPDU<char>(const PackArray<char>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU<char>(const PackArray<char>& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
/* Write raw bytes in one pass */
|
||||
return aPDU.Write(aIn.mData, aIn.mLength);
|
||||
@@ -541,16 +544,67 @@ struct PackCString0
|
||||
/* This implementation of |PackPDU| packs a 0-terminated C string.
|
||||
*/
|
||||
inline nsresult
|
||||
PackPDU(const PackCString0& aIn, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const PackCString0& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackArray<uint8_t>(reinterpret_cast<const uint8_t*>(aIn.mString.get()),
|
||||
aIn.mString.Length() + 1), aPDU);
|
||||
}
|
||||
|
||||
/* |PackReversed| is a helper for packing data in reversed order. Pass an
|
||||
* instance of this structure as the first argument to |PackPDU| to pack data
|
||||
* in reversed order.
|
||||
*/
|
||||
template<typename T>
|
||||
struct PackReversed
|
||||
{
|
||||
PackReversed(const T& aValue)
|
||||
: mValue(aValue)
|
||||
{ }
|
||||
|
||||
const T& mValue;
|
||||
};
|
||||
|
||||
/* No general rules to pack data in reversed order. Signal a link error if the
|
||||
* type |T| of |PackReversed| is not defined explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
nsresult
|
||||
PackPDU(const PackReversed<T>& aIn, DaemonSocketPDU& aPDU);
|
||||
|
||||
/* This implementation of |PackPDU| packs elements in |PackArray| in reversed
|
||||
* order. (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template<typename U>
|
||||
inline nsresult
|
||||
PackPDU(const PackReversed<PackArray<U>>& aIn, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
for (size_t i = 0; i < aIn.mValue.mLength; ++i) {
|
||||
nsresult rv = PackPDU(aIn.mValue.mData[aIn.mValue.mLength - i - 1], aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* This implementation of |PackPDU| packs |BluetoothUuid| in reversed order.
|
||||
* (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template <>
|
||||
inline nsresult
|
||||
PackPDU<BluetoothUuid>(const PackReversed<BluetoothUuid>& aIn,
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackReversed<PackArray<uint8_t>>(
|
||||
PackArray<uint8_t>(aIn.mValue.mUuid, sizeof(aIn.mValue.mUuid))),
|
||||
aPDU);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -562,7 +616,7 @@ PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
|
||||
template <typename T1, typename T2, typename T3>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
BluetoothDaemonPDU& aPDU)
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -578,7 +632,7 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4,
|
||||
BluetoothDaemonPDU& aPDU)
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -600,7 +654,7 @@ template <typename T1, typename T2, typename T3,
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5,
|
||||
BluetoothDaemonPDU& aPDU)
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -621,13 +675,43 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
return PackPDU(aIn5, aPDU);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3,
|
||||
typename T4, typename T5, typename T6>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn2, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn3, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn4, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn5, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return PackPDU(aIn6, aPDU);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3,
|
||||
typename T4, typename T5, typename T6,
|
||||
typename T7>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, BluetoothDaemonPDU& aPDU)
|
||||
const T7& aIn7, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -662,7 +746,7 @@ template <typename T1, typename T2, typename T3,
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, const T8& aIn8, BluetoothDaemonPDU& aPDU)
|
||||
const T7& aIn7, const T8& aIn8, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -705,7 +789,7 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, const T8& aIn8, const T9& aIn9,
|
||||
const T10& aIn10, const T11& aIn11, const T12& aIn12,
|
||||
const T13& aIn13, BluetoothDaemonPDU& aPDU)
|
||||
const T13& aIn13, DaemonSocketPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -765,79 +849,79 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
// introduce link errors on non-handled data types
|
||||
template <typename T>
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, T& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, T& aOut);
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, int8_t& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, int8_t& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, uint8_t& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, uint8_t& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, uint16_t& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, uint16_t& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, int32_t& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, int32_t& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, uint32_t& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, uint32_t& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut);
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, char& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpAudioState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothA2dpAudioState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpConnectionState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothA2dpConnectionState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAclState& aOut);
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAddress& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAddress& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut.mAddr, sizeof(aOut.mAddr));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpEvent& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpEvent& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpMediaAttribute& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpMediaAttribute& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpPlayerAttribute& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpPlayerAttribute& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpPlayerSettings& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpPlayerSettings& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAvrcpRemoteFeature& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpRemoteFeature& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothBondState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothBondState& aOut);
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDaemonPDUHeader& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, DaemonSocketPDUHeader& aOut)
|
||||
{
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mService);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -851,80 +935,80 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDaemonPDUHeader& aOut)
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothTypeOfDevice& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothTypeOfDevice& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeAudioState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeAudioState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeConnectionState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeConnectionState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeNRECState& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeNRECState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU,
|
||||
UnpackPDU(DaemonSocketPDU& aPDU,
|
||||
BluetoothHandsfreeVoiceRecognitionState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeVolumeType& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothHandsfreeVolumeType& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothRemoteInfo& aOut);
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteName& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothRemoteName& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut.mName, sizeof(aOut.mName));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothProperty& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothPropertyType& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothPropertyType& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothScanMode& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothScanMode& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothServiceRecord& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothServiceRecord& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothSspVariant& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothSspVariant& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothStatus& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothStatus& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattStatus& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattStatus& aOut);
|
||||
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothUuid& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothUuid& aOut)
|
||||
{
|
||||
return aPDU.Read(aOut.mUuid, sizeof(aOut.mUuid));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattId& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattId& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattServiceId& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattServiceId& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattReadParam& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattReadParam& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattWriteParam& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattWriteParam& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothGattNotifyParam& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattNotifyParam& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut);
|
||||
|
||||
/* |UnpackConversion| is a helper for convering unpacked values. Pass
|
||||
* an instance of this structure to |UnpackPDU| to read a value from
|
||||
@@ -941,7 +1025,7 @@ struct UnpackConversion {
|
||||
|
||||
template<typename Tin, typename Tout>
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut)
|
||||
{
|
||||
Tin in;
|
||||
nsresult rv = UnpackPDU(aPDU, in);
|
||||
@@ -985,7 +1069,7 @@ struct UnpackArray
|
||||
|
||||
template<typename T>
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackArray<T>& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackArray<T>& aOut)
|
||||
{
|
||||
for (size_t i = 0; i < aOut.mLength; ++i) {
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mData[i]);
|
||||
@@ -998,7 +1082,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackArray<T>& aOut)
|
||||
|
||||
template<typename T>
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, UnpackArray<T>& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, UnpackArray<T>& aOut)
|
||||
{
|
||||
for (size_t i = 0; i < aOut.mLength; ++i) {
|
||||
nsresult rv = UnpackPDU(aPDU, aOut.mData[i]);
|
||||
@@ -1011,7 +1095,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, UnpackArray<T>& aOut)
|
||||
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<uint8_t>(BluetoothDaemonPDU& aPDU, const UnpackArray<uint8_t>& aOut)
|
||||
UnpackPDU<uint8_t>(DaemonSocketPDU& aPDU, const UnpackArray<uint8_t>& aOut)
|
||||
{
|
||||
/* Read raw bytes in one pass */
|
||||
return aPDU.Read(aOut.mData, aOut.mLength);
|
||||
@@ -1019,7 +1103,7 @@ UnpackPDU<uint8_t>(BluetoothDaemonPDU& aPDU, const UnpackArray<uint8_t>& aOut)
|
||||
|
||||
template<typename T>
|
||||
inline nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, nsTArray<T>& aOut)
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, nsTArray<T>& aOut)
|
||||
{
|
||||
for (typename nsTArray<T>::size_type i = 0; i < aOut.Length(); ++i) {
|
||||
nsresult rv = UnpackPDU(aPDU, aOut[i]);
|
||||
@@ -1046,7 +1130,7 @@ struct UnpackCString0
|
||||
/* This implementation of |UnpackPDU| unpacks a 0-terminated C string.
|
||||
*/
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut);
|
||||
|
||||
/* |UnpackString0| is a helper for unpacking 0-terminated C string,
|
||||
* including the \0 character. Pass an instance of this structure
|
||||
@@ -1066,7 +1150,60 @@ struct UnpackString0
|
||||
* and converts it to wide-character encoding.
|
||||
*/
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut);
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut);
|
||||
|
||||
/* |UnpackReversed| is a helper for unpacking data in reversed order. Pass an
|
||||
* instance of this structure as the second argument to |UnpackPDU| to unpack
|
||||
* data in reversed order.
|
||||
*/
|
||||
template<typename T>
|
||||
struct UnpackReversed
|
||||
{
|
||||
UnpackReversed(T& aValue)
|
||||
: mValue(&aValue)
|
||||
{ }
|
||||
|
||||
UnpackReversed(T&& aValue)
|
||||
: mValue(&aValue)
|
||||
{ }
|
||||
|
||||
T* mValue;
|
||||
};
|
||||
|
||||
/* No general rules to unpack data in reversed order. Signal a link error if
|
||||
* the type |T| of |UnpackReversed| is not defined explicitly.
|
||||
*/
|
||||
template<typename T>
|
||||
nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<T>& aOut);
|
||||
|
||||
template<typename U>
|
||||
inline nsresult
|
||||
UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<UnpackArray<U>>& aOut)
|
||||
{
|
||||
for (size_t i = 0; i < aOut.mValue->mLength; ++i) {
|
||||
nsresult rv = UnpackPDU(aPDU,
|
||||
aOut.mValue->mData[aOut.mValue->mLength - i - 1]);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* This implementation of |UnpackPDU| unpacks |BluetoothUuid| in reversed
|
||||
* order. (ex. reversed GATT UUID, see bug 1171866)
|
||||
*/
|
||||
template<>
|
||||
inline nsresult
|
||||
UnpackPDU<BluetoothUuid>(DaemonSocketPDU& aPDU,
|
||||
const UnpackReversed<BluetoothUuid>& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU,
|
||||
UnpackReversed<UnpackArray<uint8_t>>(
|
||||
UnpackArray<uint8_t>(aOut.mValue->mUuid, sizeof(aOut.mValue->mUuid))));
|
||||
}
|
||||
|
||||
//
|
||||
// Init operators
|
||||
@@ -1076,11 +1213,11 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut);
|
||||
class PDUInitOp
|
||||
{
|
||||
protected:
|
||||
PDUInitOp(BluetoothDaemonPDU& aPDU)
|
||||
PDUInitOp(DaemonSocketPDU& aPDU)
|
||||
: mPDU(&aPDU)
|
||||
{ }
|
||||
|
||||
BluetoothDaemonPDU& GetPDU() const
|
||||
DaemonSocketPDU& GetPDU() const
|
||||
{
|
||||
return *mPDU; // cannot be nullptr
|
||||
}
|
||||
@@ -1102,7 +1239,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothDaemonPDU* mPDU; // Hold pointer to allow for constant instances
|
||||
DaemonSocketPDU* mPDU; // Hold pointer to allow for constant instances
|
||||
};
|
||||
|
||||
// |UnpackPDUInitOp| is a general-purpose init operator for all variants
|
||||
@@ -1112,7 +1249,7 @@ private:
|
||||
class UnpackPDUInitOp final : private PDUInitOp
|
||||
{
|
||||
public:
|
||||
UnpackPDUInitOp(BluetoothDaemonPDU& aPDU)
|
||||
UnpackPDUInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
@@ -1136,7 +1273,7 @@ public:
|
||||
template<typename T1, typename T2>
|
||||
nsresult operator () (T1& aArg1, T2& aArg2) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1153,7 +1290,7 @@ public:
|
||||
template<typename T1, typename T2, typename T3>
|
||||
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1174,7 +1311,7 @@ public:
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1200,7 +1337,7 @@ public:
|
||||
nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4,
|
||||
T5& aArg5) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,13 +8,13 @@
|
||||
#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemoninterface_h__
|
||||
|
||||
#include "BluetoothInterface.h"
|
||||
#include "mozilla/ipc/BluetoothDaemonConnectionConsumer.h"
|
||||
#include "mozilla/ipc/DaemonSocketConsumer.h"
|
||||
#include "mozilla/ipc/ListenSocketConsumer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class BluetoothDaemonConnection;
|
||||
class DaemonSocket;
|
||||
class ListenSocket;
|
||||
|
||||
}
|
||||
@@ -31,7 +31,7 @@ class BluetoothDaemonSocketInterface;
|
||||
|
||||
class BluetoothDaemonInterface final
|
||||
: public BluetoothInterface
|
||||
, public mozilla::ipc::BluetoothDaemonConnectionConsumer
|
||||
, public mozilla::ipc::DaemonSocketConsumer
|
||||
, public mozilla::ipc::ListenSocketConsumer
|
||||
{
|
||||
public:
|
||||
@@ -143,7 +143,7 @@ protected:
|
||||
unsigned long aPostfixLength,
|
||||
nsACString& aAddress);
|
||||
|
||||
// Methods for |BluetoothDaemonConnectionConsumer| and |ListenSocketConsumer|
|
||||
// Methods for |DaemonSocketConsumer| and |ListenSocketConsumer|
|
||||
//
|
||||
|
||||
void OnConnectSuccess(int aIndex) override;
|
||||
@@ -156,8 +156,8 @@ private:
|
||||
|
||||
nsCString mListenSocketName;
|
||||
nsRefPtr<mozilla::ipc::ListenSocket> mListenSocket;
|
||||
nsRefPtr<mozilla::ipc::BluetoothDaemonConnection> mCmdChannel;
|
||||
nsRefPtr<mozilla::ipc::BluetoothDaemonConnection> mNtfChannel;
|
||||
nsRefPtr<mozilla::ipc::DaemonSocket> mCmdChannel;
|
||||
nsRefPtr<mozilla::ipc::DaemonSocket> mNtfChannel;
|
||||
nsAutoPtr<BluetoothDaemonProtocol> mProtocol;
|
||||
|
||||
nsTArray<nsRefPtr<BluetoothResultHandler> > mResultHandlerQ;
|
||||
|
||||
@@ -30,7 +30,7 @@ BluetoothDaemonSocketModule::ListenCmd(BluetoothSocketType aType,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(new BluetoothDaemonPDU(0x02, 0x01, 0));
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x02, 0x01, 0));
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
aType,
|
||||
@@ -59,7 +59,7 @@ BluetoothDaemonSocketModule::ConnectCmd(const nsAString& aBdAddr,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothDaemonPDU> pdu(new BluetoothDaemonPDU(0x02, 0x02, 0));
|
||||
nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x02, 0x02, 0));
|
||||
|
||||
nsresult rv = PackPDU(
|
||||
PackConversion<nsAString, BluetoothAddress>(aBdAddr),
|
||||
@@ -156,13 +156,13 @@ BluetoothDaemonSocketModule::CloseCmd(BluetoothSocketResultHandler* aRes)
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonSocketModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothDaemonSocketModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
static void (BluetoothDaemonSocketModule::* const HandleRsp[])(
|
||||
const BluetoothDaemonPDUHeader&,
|
||||
BluetoothDaemonPDU&,
|
||||
const DaemonSocketPDUHeader&,
|
||||
DaemonSocketPDU&,
|
||||
BluetoothSocketResultHandler*) = {
|
||||
INIT_ARRAY_AT(0x00, &BluetoothDaemonSocketModule::ErrorRsp),
|
||||
INIT_ARRAY_AT(0x01, &BluetoothDaemonSocketModule::ListenRsp),
|
||||
@@ -186,7 +186,7 @@ BluetoothDaemonSocketModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonSocketModule::Send(BluetoothDaemonPDU* aPDU,
|
||||
BluetoothDaemonSocketModule::Send(DaemonSocketPDU* aPDU,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
aRes->AddRef(); // Keep reference for response
|
||||
@@ -203,8 +203,8 @@ BluetoothDaemonSocketModule::SocketFlags(bool aEncrypt, bool aAuth)
|
||||
//
|
||||
|
||||
void
|
||||
BluetoothDaemonSocketModule::ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothDaemonSocketModule::ErrorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
ErrorRunnable::Dispatch(
|
||||
@@ -214,14 +214,14 @@ BluetoothDaemonSocketModule::ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
class BluetoothDaemonSocketModule::ListenInitOp final : private PDUInitOp
|
||||
{
|
||||
public:
|
||||
ListenInitOp(BluetoothDaemonPDU& aPDU)
|
||||
ListenInitOp(DaemonSocketPDU& aPDU)
|
||||
: PDUInitOp(aPDU)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
operator () (int& aArg1) const
|
||||
{
|
||||
BluetoothDaemonPDU& pdu = GetPDU();
|
||||
DaemonSocketPDU& pdu = GetPDU();
|
||||
|
||||
aArg1 = pdu.AcquireFd();
|
||||
|
||||
@@ -234,8 +234,8 @@ public:
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothDaemonSocketModule::ListenRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothDaemonSocketModule::ListenRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
IntResultRunnable::Dispatch(
|
||||
@@ -274,8 +274,8 @@ public:
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothDaemonSocketModule::ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothDaemonSocketModule::ConnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
/* the file descriptor is attached in the PDU's ancillary data */
|
||||
@@ -366,8 +366,8 @@ void
|
||||
BluetoothDaemonSocketInterface::DispatchError(
|
||||
BluetoothSocketResultHandler* aRes, BluetoothStatus aStatus)
|
||||
{
|
||||
BluetoothResultRunnable1<BluetoothSocketResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
DaemonResultRunnable1<BluetoothSocketResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||
aRes, &BluetoothSocketResultHandler::OnError,
|
||||
ConstantInitOp1<BluetoothStatus>(aStatus));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothInterfaceHelpers.h"
|
||||
#include "mozilla/ipc/DaemonRunnables.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -20,7 +21,7 @@ class BluetoothDaemonSocketModule
|
||||
public:
|
||||
static const int MAX_NUM_CLIENTS;
|
||||
|
||||
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||
virtual nsresult Send(DaemonSocketPDU* aPDU, void* aUserData) = 0;
|
||||
|
||||
// Commands
|
||||
//
|
||||
@@ -43,10 +44,10 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
void HandleSvc(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU, void* aUserData);
|
||||
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU, BluetoothSocketResultHandler* aRes);
|
||||
nsresult Send(DaemonSocketPDU* aPDU, BluetoothSocketResultHandler* aRes);
|
||||
|
||||
private:
|
||||
class AcceptWatcher;
|
||||
@@ -58,32 +59,33 @@ private:
|
||||
// Responses
|
||||
//
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothSocketResultHandler, void>
|
||||
typedef mozilla::ipc::DaemonResultRunnable0<
|
||||
BluetoothSocketResultHandler, void>
|
||||
ResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothSocketResultHandler, void,
|
||||
int, int>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothSocketResultHandler, void, int, int>
|
||||
IntResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothSocketResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
typedef mozilla::ipc::DaemonResultRunnable1<
|
||||
BluetoothSocketResultHandler, void, BluetoothStatus, BluetoothStatus>
|
||||
ErrorRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable3<BluetoothSocketResultHandler, void,
|
||||
int, nsString, int,
|
||||
int, const nsAString_internal&, int>
|
||||
typedef mozilla::ipc::DaemonResultRunnable3<
|
||||
BluetoothSocketResultHandler, void, int, nsString, int, int,
|
||||
const nsAString_internal&, int>
|
||||
IntStringIntResultRunnable;
|
||||
|
||||
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothSocketResultHandler* aRes);
|
||||
|
||||
void ListenRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ListenRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothSocketResultHandler* aRes);
|
||||
|
||||
void ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void ConnectRsp(const DaemonSocketPDUHeader& aHeader,
|
||||
DaemonSocketPDU& aPDU,
|
||||
BluetoothSocketResultHandler* aRes);
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@ typedef
|
||||
BluetoothHALInterfaceRunnable0<BluetoothGattClientResultHandler, void>
|
||||
BluetoothGattClientHALResultRunnable;
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable1<BluetoothGattClientResultHandler, void,
|
||||
BluetoothTypeOfDevice, BluetoothTypeOfDevice>
|
||||
BluetoothGattClientGetDeviceTypeHALResultRunnable;
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable1<BluetoothGattClientResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
@@ -82,6 +87,35 @@ DispatchBluetoothGattServerHALResult(
|
||||
return rv;
|
||||
}
|
||||
|
||||
template <typename ResultRunnable, typename Tin1, typename Arg1>
|
||||
static nsresult
|
||||
DispatchBluetoothGattClientHALResult(
|
||||
BluetoothGattClientResultHandler* aRes,
|
||||
void (BluetoothGattClientResultHandler::*aMethod)(Arg1),
|
||||
Tin1 aArg1,
|
||||
BluetoothStatus aStatus)
|
||||
{
|
||||
MOZ_ASSERT(aRes);
|
||||
|
||||
nsRunnable* runnable;
|
||||
Arg1 arg1;
|
||||
|
||||
if (aStatus != STATUS_SUCCESS) {
|
||||
runnable = new BluetoothGattClientHALErrorRunnable(aRes,
|
||||
&BluetoothGattClientResultHandler::OnError, aStatus);
|
||||
} else if (NS_FAILED(Convert(aArg1, arg1))) {
|
||||
runnable = new BluetoothGattClientHALErrorRunnable(aRes,
|
||||
&BluetoothGattClientResultHandler::OnError, STATUS_PARM_INVALID);
|
||||
} else {
|
||||
runnable = new ResultRunnable(aRes, aMethod, arg1);
|
||||
}
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
DispatchBluetoothGattHALResult(
|
||||
BluetoothGattResultHandler* aRes,
|
||||
@@ -470,10 +504,10 @@ struct BluetoothGattServerCallback
|
||||
int, int, const nsAString&, int, int, bool>
|
||||
RequestReadNotification;
|
||||
|
||||
typedef BluetoothNotificationHALRunnable8<
|
||||
typedef BluetoothNotificationHALRunnable9<
|
||||
GattServerNotificationHandlerWrapper, void,
|
||||
int, int, nsString, int, int, nsTArray<uint8_t>, bool, bool,
|
||||
int, int, const nsAString&, int, int, const nsTArray<uint8_t>&, bool, bool>
|
||||
int, int, nsString, int, int, int, nsAutoArrayPtr<uint8_t>, bool, bool,
|
||||
int, int, const nsAString&, int, int, int, const uint8_t*, bool, bool>
|
||||
RequestWriteNotification;
|
||||
|
||||
typedef BluetoothNotificationHALRunnable4<
|
||||
@@ -599,12 +633,10 @@ struct BluetoothGattServerCallback
|
||||
int aAttrHandle, int aOffset, int aLength,
|
||||
bool aNeedRsp, bool aIsPrep, uint8_t* aValue)
|
||||
{
|
||||
nsTArray<uint8_t> value;
|
||||
value.AppendElements(aValue, aLength);
|
||||
RequestWriteNotification::Dispatch(
|
||||
&BluetoothGattServerNotificationHandler::RequestWriteNotification,
|
||||
aConnId, aTransId, *aBdAddr, aAttrHandle, aOffset, value, aNeedRsp,
|
||||
aIsPrep);
|
||||
aConnId, aTransId, *aBdAddr, aAttrHandle, aOffset, aLength,
|
||||
ConvertArray<uint8_t>(aValue, aLength), aNeedRsp, aIsPrep);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1210,22 +1242,23 @@ void
|
||||
BluetoothGattClientHALInterface::GetDeviceType(
|
||||
const nsAString& aBdAddr, BluetoothGattClientResultHandler* aRes)
|
||||
{
|
||||
int status;
|
||||
int status = BT_STATUS_FAIL;
|
||||
bt_device_type_t type = BT_DEVICE_DEVTYPE_BLE;
|
||||
#if ANDROID_VERSION >= 19
|
||||
bt_bdaddr_t bdAddr;
|
||||
|
||||
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
|
||||
status = mInterface->get_device_type(&bdAddr);
|
||||
} else {
|
||||
status = BT_STATUS_PARM_INVALID;
|
||||
status = BT_STATUS_SUCCESS;
|
||||
type = static_cast<bt_device_type_t>(mInterface->get_device_type(&bdAddr));
|
||||
}
|
||||
#else
|
||||
status = BT_STATUS_UNSUPPORTED;
|
||||
#endif
|
||||
|
||||
if (aRes) {
|
||||
DispatchBluetoothGattClientHALResult(
|
||||
aRes, &BluetoothGattClientResultHandler::GetDeviceType,
|
||||
DispatchBluetoothGattClientHALResult<
|
||||
BluetoothGattClientGetDeviceTypeHALResultRunnable>(
|
||||
aRes, &BluetoothGattClientResultHandler::GetDeviceType, type,
|
||||
ConvertDefault(status, STATUS_FAIL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace {
|
||||
StaticRefPtr<BluetoothGattManager> sBluetoothGattManager;
|
||||
static BluetoothGattInterface* sBluetoothGattInterface;
|
||||
static BluetoothGattClientInterface* sBluetoothGattClientInterface;
|
||||
static BluetoothGattServerInterface* sBluetoothGattServerInterface;
|
||||
} // anonymous namespace
|
||||
|
||||
bool BluetoothGattManager::mInShutdown = false;
|
||||
@@ -306,6 +307,10 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
|
||||
sBluetoothGattInterface->GetBluetoothGattClientInterface();
|
||||
NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
|
||||
|
||||
sBluetoothGattServerInterface =
|
||||
sBluetoothGattInterface->GetBluetoothGattServerInterface();
|
||||
NS_ENSURE_TRUE_VOID(sBluetoothGattServerInterface);
|
||||
|
||||
if (!sClients) {
|
||||
sClients = new nsTArray<nsRefPtr<BluetoothGattClient> >;
|
||||
}
|
||||
@@ -335,6 +340,7 @@ public:
|
||||
void Cleanup() override
|
||||
{
|
||||
sBluetoothGattClientInterface = nullptr;
|
||||
sBluetoothGattServerInterface = nullptr;
|
||||
sBluetoothGattInterface = nullptr;
|
||||
sClients = nullptr;
|
||||
|
||||
@@ -479,7 +485,10 @@ BluetoothGattManager::UnregisterClient(int aClientIf,
|
||||
|
||||
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
|
||||
ClientIfComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
client->mUnregisterClientRunnable = aRunnable;
|
||||
@@ -522,8 +531,7 @@ public:
|
||||
gattManager->UnregisterClient(mClient->mClientIf, result);
|
||||
}
|
||||
|
||||
DispatchReplyError(mClient->mStartLeScanRunnable,
|
||||
BluetoothValue(mClient->mAppUuid));
|
||||
DispatchReplyError(mClient->mStartLeScanRunnable, aStatus);
|
||||
mClient->mStartLeScanRunnable = nullptr;
|
||||
}
|
||||
|
||||
@@ -581,7 +589,7 @@ BluetoothGattManager::StartLeScan(const nsTArray<nsString>& aServiceUuids,
|
||||
size_t index = sClients->IndexOf(appUuidStr, 0 /* Start */, UuidComparator());
|
||||
|
||||
// Reject the startLeScan request if the clientIf is being used.
|
||||
if (index != sClients->NoIndex) {
|
||||
if (NS_WARN_IF(index != sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable,
|
||||
NS_LITERAL_STRING("start LE scan failed"));
|
||||
return;
|
||||
@@ -739,7 +747,10 @@ BluetoothGattManager::Disconnect(const nsAString& aAppUuid,
|
||||
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
client->mDisconnectRunnable = aRunnable;
|
||||
@@ -783,7 +794,10 @@ BluetoothGattManager::Discover(const nsAString& aAppUuid,
|
||||
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
MOZ_ASSERT(client->mConnId > 0);
|
||||
@@ -852,7 +866,10 @@ BluetoothGattManager::ReadRemoteRssi(int aClientIf,
|
||||
|
||||
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
|
||||
ClientIfComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
client->mReadRemoteRssiRunnable = aRunnable;
|
||||
@@ -916,7 +933,10 @@ BluetoothGattManager::RegisterNotifications(
|
||||
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
@@ -989,7 +1009,10 @@ BluetoothGattManager::DeregisterNotifications(
|
||||
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
@@ -1050,9 +1073,7 @@ BluetoothGattManager::ReadCharacteristicValue(
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
// Reject the read characteristic value request
|
||||
DispatchReplyError(aRunnable,
|
||||
NS_LITERAL_STRING("ReadCharacteristicValue failed"));
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1132,9 +1153,7 @@ BluetoothGattManager::WriteCharacteristicValue(
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
// Reject the write characteristic value request
|
||||
DispatchReplyError(aRunnable,
|
||||
NS_LITERAL_STRING("WriteCharacteristicValue failed"));
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1215,9 +1234,7 @@ BluetoothGattManager::ReadDescriptorValue(
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
// Reject the read descriptor value request
|
||||
DispatchReplyError(aRunnable,
|
||||
NS_LITERAL_STRING("ReadDescriptorValue failed"));
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1298,9 +1315,7 @@ BluetoothGattManager::WriteDescriptorValue(
|
||||
|
||||
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
|
||||
if (NS_WARN_IF(index == sClients->NoIndex)) {
|
||||
// Reject the write descriptor value request
|
||||
DispatchReplyError(aRunnable,
|
||||
NS_LITERAL_STRING("WriteDescriptorValue failed"));
|
||||
DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1352,7 +1367,8 @@ BluetoothGattManager::RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
UuidToString(aAppUuid, uuid);
|
||||
|
||||
size_t index = sClients->IndexOf(uuid, 0 /* Start */, UuidComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
@@ -1406,6 +1422,53 @@ BluetoothGattManager::RegisterClientNotification(BluetoothGattStatus aStatus,
|
||||
}
|
||||
}
|
||||
|
||||
class BluetoothGattManager::ScanDeviceTypeResultHandler final
|
||||
: public BluetoothGattClientResultHandler
|
||||
{
|
||||
public:
|
||||
ScanDeviceTypeResultHandler(const nsAString& aBdAddr, int aRssi,
|
||||
const BluetoothGattAdvData& aAdvData)
|
||||
: mBdAddr(aBdAddr)
|
||||
, mRssi(static_cast<int32_t>(aRssi))
|
||||
{
|
||||
mAdvData.AppendElements(aAdvData.mAdvData, sizeof(aAdvData.mAdvData));
|
||||
}
|
||||
|
||||
void GetDeviceType(BluetoothTypeOfDevice type)
|
||||
{
|
||||
DistributeSignalDeviceFound(type);
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
DistributeSignalDeviceFound(TYPE_OF_DEVICE_BLE);
|
||||
}
|
||||
|
||||
private:
|
||||
void DistributeSignalDeviceFound(BluetoothTypeOfDevice type)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> properties;
|
||||
|
||||
BT_APPEND_NAMED_VALUE(properties, "Address", mBdAddr);
|
||||
BT_APPEND_NAMED_VALUE(properties, "Rssi", mRssi);
|
||||
BT_APPEND_NAMED_VALUE(properties, "GattAdv", mAdvData);
|
||||
BT_APPEND_NAMED_VALUE(properties, "Type", static_cast<uint32_t>(type));
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("LeDeviceFound"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(properties));
|
||||
}
|
||||
|
||||
nsString mBdAddr;
|
||||
int32_t mRssi;
|
||||
nsTArray<uint8_t> mAdvData;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothGattManager::ScanResultNotification(
|
||||
const nsAString& aBdAddr, int aRssi,
|
||||
@@ -1413,21 +1476,13 @@ BluetoothGattManager::ScanResultNotification(
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> properties;
|
||||
NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
|
||||
|
||||
nsTArray<uint8_t> advData;
|
||||
advData.AppendElements(aAdvData.mAdvData, sizeof(aAdvData.mAdvData));
|
||||
|
||||
BT_APPEND_NAMED_VALUE(properties, "Address", nsString(aBdAddr));
|
||||
BT_APPEND_NAMED_VALUE(properties, "Rssi", static_cast<int32_t>(aRssi));
|
||||
BT_APPEND_NAMED_VALUE(properties, "GattAdv", advData);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("LeDeviceFound"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(properties));
|
||||
// Distribute "LeDeviceFound" signal after we know the corresponding
|
||||
// BluetoothTypeOfDevice of the device
|
||||
sBluetoothGattClientInterface->GetDeviceType(
|
||||
aBdAddr,
|
||||
new ScanDeviceTypeResultHandler(aBdAddr, aRssi, aAdvData));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1443,7 +1498,8 @@ BluetoothGattManager::ConnectNotification(int aConnId,
|
||||
|
||||
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
|
||||
ClientIfComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
if (aStatus != GATT_STATUS_SUCCESS) {
|
||||
@@ -1494,7 +1550,8 @@ BluetoothGattManager::DisconnectNotification(int aConnId,
|
||||
|
||||
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
|
||||
ClientIfComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
if (aStatus != GATT_STATUS_SUCCESS) {
|
||||
@@ -1540,7 +1597,7 @@ BluetoothGattManager::SearchCompleteNotification(int aConnId,
|
||||
|
||||
size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
|
||||
ConnIdComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
MOZ_ASSERT(client->mDiscoverRunnable);
|
||||
@@ -1577,7 +1634,7 @@ BluetoothGattManager::SearchResultNotification(
|
||||
|
||||
size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
|
||||
ConnIdComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
// Save to mServices for distributing to application and discovering
|
||||
// included services, characteristics of this service later
|
||||
@@ -1598,7 +1655,7 @@ BluetoothGattManager::GetCharacteristicNotification(
|
||||
|
||||
size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
|
||||
ConnIdComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
MOZ_ASSERT(client->mDiscoverRunnable);
|
||||
@@ -1624,13 +1681,15 @@ BluetoothGattManager::GetCharacteristicNotification(
|
||||
aCharId,
|
||||
new DiscoverResultHandler(client));
|
||||
} else { // all characteristics of this service are discovered
|
||||
// Notify BluetoothGattService to create characteristics then proceed
|
||||
nsString path;
|
||||
GeneratePathFromGattId(aServiceId.mId, path);
|
||||
// Notify BluetoothGatt to make BluetoothGattService create characteristics
|
||||
// then proceed
|
||||
nsTArray<BluetoothNamedValue> values;
|
||||
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
|
||||
BT_APPEND_NAMED_VALUE(values, "characteristics", client->mCharacteristics);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("CharacteristicsDiscovered"),
|
||||
path,
|
||||
BluetoothValue(client->mCharacteristics));
|
||||
client->mAppUuid,
|
||||
BluetoothValue(values));
|
||||
|
||||
ProceedDiscoverProcess(client, aServiceId);
|
||||
}
|
||||
@@ -1650,7 +1709,7 @@ BluetoothGattManager::GetDescriptorNotification(
|
||||
|
||||
size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
|
||||
ConnIdComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
MOZ_ASSERT(client->mDiscoverRunnable);
|
||||
@@ -1668,13 +1727,16 @@ BluetoothGattManager::GetDescriptorNotification(
|
||||
aDescriptorId,
|
||||
new DiscoverResultHandler(client));
|
||||
} else { // all descriptors of this characteristic are discovered
|
||||
// Notify BluetoothGattCharacteristic to create descriptors then proceed
|
||||
nsString path;
|
||||
GeneratePathFromGattId(aCharId, path);
|
||||
// Notify BluetoothGatt to make BluetoothGattCharacteristic create
|
||||
// descriptors then proceed
|
||||
nsTArray<BluetoothNamedValue> values;
|
||||
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
|
||||
BT_APPEND_NAMED_VALUE(values, "characteristicId", aCharId);
|
||||
BT_APPEND_NAMED_VALUE(values, "descriptors", client->mDescriptors);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("DescriptorsDiscovered"),
|
||||
path,
|
||||
BluetoothValue(client->mDescriptors));
|
||||
client->mAppUuid,
|
||||
BluetoothValue(values));
|
||||
client->mDescriptors.Clear();
|
||||
|
||||
ProceedDiscoverProcess(client, aServiceId);
|
||||
@@ -1694,7 +1756,7 @@ BluetoothGattManager::GetIncludedServiceNotification(
|
||||
|
||||
size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
|
||||
ConnIdComparator());
|
||||
MOZ_ASSERT(index != sClients->NoIndex);
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
MOZ_ASSERT(client->mDiscoverRunnable);
|
||||
@@ -1711,13 +1773,16 @@ BluetoothGattManager::GetIncludedServiceNotification(
|
||||
aIncludedServId,
|
||||
new DiscoverResultHandler(client));
|
||||
} else { // all included services of this service are discovered
|
||||
// Notify BluetoothGattService to create included services
|
||||
nsString path;
|
||||
GeneratePathFromGattId(aServiceId.mId, path);
|
||||
// Notify BluetoothGatt to make BluetoothGattService create included
|
||||
// services
|
||||
nsTArray<BluetoothNamedValue> values;
|
||||
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
|
||||
BT_APPEND_NAMED_VALUE(values, "includedServices",
|
||||
client->mIncludedServices);
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING("IncludedServicesDiscovered"),
|
||||
path,
|
||||
BluetoothValue(client->mIncludedServices));
|
||||
client->mAppUuid,
|
||||
BluetoothValue(values));
|
||||
client->mIncludedServices.Clear();
|
||||
|
||||
// Start to discover characteristics of this service
|
||||
@@ -2012,6 +2077,7 @@ BluetoothGattManager::ReadRemoteRssiNotification(int aClientIf,
|
||||
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
|
||||
ClientIfComparator());
|
||||
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
|
||||
|
||||
if (aStatus != GATT_STATUS_SUCCESS) { // operation failed
|
||||
|
||||
@@ -110,6 +110,7 @@ private:
|
||||
class WriteCharacteristicValueResultHandler;
|
||||
class ReadDescriptorValueResultHandler;
|
||||
class WriteDescriptorValueResultHandler;
|
||||
class ScanDeviceTypeResultHandler;
|
||||
|
||||
BluetoothGattManager();
|
||||
|
||||
|
||||
@@ -233,15 +233,35 @@ Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut)
|
||||
nsresult
|
||||
Convert(const BluetoothGattId& aIn, btgatt_gatt_id_t& aOut)
|
||||
{
|
||||
nsresult rv = Convert(aIn.mUuid, aOut.uuid);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// HAL uses reversed UUID for GATT
|
||||
for (uint8_t i = 0; i < sizeof(aOut.uuid.uu) / 2; i++) {
|
||||
auto temp = aOut.uuid.uu[i];
|
||||
aOut.uuid.uu[i] = aOut.uuid.uu[sizeof(aOut.uuid.uu) - i - 1];
|
||||
aOut.uuid.uu[sizeof(aOut.uuid.uu) - i - 1] = temp;
|
||||
}
|
||||
aOut.inst_id = aIn.mInstanceId;
|
||||
return Convert(aIn.mUuid, aOut.uuid);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(const btgatt_gatt_id_t& aIn, BluetoothGattId& aOut)
|
||||
{
|
||||
nsresult rv = Convert(aIn.uuid, aOut.mUuid);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
// HAL uses reversed UUID for GATT
|
||||
for (uint8_t i = 0; i < sizeof(aOut.mUuid.mUuid) / 2; i++) {
|
||||
auto temp = aOut.mUuid.mUuid[i];
|
||||
aOut.mUuid.mUuid[i] = aOut.mUuid.mUuid[sizeof(aOut.mUuid.mUuid) - i - 1];
|
||||
aOut.mUuid.mUuid[sizeof(aOut.mUuid.mUuid) - i - 1] = temp;
|
||||
}
|
||||
aOut.mInstanceId = aIn.inst_id;
|
||||
return Convert(aIn.uuid, aOut.mUuid);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@@ -1945,47 +1945,48 @@ private:
|
||||
template <typename ObjectWrapper, typename Res,
|
||||
typename Tin1, typename Tin2, typename Tin3,
|
||||
typename Tin4, typename Tin5, typename Tin6,
|
||||
typename Tin7, typename Tin8,
|
||||
typename Tin7, typename Tin8, typename Tin9,
|
||||
typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3,
|
||||
typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6,
|
||||
typename Arg7=Tin7, typename Arg8=Tin8>
|
||||
class BluetoothNotificationHALRunnable8 : public nsRunnable
|
||||
typename Arg7=Tin7, typename Arg8=Tin8, typename Arg9=Tin9>
|
||||
class BluetoothNotificationHALRunnable9 : public nsRunnable
|
||||
{
|
||||
public:
|
||||
typedef typename ObjectWrapper::ObjectType ObjectType;
|
||||
typedef BluetoothNotificationHALRunnable8<ObjectWrapper, Res,
|
||||
Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8,
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> SelfType;
|
||||
typedef BluetoothNotificationHALRunnable9<ObjectWrapper, Res,
|
||||
Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, Tin9,
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> SelfType;
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
static already_AddRefed<SelfType> Create(
|
||||
Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8),
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9),
|
||||
const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, const T8& aIn8)
|
||||
const T7& aIn7, const T8& aIn8, const T9& aIn9)
|
||||
{
|
||||
nsRefPtr<SelfType> runnable(new SelfType(aMethod));
|
||||
|
||||
if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4, aIn5,
|
||||
aIn6, aIn7, aIn8))) {
|
||||
aIn6, aIn7, aIn8, aIn9))) {
|
||||
return nullptr;
|
||||
}
|
||||
return runnable.forget();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
static void
|
||||
Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7,
|
||||
Arg8),
|
||||
Arg8, Arg9),
|
||||
const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, const T8& aIn8)
|
||||
const T7& aIn7, const T8& aIn8, const T9& aIn9)
|
||||
{
|
||||
nsRefPtr<SelfType> runnable = Create(aMethod,
|
||||
aIn1, aIn2, aIn3, aIn4, aIn5, aIn6,
|
||||
aIn7, aIn8);
|
||||
aIn7, aIn8, aIn9);
|
||||
if (!runnable) {
|
||||
BT_WARNING("BluetoothNotificationHALRunnable8::Create failed");
|
||||
return;
|
||||
@@ -2006,25 +2007,27 @@ public:
|
||||
if (!obj) {
|
||||
BT_WARNING("Notification handler not initialized");
|
||||
} else {
|
||||
((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6, mArg7, mArg8);
|
||||
((*obj).*mMethod)(
|
||||
mArg1, mArg2, mArg3, mArg4, mArg5, mArg6, mArg7, mArg8, mArg9);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothNotificationHALRunnable8(
|
||||
Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8))
|
||||
BluetoothNotificationHALRunnable9(
|
||||
Res (ObjectType::*aMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9))
|
||||
: mMethod(aMethod)
|
||||
{
|
||||
MOZ_ASSERT(mMethod);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
typename T6, typename T7, typename T8, typename T9>
|
||||
nsresult
|
||||
ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, const T8& aIn8)
|
||||
const T7& aIn7, const T8& aIn8, const T9& aIn9)
|
||||
{
|
||||
nsresult rv = Convert(aIn1, mArg1);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -2058,10 +2061,15 @@ private:
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Convert(aIn9, mArg9);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
|
||||
Res (ObjectType::*mMethod)(
|
||||
Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
|
||||
Tin1 mArg1;
|
||||
Tin2 mArg2;
|
||||
Tin3 mArg3;
|
||||
@@ -2070,6 +2078,7 @@ private:
|
||||
Tin6 mArg6;
|
||||
Tin7 mArg7;
|
||||
Tin8 mArg8;
|
||||
Tin9 mArg9;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -5,18 +5,15 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BluetoothSocket.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
@@ -43,7 +40,7 @@ EnsureBluetoothSocketHalLoad()
|
||||
}
|
||||
|
||||
class mozilla::dom::bluetooth::DroidSocketImpl
|
||||
: public ipc::UnixFdWatcher
|
||||
: public mozilla::ipc::UnixFdWatcher
|
||||
, public DataSocketIO
|
||||
{
|
||||
public:
|
||||
@@ -74,16 +71,23 @@ public:
|
||||
SOCKET_IS_CONNECTED
|
||||
};
|
||||
|
||||
DroidSocketImpl(MessageLoop* aIOLoop, BluetoothSocket* aConsumer)
|
||||
: ipc::UnixFdWatcher(aIOLoop)
|
||||
DroidSocketImpl(MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop,
|
||||
BluetoothSocket* aConsumer)
|
||||
: mozilla::ipc::UnixFdWatcher(aIOLoop)
|
||||
, DataSocketIO(aConsumerLoop)
|
||||
, mConsumer(aConsumer)
|
||||
, mShuttingDownOnIOThread(false)
|
||||
, mConnectionStatus(SOCKET_IS_DISCONNECTED)
|
||||
{ }
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(DroidSocketImpl, DataSocketIO);
|
||||
}
|
||||
|
||||
~DroidSocketImpl()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
|
||||
MOZ_COUNT_DTOR_INHERITED(DroidSocketImpl, DataSocketIO);
|
||||
}
|
||||
|
||||
void Send(UnixSocketIOBuffer* aBuffer)
|
||||
@@ -110,7 +114,7 @@ public:
|
||||
|
||||
BluetoothSocket* GetBluetoothSocket()
|
||||
{
|
||||
return mConsumer.get();
|
||||
return mConsumer;
|
||||
}
|
||||
|
||||
DataSocket* GetDataSocket()
|
||||
@@ -119,11 +123,11 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
||||
* directly from main thread. All non-main-thread accesses should happen with
|
||||
* mImpl as container.
|
||||
* Consumer pointer. Non-thread-safe pointer, so should only be manipulated
|
||||
* directly from consumer thread. All non-consumer-thread accesses should
|
||||
* happen with mImpl as container.
|
||||
*/
|
||||
RefPtr<BluetoothSocket> mConsumer;
|
||||
BluetoothSocket* mConsumer;
|
||||
|
||||
// Methods for |DataSocket|
|
||||
//
|
||||
@@ -140,9 +144,10 @@ public:
|
||||
return GetDataSocket();
|
||||
}
|
||||
|
||||
bool IsShutdownOnMainThread() const override
|
||||
bool IsShutdownOnConsumerThread() const override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
|
||||
return mConsumer == nullptr;
|
||||
}
|
||||
|
||||
@@ -151,16 +156,17 @@ public:
|
||||
return mShuttingDownOnIOThread;
|
||||
}
|
||||
|
||||
void ShutdownOnMainThread() override
|
||||
void ShutdownOnConsumerThread() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsShutdownOnMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
MOZ_ASSERT(!IsShutdownOnConsumerThread());
|
||||
|
||||
mConsumer = nullptr;
|
||||
}
|
||||
|
||||
void ShutdownOnIOThread() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsConsumerThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
Close(); // will also remove fd from I/O loop
|
||||
@@ -168,7 +174,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
class ReceiveRunnable;
|
||||
class ReceiveTask;
|
||||
|
||||
/**
|
||||
* libevent triggered functions that reads data from socket when available and
|
||||
@@ -214,7 +220,7 @@ public:
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
|
||||
GetIO()->Connect(mFd);
|
||||
@@ -234,7 +240,7 @@ public:
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
||||
|
||||
if (!IsCanceled()) {
|
||||
GetIO()->Listen(mFd);
|
||||
@@ -254,7 +260,7 @@ class SocketConnectClientFdTask final
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
||||
|
||||
GetIO()->ConnectClientFd();
|
||||
}
|
||||
@@ -314,8 +320,8 @@ DroidSocketImpl::Accept(int aFd)
|
||||
SetFd(aFd);
|
||||
mConnectionStatus = SOCKET_IS_CONNECTED;
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
|
||||
GetConsumerThread()->PostTask(
|
||||
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
@@ -338,10 +344,10 @@ DroidSocketImpl::OnFileCanReadWithoutBlocking(int aFd)
|
||||
void
|
||||
DroidSocketImpl::OnSocketCanReceiveWithoutBlocking(int aFd)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsConsumerThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
ssize_t res = ReceiveData(aFd, this);
|
||||
ssize_t res = ReceiveData(aFd);
|
||||
if (res < 0) {
|
||||
/* I/O error */
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
@@ -361,7 +367,7 @@ public:
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
|
||||
GetIO()->Accept(mFd);
|
||||
@@ -383,11 +389,11 @@ public:
|
||||
void Accept(int aFd, const nsAString& aBdAddress,
|
||||
int aConnectionStatus) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
|
||||
mozilla::ScopedClose fd(aFd); // Close received socket fd on error
|
||||
|
||||
if (mImpl->IsShutdownOnMainThread()) {
|
||||
if (mImpl->IsShutdownOnConsumerThread()) {
|
||||
BT_LOGD("mConsumer is null, aborting receive!");
|
||||
return;
|
||||
}
|
||||
@@ -398,16 +404,16 @@ public:
|
||||
}
|
||||
|
||||
mImpl->mConsumer->SetAddress(aBdAddress);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new AcceptTask(mImpl, fd.forget()));
|
||||
mImpl->GetIOLoop()->PostTask(FROM_HERE,
|
||||
new AcceptTask(mImpl, fd.forget()));
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
BT_LOGR("BluetoothSocketInterface::Accept failed: %d", (int)aStatus);
|
||||
|
||||
if (!mImpl->IsShutdownOnMainThread()) {
|
||||
if (!mImpl->IsShutdownOnConsumerThread()) {
|
||||
// Instead of NotifyError(), call NotifyDisconnect() to trigger
|
||||
// BluetoothOppManager::OnSocketDisconnect() as
|
||||
// DroidSocketImpl::OnFileCanReadWithoutBlocking() in Firefox OS 2.0 in
|
||||
@@ -420,25 +426,23 @@ private:
|
||||
DroidSocketImpl* mImpl;
|
||||
};
|
||||
|
||||
class AcceptRunnable final : public SocketIORunnable<DroidSocketImpl>
|
||||
class InvokeAcceptTask final : public SocketTask<DroidSocketImpl>
|
||||
{
|
||||
public:
|
||||
AcceptRunnable(DroidSocketImpl* aImpl, int aFd)
|
||||
: SocketIORunnable<DroidSocketImpl>(aImpl)
|
||||
, mFd(aFd)
|
||||
InvokeAcceptTask(DroidSocketImpl* aImpl, int aFd)
|
||||
: SocketTask<DroidSocketImpl>(aImpl)
|
||||
, mFd(aFd)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetIO()->IsConsumerThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
|
||||
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
|
||||
GetIO()->mConsumer->SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -448,7 +452,7 @@ private:
|
||||
void
|
||||
DroidSocketImpl::OnSocketCanAcceptWithoutBlocking(int aFd)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsConsumerThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
/* When a listening socket is ready for receiving data,
|
||||
@@ -456,8 +460,7 @@ DroidSocketImpl::OnSocketCanAcceptWithoutBlocking(int aFd)
|
||||
*/
|
||||
|
||||
RemoveWatchers(READ_WATCHER);
|
||||
nsRefPtr<AcceptRunnable> t = new AcceptRunnable(this, aFd);
|
||||
NS_DispatchToMainThread(t);
|
||||
GetConsumerThread()->PostTask(FROM_HERE, new InvokeAcceptTask(this, aFd));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -475,11 +478,11 @@ DroidSocketImpl::OnFileCanWriteWithoutBlocking(int aFd)
|
||||
void
|
||||
DroidSocketImpl::OnSocketCanSendWithoutBlocking(int aFd)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsConsumerThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
MOZ_ASSERT(aFd >= 0);
|
||||
|
||||
nsresult rv = SendPendingData(aFd, this);
|
||||
nsresult rv = SendPendingData(aFd);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
@@ -492,7 +495,7 @@ DroidSocketImpl::OnSocketCanSendWithoutBlocking(int aFd)
|
||||
void
|
||||
DroidSocketImpl::OnSocketCanConnectWithoutBlocking(int aFd)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsConsumerThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
/* We follow Posix behaviour here: Connect operations are
|
||||
@@ -501,8 +504,8 @@ DroidSocketImpl::OnSocketCanConnectWithoutBlocking(int aFd)
|
||||
|
||||
mConnectionStatus = SOCKET_IS_CONNECTED;
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
|
||||
GetConsumerThread()->PostTask(
|
||||
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
@@ -528,35 +531,32 @@ DroidSocketImpl::QueryReceiveBuffer(
|
||||
|
||||
/**
|
||||
* |ReceiveRunnable| transfers data received on the I/O thread
|
||||
* to an instance of |BluetoothSocket| on the main thread.
|
||||
* to an instance of |BluetoothSocket| on the consumer thread.
|
||||
*/
|
||||
class DroidSocketImpl::ReceiveRunnable final
|
||||
: public SocketIORunnable<DroidSocketImpl>
|
||||
class DroidSocketImpl::ReceiveTask final : public SocketTask<DroidSocketImpl>
|
||||
{
|
||||
public:
|
||||
ReceiveRunnable(DroidSocketImpl* aIO, UnixSocketBuffer* aBuffer)
|
||||
: SocketIORunnable<DroidSocketImpl>(aIO)
|
||||
ReceiveTask(DroidSocketImpl* aIO, UnixSocketBuffer* aBuffer)
|
||||
: SocketTask<DroidSocketImpl>(aIO)
|
||||
, mBuffer(aBuffer)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DroidSocketImpl* io = SocketTask<DroidSocketImpl>::GetIO();
|
||||
|
||||
DroidSocketImpl* io = SocketIORunnable<DroidSocketImpl>::GetIO();
|
||||
MOZ_ASSERT(io->IsConsumerThread());
|
||||
|
||||
if (NS_WARN_IF(io->IsShutdownOnMainThread())) {
|
||||
if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
|
||||
// Since we've already explicitly closed and the close
|
||||
// happened before this, this isn't really an error.
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
|
||||
MOZ_ASSERT(bluetoothSocket);
|
||||
|
||||
bluetoothSocket->ReceiveSocketData(mBuffer);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -566,7 +566,8 @@ private:
|
||||
void
|
||||
DroidSocketImpl::ConsumeBuffer()
|
||||
{
|
||||
NS_DispatchToMainThread(new ReceiveRunnable(this, mBuffer.forget()));
|
||||
GetConsumerThread()->PostTask(FROM_HERE,
|
||||
new ReceiveTask(this, mBuffer.forget()));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -586,10 +587,17 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
|
||||
{
|
||||
MOZ_ASSERT(aObserver);
|
||||
|
||||
MOZ_COUNT_CTOR_INHERITED(BluetoothSocket, DataSocket);
|
||||
|
||||
EnsureBluetoothSocketHalLoad();
|
||||
mDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
|
||||
}
|
||||
|
||||
BluetoothSocket::~BluetoothSocket()
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(BluetoothSocket, DataSocket);
|
||||
}
|
||||
|
||||
class ConnectSocketResultHandler final : public BluetoothSocketResultHandler
|
||||
{
|
||||
public:
|
||||
@@ -602,9 +610,9 @@ public:
|
||||
void Connect(int aFd, const nsAString& aBdAddress,
|
||||
int aConnectionStatus) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
|
||||
if (mImpl->IsShutdownOnMainThread()) {
|
||||
if (mImpl->IsShutdownOnConsumerThread()) {
|
||||
BT_LOGD("mConsumer is null, aborting send!");
|
||||
return;
|
||||
}
|
||||
@@ -615,16 +623,16 @@ public:
|
||||
}
|
||||
|
||||
mImpl->mConsumer->SetAddress(aBdAddress);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new SocketConnectTask(mImpl, aFd));
|
||||
mImpl->GetIOLoop()->PostTask(FROM_HERE,
|
||||
new SocketConnectTask(mImpl, aFd));
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
BT_WARNING("Connect failed: %d", (int)aStatus);
|
||||
|
||||
if (!mImpl->IsShutdownOnMainThread()) {
|
||||
if (!mImpl->IsShutdownOnConsumerThread()) {
|
||||
// Instead of NotifyError(), call NotifyDisconnect() to trigger
|
||||
// BluetoothOppManager::OnSocketDisconnect() as
|
||||
// DroidSocketImpl::OnFileCanReadWithoutBlocking() in Firefox OS 2.0 in
|
||||
@@ -642,14 +650,15 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt)
|
||||
bool aAuth, bool aEncrypt,
|
||||
MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mImpl);
|
||||
|
||||
SetConnectionStatus(SOCKET_CONNECTING);
|
||||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
mImpl = new DroidSocketImpl(aConsumerLoop, aIOLoop, this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
@@ -662,6 +671,17 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothSocket::Connect(const nsAString& aDeviceAddress,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt)
|
||||
{
|
||||
return Connect(aDeviceAddress, aServiceUuid, aType, aChannel, aAuth,
|
||||
aEncrypt, MessageLoop::current(), XRE_GetIOMessageLoop());
|
||||
}
|
||||
|
||||
class ListenResultHandler final : public BluetoothSocketResultHandler
|
||||
{
|
||||
public:
|
||||
@@ -673,15 +693,14 @@ public:
|
||||
|
||||
void Listen(int aFd) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new SocketListenTask(mImpl, aFd));
|
||||
mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketListenTask(mImpl, aFd));
|
||||
}
|
||||
|
||||
void OnError(BluetoothStatus aStatus) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
|
||||
BT_WARNING("Listen failed: %d", (int)aStatus);
|
||||
}
|
||||
@@ -695,14 +714,15 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt)
|
||||
bool aAuth, bool aEncrypt,
|
||||
MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mImpl);
|
||||
|
||||
SetConnectionStatus(SOCKET_LISTENING);
|
||||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
mImpl = new DroidSocketImpl(aConsumerLoop, aIOLoop, this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
@@ -715,10 +735,20 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothSocket::Listen(const nsAString& aServiceName,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt)
|
||||
{
|
||||
return Listen(aServiceName, aServiceUuid, aType, aChannel, aAuth, aEncrypt,
|
||||
MessageLoop::current(), XRE_GetIOMessageLoop());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
mObserver->ReceiveSocketData(this, aBuffer);
|
||||
@@ -729,11 +759,11 @@ BluetoothSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
|
||||
void
|
||||
BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mImpl);
|
||||
MOZ_ASSERT(!mImpl->IsShutdownOnMainThread());
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
MOZ_ASSERT(!mImpl->IsShutdownOnConsumerThread());
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
mImpl->GetIOLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new SocketIOSendTask<DroidSocketImpl, UnixSocketIOBuffer>(mImpl, aBuffer));
|
||||
}
|
||||
@@ -743,12 +773,14 @@ BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
|
||||
void
|
||||
BluetoothSocket::Close()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
|
||||
if (!mImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mImpl->IsConsumerThread());
|
||||
|
||||
// Stop any watching |SocketMessageWatcher|
|
||||
if (mCurrentRes) {
|
||||
sBluetoothSocketInterface->Close(mCurrentRes);
|
||||
@@ -757,10 +789,8 @@ BluetoothSocket::Close()
|
||||
// From this point on, we consider mImpl as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
mImpl->ShutdownOnMainThread();
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mImpl));
|
||||
|
||||
mImpl->ShutdownOnConsumerThread();
|
||||
mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mImpl));
|
||||
mImpl = nullptr;
|
||||
|
||||
NotifyDisconnect();
|
||||
@@ -769,7 +799,6 @@ BluetoothSocket::Close()
|
||||
void
|
||||
BluetoothSocket::OnConnectSuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
@@ -779,7 +808,6 @@ BluetoothSocket::OnConnectSuccess()
|
||||
void
|
||||
BluetoothSocket::OnConnectError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
@@ -789,7 +817,6 @@ BluetoothSocket::OnConnectError()
|
||||
void
|
||||
BluetoothSocket::OnDisconnect()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
mObserver->OnSocketDisconnect(this);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "BluetoothCommon.h"
|
||||
#include "mozilla/ipc/DataSocket.h"
|
||||
|
||||
class MessageLoop;
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSocketObserver;
|
||||
@@ -20,6 +22,15 @@ class BluetoothSocket final : public mozilla::ipc::DataSocket
|
||||
{
|
||||
public:
|
||||
BluetoothSocket(BluetoothSocketObserver* aObserver);
|
||||
~BluetoothSocket();
|
||||
|
||||
nsresult Connect(const nsAString& aDeviceAddress,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt,
|
||||
MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop);
|
||||
|
||||
nsresult Connect(const nsAString& aDeviceAddress,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
@@ -27,6 +38,14 @@ public:
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt);
|
||||
|
||||
nsresult Listen(const nsAString& aServiceName,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt,
|
||||
MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop);
|
||||
|
||||
nsresult Listen(const nsAString& aServiceName,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
BluetoothSocketType aType,
|
||||
@@ -35,7 +54,7 @@ public:
|
||||
|
||||
/**
|
||||
* Method to be called whenever data is received. This is only called on the
|
||||
* main thread.
|
||||
* consumer thread.
|
||||
*
|
||||
* @param aBuffer Data received from the socket.
|
||||
*/
|
||||
|
||||
@@ -269,6 +269,77 @@ BluetoothGatt::HandleServicesDiscovered(const BluetoothValue& aValue)
|
||||
BluetoothGattBinding::ClearCachedServicesValue(this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleIncludedServicesDiscovered(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(values.Length() == 2); // ServiceId, IncludedServices
|
||||
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
|
||||
MOZ_ASSERT(values[0].value().type() ==
|
||||
BluetoothValue::TBluetoothGattServiceId);
|
||||
MOZ_ASSERT(values[1].name().EqualsLiteral("includedServices"));
|
||||
MOZ_ASSERT(values[1].value().type() ==
|
||||
BluetoothValue::TArrayOfBluetoothGattServiceId);
|
||||
|
||||
size_t index = mServices.IndexOf(
|
||||
values[0].value().get_BluetoothGattServiceId());
|
||||
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
|
||||
service->AssignIncludedServices(
|
||||
values[1].value().get_ArrayOfBluetoothGattServiceId());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleCharacteristicsDiscovered(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(values.Length() == 2); // ServiceId, Characteristics
|
||||
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
|
||||
MOZ_ASSERT(values[0].value().type() == BluetoothValue::TBluetoothGattServiceId);
|
||||
MOZ_ASSERT(values[1].name().EqualsLiteral("characteristics"));
|
||||
MOZ_ASSERT(values[1].value().type() ==
|
||||
BluetoothValue::TArrayOfBluetoothGattCharAttribute);
|
||||
|
||||
size_t index = mServices.IndexOf(
|
||||
values[0].value().get_BluetoothGattServiceId());
|
||||
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
|
||||
service->AssignCharacteristics(
|
||||
values[1].value().get_ArrayOfBluetoothGattCharAttribute());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleDescriptorsDiscovered(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
||||
|
||||
const InfallibleTArray<BluetoothNamedValue>& values =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
MOZ_ASSERT(values.Length() == 3); // ServiceId, CharacteristicId, Descriptors
|
||||
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
|
||||
MOZ_ASSERT(values[0].value().type() == BluetoothValue::TBluetoothGattServiceId);
|
||||
MOZ_ASSERT(values[1].name().EqualsLiteral("characteristicId"));
|
||||
MOZ_ASSERT(values[1].value().type() == BluetoothValue::TBluetoothGattId);
|
||||
MOZ_ASSERT(values[2].name().EqualsLiteral("descriptors"));
|
||||
MOZ_ASSERT(values[2].value().type() == BluetoothValue::TArrayOfBluetoothGattId);
|
||||
|
||||
size_t index = mServices.IndexOf(
|
||||
values[0].value().get_BluetoothGattServiceId());
|
||||
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
|
||||
|
||||
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
|
||||
service->AssignDescriptors(values[1].value().get_BluetoothGattId(),
|
||||
values[2].value().get_ArrayOfBluetoothGattId());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGatt::HandleCharacteristicChanged(const BluetoothValue& aValue)
|
||||
{
|
||||
@@ -336,6 +407,12 @@ BluetoothGatt::Notify(const BluetoothSignal& aData)
|
||||
}
|
||||
|
||||
mDiscoveringServices = false;
|
||||
} else if (aData.name().EqualsLiteral("IncludedServicesDiscovered")) {
|
||||
HandleIncludedServicesDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("CharacteristicsDiscovered")) {
|
||||
HandleCharacteristicsDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("DescriptorsDiscovered")) {
|
||||
HandleDescriptorsDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral(GATT_CHARACTERISTIC_CHANGED_ID)) {
|
||||
HandleCharacteristicChanged(v);
|
||||
} else {
|
||||
|
||||
@@ -96,6 +96,50 @@ private:
|
||||
*/
|
||||
void HandleServicesDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT included services into mIncludedServices of
|
||||
* BluetoothGattService and update the cache value of mIncludedServices.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothNamedValue. There are exact two elements in
|
||||
* the array. The first element uses 'serviceId' as the
|
||||
* name and uses BluetoothGattServiceId as the value. The
|
||||
* second element uses 'includedServices' as the name and
|
||||
* uses an array of BluetoothGattServiceId of all
|
||||
* discovered included services as the value.
|
||||
*/
|
||||
void HandleIncludedServicesDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT characteristics into mCharacteristics of
|
||||
* BluetoothGattService and update the cache value of mCharacteristics.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothNamedValue. There are exact two elements in
|
||||
* the array. The first element uses 'serviceId' as the
|
||||
* name and uses BluetoothGattServiceId as the value. The
|
||||
* second element uses 'characteristics' as the name and
|
||||
* uses an array of BluetoothGattCharAttribute of all
|
||||
* discovered characteristics as the value.
|
||||
*/
|
||||
void HandleCharacteristicsDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT descriptors into mDescriptors of
|
||||
* BluetoothGattCharacteristic and update the cache value of mDescriptors.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothNamedValue. There are exact three elements in
|
||||
* the array. The first element uses 'serviceId' as the
|
||||
* name and uses BluetoothGattServiceId as the value. The
|
||||
* second element uses 'characteristicId' as the name and
|
||||
* uses BluetoothGattId as the value. The third element
|
||||
* uses 'descriptors' as the name and uses an array of
|
||||
* BluetoothGattId of all discovered descriptors as the
|
||||
* value.
|
||||
*/
|
||||
void HandleDescriptorsDiscovered(const BluetoothValue& aValue);
|
||||
|
||||
/**
|
||||
* The value of a GATT characteristic has changed. In the mean time, the
|
||||
* cached value of this GATT characteristic has already been updated. An
|
||||
|
||||
@@ -68,10 +68,11 @@ BluetoothGattCharacteristic::BluetoothGattCharacteristic(
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(mService);
|
||||
|
||||
// Generate bluetooth signal path and a string representation to provide uuid
|
||||
// of this characteristic to applications
|
||||
UuidToString(mCharId.mUuid, mUuidStr);
|
||||
|
||||
// Generate bluetooth signal path of this characteristic to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mCharId, path, mUuidStr);
|
||||
GeneratePathFromGattId(mCharId, path);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
@@ -129,18 +130,13 @@ BluetoothGattCharacteristic::StopNotifications(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattCharacteristic::HandleDescriptorsDiscovered(
|
||||
const BluetoothValue& aValue)
|
||||
BluetoothGattCharacteristic::AssignDescriptors(
|
||||
const nsTArray<BluetoothGattId>& aDescriptorIds)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattId);
|
||||
|
||||
const InfallibleTArray<BluetoothGattId>& descriptorIds =
|
||||
aValue.get_ArrayOfBluetoothGattId();
|
||||
|
||||
mDescriptors.Clear();
|
||||
for (uint32_t i = 0; i < descriptorIds.Length(); i++) {
|
||||
for (uint32_t i = 0; i < aDescriptorIds.Length(); i++) {
|
||||
mDescriptors.AppendElement(new BluetoothGattDescriptor(
|
||||
GetParentObject(), this, descriptorIds[i]));
|
||||
GetParentObject(), this, aDescriptorIds[i]));
|
||||
}
|
||||
|
||||
BluetoothGattCharacteristicBinding::ClearCachedDescriptorsValue(this);
|
||||
@@ -162,9 +158,7 @@ BluetoothGattCharacteristic::Notify(const BluetoothSignal& aData)
|
||||
NS_ENSURE_TRUE_VOID(mSignalRegistered);
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("DescriptorsDiscovered")) {
|
||||
HandleDescriptorsDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("CharacteristicValueUpdated")) {
|
||||
if (aData.name().EqualsLiteral("CharacteristicValueUpdated")) {
|
||||
HandleCharacteristicValueUpdated(v);
|
||||
} else {
|
||||
BT_WARNING("Not handling GATT Characteristic signal: %s",
|
||||
|
||||
@@ -32,6 +32,7 @@ class BluetoothGattCharacteristic final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public BluetoothSignalObserver
|
||||
{
|
||||
friend class BluetoothGattService;
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattCharacteristic)
|
||||
@@ -106,10 +107,10 @@ private:
|
||||
* Add newly discovered GATT descriptors into mDescriptors and update the
|
||||
* cache value of mDescriptors.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothGattId of all discovered descriptors.
|
||||
* @param aDescriptorIds [in] An array of BluetoothGattId for each descriptor
|
||||
* that belongs to this characteristic.
|
||||
*/
|
||||
void HandleDescriptorsDiscovered(const BluetoothValue& aValue);
|
||||
void AssignDescriptors(const nsTArray<BluetoothGattId>& aDescriptorIds);
|
||||
|
||||
/**
|
||||
* Update the value of this characteristic.
|
||||
|
||||
@@ -63,10 +63,11 @@ BluetoothGattDescriptor::BluetoothGattDescriptor(
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(aCharacteristic);
|
||||
|
||||
// Generate bluetooth signal path and a string representation to provide uuid
|
||||
// of this descriptor to applications
|
||||
UuidToString(mDescriptorId.mUuid, mUuidStr);
|
||||
|
||||
// Generate bluetooth signal path of this descriptor to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mDescriptorId, path, mUuidStr);
|
||||
GeneratePathFromGattId(mDescriptorId, path);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,33 +17,10 @@ using namespace mozilla::dom;
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothGattService)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncludedServices)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCharacteristics)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
|
||||
/**
|
||||
* Unregister the bluetooth signal handler after unlinked.
|
||||
*
|
||||
* This is needed to avoid ending up with exposing a deleted object to JS or
|
||||
* accessing deleted objects while receiving signals from parent process
|
||||
* after unlinked. Please see Bug 1138267 for detail informations.
|
||||
*/
|
||||
nsString path;
|
||||
GeneratePathFromGattId(tmp->mServiceId.mId, path);
|
||||
UnregisterBluetoothSignalHandler(path, tmp);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncludedServices)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCharacteristics)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothGattService,
|
||||
mOwner,
|
||||
mIncludedServices,
|
||||
mCharacteristics)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothGattService)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(BluetoothGattService)
|
||||
@@ -62,72 +39,50 @@ BluetoothGattService::BluetoothGattService(
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(!mAppUuid.IsEmpty());
|
||||
|
||||
// Generate bluetooth signal path and a string representation to provide
|
||||
// uuid of this service to applications
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mServiceId.mId, path, mUuidStr);
|
||||
RegisterBluetoothSignalHandler(path, this);
|
||||
UuidToString(mServiceId.mId.mUuid, mUuidStr);
|
||||
}
|
||||
|
||||
BluetoothGattService::~BluetoothGattService()
|
||||
{
|
||||
nsString path;
|
||||
GeneratePathFromGattId(mServiceId.mId, path);
|
||||
UnregisterBluetoothSignalHandler(path, this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattService::HandleIncludedServicesDiscovered(
|
||||
const BluetoothValue& aValue)
|
||||
BluetoothGattService::AssignIncludedServices(
|
||||
const nsTArray<BluetoothGattServiceId>& aServiceIds)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattServiceId);
|
||||
|
||||
const InfallibleTArray<BluetoothGattServiceId>& includedServIds =
|
||||
aValue.get_ArrayOfBluetoothGattServiceId();
|
||||
|
||||
mIncludedServices.Clear();
|
||||
for (uint32_t i = 0; i < includedServIds.Length(); i++) {
|
||||
for (uint32_t i = 0; i < aServiceIds.Length(); i++) {
|
||||
mIncludedServices.AppendElement(new BluetoothGattService(
|
||||
GetParentObject(), mAppUuid, includedServIds[i]));
|
||||
GetParentObject(), mAppUuid, aServiceIds[i]));
|
||||
}
|
||||
|
||||
BluetoothGattServiceBinding::ClearCachedIncludedServicesValue(this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattService::HandleCharacteristicsDiscovered(
|
||||
const BluetoothValue& aValue)
|
||||
BluetoothGattService::AssignCharacteristics(
|
||||
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() ==
|
||||
BluetoothValue::TArrayOfBluetoothGattCharAttribute);
|
||||
|
||||
const InfallibleTArray<BluetoothGattCharAttribute>& characteristics =
|
||||
aValue.get_ArrayOfBluetoothGattCharAttribute();
|
||||
|
||||
mCharacteristics.Clear();
|
||||
for (uint32_t i = 0; i < characteristics.Length(); i++) {
|
||||
for (uint32_t i = 0; i < aCharacteristics.Length(); i++) {
|
||||
mCharacteristics.AppendElement(new BluetoothGattCharacteristic(
|
||||
GetParentObject(), this, characteristics[i]));
|
||||
GetParentObject(), this, aCharacteristics[i]));
|
||||
}
|
||||
|
||||
BluetoothGattServiceBinding::ClearCachedCharacteristicsValue(this);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothGattService::Notify(const BluetoothSignal& aData)
|
||||
BluetoothGattService::AssignDescriptors(
|
||||
const BluetoothGattId& aCharacteristicId,
|
||||
const nsTArray<BluetoothGattId>& aDescriptorIds)
|
||||
{
|
||||
BT_LOGD("[D] %s", NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
NS_ENSURE_TRUE_VOID(mSignalRegistered);
|
||||
size_t index = mCharacteristics.IndexOf(aCharacteristicId);
|
||||
NS_ENSURE_TRUE_VOID(index != mCharacteristics.NoIndex);
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("IncludedServicesDiscovered")) {
|
||||
HandleIncludedServicesDiscovered(v);
|
||||
} else if (aData.name().EqualsLiteral("CharacteristicsDiscovered")) {
|
||||
HandleCharacteristicsDiscovered(v);
|
||||
} else {
|
||||
BT_WARNING("Not handling GATT Service signal: %s",
|
||||
NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
}
|
||||
nsRefPtr<BluetoothGattCharacteristic> characteristic =
|
||||
mCharacteristics.ElementAt(index);
|
||||
characteristic->AssignDescriptors(aDescriptorIds);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothGatt;
|
||||
class BluetoothSignal;
|
||||
class BluetoothValue;
|
||||
|
||||
class BluetoothGattService final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public BluetoothSignalObserver
|
||||
{
|
||||
friend class BluetoothGatt;
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattService)
|
||||
@@ -71,8 +72,6 @@ public:
|
||||
return mServiceId;
|
||||
}
|
||||
|
||||
void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
@@ -92,20 +91,36 @@ private:
|
||||
* Add newly discovered GATT included services into mIncludedServices and
|
||||
* update the cache value of mIncludedServices.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothGattServiceId of all discovered included
|
||||
* services.
|
||||
* @param aServiceIds [in] An array of BluetoothGattServiceId for each
|
||||
* included service that belongs to this service.
|
||||
*/
|
||||
void HandleIncludedServicesDiscovered(const BluetoothValue& aValue);
|
||||
void AssignIncludedServices(
|
||||
const nsTArray<BluetoothGattServiceId>& aServiceIds);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT characteristics into mCharacteristics and
|
||||
* update the cache value of mCharacteristics.
|
||||
*
|
||||
* @param aValue [in] BluetoothValue which contains an array of
|
||||
* BluetoothGattId of all discovered characteristics.
|
||||
* @param aCharacteristics [in] An array of BluetoothGattCharAttribute for
|
||||
* each characteristic that belongs to this
|
||||
* service.
|
||||
*/
|
||||
void HandleCharacteristicsDiscovered(const BluetoothValue& aValue);
|
||||
void AssignCharacteristics(
|
||||
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics);
|
||||
|
||||
/**
|
||||
* Add newly discovered GATT descriptors into mDescriptors of
|
||||
* BluetoothGattCharacteristic and update the cache value of mDescriptors.
|
||||
*
|
||||
* @param aCharacteristicId [in] BluetoothGattId of a characteristic that
|
||||
* belongs to this service.
|
||||
* @param aDescriptorIds [in] An array of BluetoothGattId for each descriptor
|
||||
* that belongs to the characteristic referred by
|
||||
* aCharacteristicId.
|
||||
*/
|
||||
void AssignDescriptors(
|
||||
const BluetoothGattId& aCharacteristicId,
|
||||
const nsTArray<BluetoothGattId>& aDescriptorIds);
|
||||
|
||||
/****************************************************************************
|
||||
* Variables
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
#include <fcntl.h>
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "BluetoothUnixSocketConnector.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
@@ -28,7 +27,8 @@ class BluetoothSocket::BluetoothSocketIO final
|
||||
, public DataSocketIO
|
||||
{
|
||||
public:
|
||||
BluetoothSocketIO(MessageLoop* mIOLoop,
|
||||
BluetoothSocketIO(MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop,
|
||||
BluetoothSocket* aConsumer,
|
||||
UnixSocketConnector* aConnector);
|
||||
~BluetoothSocketIO();
|
||||
@@ -82,23 +82,23 @@ public:
|
||||
|
||||
SocketBase* GetSocketBase() override;
|
||||
|
||||
bool IsShutdownOnMainThread() const override;
|
||||
bool IsShutdownOnConsumerThread() const override;
|
||||
bool IsShutdownOnIOThread() const override;
|
||||
|
||||
void ShutdownOnMainThread() override;
|
||||
void ShutdownOnConsumerThread() override;
|
||||
void ShutdownOnIOThread() override;
|
||||
|
||||
private:
|
||||
class ReceiveRunnable;
|
||||
class ReceiveTask;
|
||||
|
||||
void FireSocketError();
|
||||
|
||||
/**
|
||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
||||
* directly from main thread. All non-main-thread accesses should happen with
|
||||
* mIO as container.
|
||||
* Consumer pointer. Non-thread-safe pointer, so should only be manipulated
|
||||
* directly from consumer thread. All non-consumer-thread accesses should
|
||||
* happen with mIO as container.
|
||||
*/
|
||||
RefPtr<BluetoothSocket> mConsumer;
|
||||
BluetoothSocket* mConsumer;
|
||||
|
||||
/**
|
||||
* Connector object used to create the connection we are currently using.
|
||||
@@ -121,7 +121,8 @@ private:
|
||||
struct sockaddr_storage mAddress;
|
||||
|
||||
/**
|
||||
* Task member for delayed connect task. Should only be access on main thread.
|
||||
* Task member for delayed connect task. Should only be access on consumer
|
||||
* thread.
|
||||
*/
|
||||
CancelableTask* mDelayedConnectTask;
|
||||
|
||||
@@ -132,10 +133,12 @@ private:
|
||||
};
|
||||
|
||||
BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
|
||||
MessageLoop* mIOLoop,
|
||||
MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop,
|
||||
BluetoothSocket* aConsumer,
|
||||
UnixSocketConnector* aConnector)
|
||||
: UnixSocketWatcher(mIOLoop)
|
||||
: UnixSocketWatcher(aIOLoop)
|
||||
, DataSocketIO(aConsumerLoop)
|
||||
, mConsumer(aConsumer)
|
||||
, mConnector(aConnector)
|
||||
, mShuttingDownOnIOThread(false)
|
||||
@@ -144,12 +147,16 @@ BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
|
||||
{
|
||||
MOZ_ASSERT(mConsumer);
|
||||
MOZ_ASSERT(mConnector);
|
||||
|
||||
MOZ_COUNT_CTOR_INHERITED(BluetoothSocketIO, DataSocketIO);
|
||||
}
|
||||
|
||||
BluetoothSocket::BluetoothSocketIO::~BluetoothSocketIO()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsShutdownOnMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
MOZ_ASSERT(IsShutdownOnConsumerThread());
|
||||
|
||||
MOZ_COUNT_DTOR_INHERITED(BluetoothSocketIO, DataSocketIO);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -176,7 +183,7 @@ BluetoothSocket::BluetoothSocketIO::GetSocketAddr(nsAString& aAddrStr) const
|
||||
BluetoothSocket*
|
||||
BluetoothSocket::BluetoothSocketIO::GetBluetoothSocket()
|
||||
{
|
||||
return mConsumer.get();
|
||||
return mConsumer;
|
||||
}
|
||||
|
||||
DataSocket*
|
||||
@@ -188,7 +195,7 @@ BluetoothSocket::BluetoothSocketIO::GetDataSocket()
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
|
||||
mDelayedConnectTask = aTask;
|
||||
}
|
||||
@@ -196,7 +203,7 @@ BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ClearDelayedConnectTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
|
||||
mDelayedConnectTask = nullptr;
|
||||
}
|
||||
@@ -204,7 +211,7 @@ BluetoothSocket::BluetoothSocketIO::ClearDelayedConnectTask()
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::CancelDelayedConnectTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
|
||||
if (!mDelayedConnectTask) {
|
||||
return;
|
||||
@@ -277,8 +284,8 @@ BluetoothSocket::BluetoothSocketIO::OnConnected()
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
|
||||
GetConsumerThread()->PostTask(
|
||||
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
@@ -326,8 +333,8 @@ BluetoothSocket::BluetoothSocketIO::OnSocketCanAcceptWithoutBlocking()
|
||||
Close();
|
||||
SetSocket(fd, SOCKET_IS_CONNECTED);
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
|
||||
GetConsumerThread()->PostTask(
|
||||
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_SUCCESS));
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
@@ -341,7 +348,7 @@ BluetoothSocket::BluetoothSocketIO::OnSocketCanReceiveWithoutBlocking()
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
|
||||
|
||||
ssize_t res = ReceiveData(GetFd(), this);
|
||||
ssize_t res = ReceiveData(GetFd());
|
||||
if (res < 0) {
|
||||
/* I/O error */
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
@@ -357,7 +364,7 @@ BluetoothSocket::BluetoothSocketIO::OnSocketCanSendWithoutBlocking()
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
|
||||
|
||||
nsresult rv = SendPendingData(GetFd(), this);
|
||||
nsresult rv = SendPendingData(GetFd());
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
@@ -375,10 +382,9 @@ BluetoothSocket::BluetoothSocketIO::FireSocketError()
|
||||
// Clean up watchers, statuses, fds
|
||||
Close();
|
||||
|
||||
// Tell the main thread we've errored
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
|
||||
|
||||
// Tell the consumer thread we've errored
|
||||
GetConsumerThread()->PostTask(
|
||||
FROM_HERE, new SocketEventTask(this, SocketEventTask::CONNECT_ERROR));
|
||||
}
|
||||
|
||||
// |DataSocketIO|
|
||||
@@ -398,36 +404,34 @@ BluetoothSocket::BluetoothSocketIO::QueryReceiveBuffer(
|
||||
}
|
||||
|
||||
/**
|
||||
* |ReceiveRunnable| transfers data received on the I/O thread
|
||||
* to an instance of |BluetoothSocket| on the main thread.
|
||||
* |ReceiveTask| transfers data received on the I/O thread
|
||||
* to an instance of |BluetoothSocket| on the consumer thread.
|
||||
*/
|
||||
class BluetoothSocket::BluetoothSocketIO::ReceiveRunnable final
|
||||
: public SocketIORunnable<BluetoothSocketIO>
|
||||
class BluetoothSocket::BluetoothSocketIO::ReceiveTask final
|
||||
: public SocketTask<BluetoothSocketIO>
|
||||
{
|
||||
public:
|
||||
ReceiveRunnable(BluetoothSocketIO* aIO, UnixSocketBuffer* aBuffer)
|
||||
: SocketIORunnable<BluetoothSocketIO>(aIO)
|
||||
ReceiveTask(BluetoothSocketIO* aIO, UnixSocketBuffer* aBuffer)
|
||||
: SocketTask<BluetoothSocketIO>(aIO)
|
||||
, mBuffer(aBuffer)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
BluetoothSocketIO* io = SocketTask<BluetoothSocketIO>::GetIO();
|
||||
|
||||
BluetoothSocketIO* io = SocketIORunnable<BluetoothSocketIO>::GetIO();
|
||||
MOZ_ASSERT(io->IsConsumerThread());
|
||||
|
||||
if (NS_WARN_IF(io->IsShutdownOnMainThread())) {
|
||||
if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) {
|
||||
// Since we've already explicitly closed and the close
|
||||
// happened before this, this isn't really an error.
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothSocket* bluetoothSocket = io->GetBluetoothSocket();
|
||||
MOZ_ASSERT(bluetoothSocket);
|
||||
|
||||
bluetoothSocket->ReceiveSocketData(mBuffer);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -437,7 +441,8 @@ private:
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ConsumeBuffer()
|
||||
{
|
||||
NS_DispatchToMainThread(new ReceiveRunnable(this, mBuffer.forget()));
|
||||
GetConsumerThread()->PostTask(FROM_HERE,
|
||||
new ReceiveTask(this, mBuffer.forget()));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -455,18 +460,18 @@ BluetoothSocket::BluetoothSocketIO::GetSocketBase()
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::BluetoothSocketIO::IsShutdownOnMainThread() const
|
||||
BluetoothSocket::BluetoothSocketIO::IsShutdownOnConsumerThread() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
|
||||
return mConsumer == nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ShutdownOnMainThread()
|
||||
BluetoothSocket::BluetoothSocketIO::ShutdownOnConsumerThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsShutdownOnMainThread());
|
||||
MOZ_ASSERT(IsConsumerThread());
|
||||
MOZ_ASSERT(!IsShutdownOnConsumerThread());
|
||||
|
||||
mConsumer = nullptr;
|
||||
}
|
||||
@@ -480,7 +485,7 @@ BluetoothSocket::BluetoothSocketIO::IsShutdownOnIOThread() const
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ShutdownOnIOThread()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsConsumerThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
Close(); // will also remove fd from I/O loop
|
||||
@@ -502,7 +507,7 @@ public:
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
||||
|
||||
if (!IsCanceled()) {
|
||||
GetIO()->Listen();
|
||||
@@ -520,7 +525,7 @@ public:
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!GetIO()->IsConsumerThread());
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
|
||||
GetIO()->Connect();
|
||||
@@ -537,19 +542,19 @@ public:
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetIO()->IsConsumerThread());
|
||||
|
||||
if (IsCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothSocketIO* io = GetIO();
|
||||
if (io->IsShutdownOnMainThread()) {
|
||||
if (io->IsShutdownOnConsumerThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
io->ClearDelayedConnectTask();
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ConnectTask(io));
|
||||
io->GetIOLoop()->PostTask(FROM_HERE, new ConnectTask(io));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -562,11 +567,15 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
|
||||
, mIO(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aObserver);
|
||||
|
||||
MOZ_COUNT_CTOR_INHERITED(BluetoothSocket, DataSocket);
|
||||
}
|
||||
|
||||
BluetoothSocket::~BluetoothSocket()
|
||||
{
|
||||
MOZ_ASSERT(!mIO);
|
||||
|
||||
MOZ_COUNT_DTOR_INHERITED(BluetoothSocket, DataSocket);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -576,7 +585,6 @@ BluetoothSocket::Connect(const nsAString& aDeviceAddress,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
||||
|
||||
nsAutoPtr<BluetoothUnixSocketConnector> connector(
|
||||
@@ -603,8 +611,6 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
|
||||
int aChannel,
|
||||
bool aAuth, bool aEncrypt)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<BluetoothUnixSocketConnector> connector(
|
||||
new BluetoothUnixSocketConnector(NS_LITERAL_CSTRING(BLUETOOTH_ADDRESS_NONE),
|
||||
aType, aChannel, aAuth, aEncrypt));
|
||||
@@ -625,7 +631,6 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
|
||||
void
|
||||
BluetoothSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
mObserver->ReceiveSocketData(this, aBuffer);
|
||||
@@ -645,39 +650,57 @@ BluetoothSocket::SendSocketData(const nsACString& aStr)
|
||||
|
||||
nsresult
|
||||
BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
|
||||
int aDelayMs)
|
||||
int aDelayMs,
|
||||
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(aConsumerLoop);
|
||||
MOZ_ASSERT(aIOLoop);
|
||||
MOZ_ASSERT(!mIO);
|
||||
|
||||
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
|
||||
mIO = new BluetoothSocketIO(ioLoop, this, aConnector);
|
||||
mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
|
||||
SetConnectionStatus(SOCKET_CONNECTING);
|
||||
|
||||
if (aDelayMs > 0) {
|
||||
DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
|
||||
mIO->SetDelayedConnectTask(connectTask);
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
|
||||
} else {
|
||||
ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
|
||||
aIOLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
|
||||
int aDelayMs)
|
||||
{
|
||||
return Connect(aConnector, aDelayMs, MessageLoop::current(),
|
||||
XRE_GetIOMessageLoop());
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector,
|
||||
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
|
||||
{
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(aConsumerLoop);
|
||||
MOZ_ASSERT(aIOLoop);
|
||||
MOZ_ASSERT(!mIO);
|
||||
|
||||
mIO = new BluetoothSocketIO(aConsumerLoop, aIOLoop, this, aConnector);
|
||||
SetConnectionStatus(SOCKET_LISTENING);
|
||||
|
||||
aIOLoop->PostTask(FROM_HERE, new ListenTask(mIO));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(!mIO);
|
||||
|
||||
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
|
||||
|
||||
mIO = new BluetoothSocketIO(ioLoop, this, aConnector);
|
||||
SetConnectionStatus(SOCKET_LISTENING);
|
||||
ioLoop->PostTask(FROM_HERE, new ListenTask(mIO));
|
||||
|
||||
return NS_OK;
|
||||
return Listen(aConnector, MessageLoop::current(), XRE_GetIOMessageLoop());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -696,11 +719,11 @@ BluetoothSocket::GetAddress(nsAString& aAddrStr)
|
||||
void
|
||||
BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIO);
|
||||
MOZ_ASSERT(!mIO->IsShutdownOnMainThread());
|
||||
MOZ_ASSERT(mIO->IsConsumerThread());
|
||||
MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread());
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
mIO->GetIOLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new SocketIOSendTask<BluetoothSocketIO, UnixSocketIOBuffer>(mIO, aBuffer));
|
||||
}
|
||||
@@ -710,20 +733,19 @@ BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
|
||||
void
|
||||
BluetoothSocket::Close()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mIO) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mIO->IsConsumerThread());
|
||||
|
||||
mIO->CancelDelayedConnectTask();
|
||||
|
||||
// From this point on, we consider mIO as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
mIO->ShutdownOnMainThread();
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
|
||||
|
||||
mIO->ShutdownOnConsumerThread();
|
||||
mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
|
||||
mIO = nullptr;
|
||||
|
||||
NotifyDisconnect();
|
||||
@@ -732,7 +754,6 @@ BluetoothSocket::Close()
|
||||
void
|
||||
BluetoothSocket::OnConnectSuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
mObserver->OnSocketConnectSuccess(this);
|
||||
}
|
||||
@@ -740,7 +761,6 @@ BluetoothSocket::OnConnectSuccess()
|
||||
void
|
||||
BluetoothSocket::OnConnectError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
mObserver->OnSocketConnectError(this);
|
||||
}
|
||||
@@ -748,7 +768,6 @@ BluetoothSocket::OnConnectError()
|
||||
void
|
||||
BluetoothSocket::OnDisconnect()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
mObserver->OnSocketDisconnect(this);
|
||||
}
|
||||
|
||||
@@ -8,13 +8,12 @@
|
||||
#define mozilla_dom_bluetooth_BluetoothSocket_h
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include <stdlib.h>
|
||||
#include "mozilla/ipc/DataSocket.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class MessageLoop;
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
@@ -41,7 +40,7 @@ public:
|
||||
|
||||
/**
|
||||
* Method to be called whenever data is received. This is only called on the
|
||||
* main thread.
|
||||
* consumer thread.
|
||||
*
|
||||
* @param aBuffer Data received from the socket.
|
||||
*/
|
||||
@@ -58,6 +57,19 @@ public:
|
||||
*/
|
||||
bool SendSocketData(const nsACString& aMessage);
|
||||
|
||||
/**
|
||||
* Starts a task on the socket that will try to connect to a socket in a
|
||||
* non-blocking manner.
|
||||
*
|
||||
* @param aConnector Connector object for socket type specific functions
|
||||
* @param aDelayMs Time delay in milli-seconds.
|
||||
* @param aConsumerLoop The socket's consumer thread.
|
||||
* @param aIOLoop The socket's I/O thread.
|
||||
* @return NS_OK on success, or an XPCOM error code otherwise.
|
||||
*/
|
||||
nsresult Connect(BluetoothUnixSocketConnector* aConnector, int aDelayMs,
|
||||
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
|
||||
|
||||
/**
|
||||
* Starts a task on the socket that will try to connect to a socket in a
|
||||
* non-blocking manner.
|
||||
@@ -69,6 +81,18 @@ public:
|
||||
nsresult Connect(BluetoothUnixSocketConnector* aConnector,
|
||||
int aDelayMs = 0);
|
||||
|
||||
/**
|
||||
* Starts a task on the socket that will try to accept a new connection in a
|
||||
* non-blocking manner.
|
||||
*
|
||||
* @param aConnector Connector object for socket type specific functions
|
||||
* @param aConsumerLoop The socket's consumer thread.
|
||||
* @param aIOLoop The socket's I/O thread.
|
||||
* @return NS_OK on success, or an XPCOM error code otherwise.
|
||||
*/
|
||||
nsresult Listen(BluetoothUnixSocketConnector* aConnector,
|
||||
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
|
||||
|
||||
/**
|
||||
* Starts a task on the socket that will try to accept a new connection in a
|
||||
* non-blocking manner.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
|
||||
#include "nsThreadUtils.h" // For NS_IsMainThread.
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
@@ -52,10 +53,14 @@ BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
|
||||
, mChannel(aChannel)
|
||||
, mAuth(aAuth)
|
||||
, mEncrypt(aEncrypt)
|
||||
{ }
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(BluetoothUnixSocketConnector, UnixSocketConnector);
|
||||
}
|
||||
|
||||
BluetoothUnixSocketConnector::~BluetoothUnixSocketConnector()
|
||||
{ }
|
||||
{
|
||||
MOZ_COUNT_DTOR_INHERITED(BluetoothUnixSocketConnector, UnixSocketConnector);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothUnixSocketConnector::CreateSocket(int& aFd) const
|
||||
|
||||
@@ -38,7 +38,8 @@ public:
|
||||
NS_INLINE_DECL_REFCOUNTING(BroadcastChannelMessage)
|
||||
|
||||
BroadcastChannelMessage()
|
||||
: StructuredCloneHelper(CloningSupported, TransferringNotSupported)
|
||||
: StructuredCloneHelper(CloningSupported, TransferringNotSupported,
|
||||
DifferentProcess)
|
||||
{}
|
||||
|
||||
private:
|
||||
@@ -502,14 +503,6 @@ BroadcastChannel::PostMessageInternal(JSContext* aCx,
|
||||
return;
|
||||
}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = data->BlobImpls();
|
||||
for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) {
|
||||
if (!blobImpls[i]->MayBeClonedToOtherThreads()) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PostMessageData(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
namespace mozilla {
|
||||
@@ -85,18 +85,17 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
|
||||
return true;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
ipc::StructuredCloneData cloneData;
|
||||
cloneData.BlobImpls().AppendElements(blobs);
|
||||
|
||||
const SerializedStructuredCloneBuffer& buffer = aData.data();
|
||||
StructuredCloneHelper cloneHelper(StructuredCloneHelper::CloningSupported,
|
||||
StructuredCloneHelper::TransferringNotSupported);
|
||||
|
||||
cloneHelper.BlobImpls().AppendElements(blobs);
|
||||
cloneData.UseExternalData(buffer.data, buffer.dataLength);
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx, JS::NullValue());
|
||||
if (buffer.dataLength) {
|
||||
ErrorResult rv;
|
||||
cloneHelper.ReadFromBuffer(mBC->GetParentObject(), cx,
|
||||
buffer.data, buffer.dataLength, &value, rv);
|
||||
cloneData.Read(cx, &value, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "imgTools.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "libyuv.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ ChannelInfo::InitFromChannel(nsIChannel* aChannel)
|
||||
}
|
||||
|
||||
void
|
||||
ChannelInfo::InitFromIPCChannelInfo(const ipc::IPCChannelInfo& aChannelInfo)
|
||||
ChannelInfo::InitFromIPCChannelInfo(const mozilla::ipc::IPCChannelInfo& aChannelInfo)
|
||||
{
|
||||
MOZ_ASSERT(!mInited, "Cannot initialize the object twice");
|
||||
|
||||
@@ -136,7 +136,7 @@ ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ipc::IPCChannelInfo
|
||||
mozilla::ipc::IPCChannelInfo
|
||||
ChannelInfo::AsIPCChannelInfo() const
|
||||
{
|
||||
// This may be called when mInited is false, for example if we try to store
|
||||
|
||||
@@ -159,6 +159,15 @@ public:
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::marginheight, aMarginHeight, aError);
|
||||
}
|
||||
void SetReferrer(const nsAString& aReferrer, ErrorResult& aError)
|
||||
{
|
||||
SetHTMLAttr(nsGkAtoms::referrer, aReferrer, aError);
|
||||
}
|
||||
void GetReferrer(nsAString& aReferrer)
|
||||
{
|
||||
GetHTMLAttr(nsGkAtoms::referrer, aReferrer);
|
||||
}
|
||||
|
||||
nsIDocument* GetSVGDocument()
|
||||
{
|
||||
return GetContentDocument();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "mozilla/dom/ContentBridgeChild.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
|
||||
@@ -76,7 +76,7 @@ ContentBridgeParent::RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals)
|
||||
nsTArray<StructuredCloneData>* aRetvals)
|
||||
{
|
||||
return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows),
|
||||
aPrincipal, aRetvals);
|
||||
|
||||
@@ -19,7 +19,6 @@ class ContentBridgeParent : public PContentBridgeParent
|
||||
, public nsIContentParent
|
||||
, public nsIObserver
|
||||
{
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
public:
|
||||
explicit ContentBridgeParent(Transport* aTransport);
|
||||
|
||||
@@ -83,7 +82,7 @@ protected:
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals) override;
|
||||
nsTArray<StructuredCloneData>* aRetvals) override;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
|
||||
@@ -174,13 +174,13 @@
|
||||
#endif
|
||||
|
||||
#include "ProcessUtils.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "URIUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsDeviceStorage.h"
|
||||
#include "DomainPolicy.h"
|
||||
#include "mozilla/dom/DataStoreService.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/dom/telephony/PTelephonyChild.h"
|
||||
#include "mozilla/dom/time/DateCacheCleaner.h"
|
||||
#include "mozilla/dom/voicemail/VoicemailIPCService.h"
|
||||
@@ -789,7 +789,7 @@ ContentChild::InitXPCOM()
|
||||
bool isConnected;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
OwningSerializedStructuredCloneBuffer initialData;
|
||||
StructuredCloneData initialData;
|
||||
|
||||
SendGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &mAvailableDictionaries,
|
||||
@@ -821,9 +821,10 @@ ContentChild::InitXPCOM()
|
||||
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
ErrorResult rv;
|
||||
JS::RootedValue data(jsapi.cx());
|
||||
if (!JS_ReadStructuredClone(jsapi.cx(), initialData.data, initialData.dataLength,
|
||||
JS_STRUCTURED_CLONE_VERSION, &data, nullptr, nullptr)) {
|
||||
initialData.Read(jsapi.cx(), &data, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
ProcessGlobal* global = ProcessGlobal::Get();
|
||||
@@ -2042,10 +2043,11 @@ ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
||||
{
|
||||
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::GetChildProcessManager();
|
||||
if (cpm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
||||
StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForChild(aData, data);
|
||||
CrossProcessCpowHolder cpows(this, aCpows);
|
||||
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()), nullptr,
|
||||
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||
aMsg, false, &data, &cpows, aPrincipal, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2834,4 +2836,3 @@ ContentChild::RecvTestGraphicsDeviceReset(const uint32_t& aResetReason)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
+10
-11
@@ -148,7 +148,6 @@
|
||||
#include "SandboxHal.h"
|
||||
#include "ScreenManagerParent.h"
|
||||
#include "SourceSurfaceRawData.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "TabParent.h"
|
||||
#include "URIUtils.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
@@ -159,6 +158,7 @@
|
||||
#include "prio.h"
|
||||
#include "private/pprio.h"
|
||||
#include "ContentProcessManager.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/psm/PSMContentListener.h"
|
||||
#include "nsPluginHost.h"
|
||||
#include "nsPluginTags.h"
|
||||
@@ -2904,7 +2904,7 @@ ContentParent::OnNewProcessCreated(uint32_t aPid,
|
||||
InfallibleTArray<nsString> unusedDictionaries;
|
||||
ClipboardCapabilities clipboardCaps;
|
||||
DomainPolicyClone domainPolicy;
|
||||
OwningSerializedStructuredCloneBuffer initialData;
|
||||
StructuredCloneData initialData;
|
||||
|
||||
RecvGetXPCOMProcessAttributes(&isOffline, &isConnected,
|
||||
&isLangRTL, &unusedDictionaries,
|
||||
@@ -3224,7 +3224,7 @@ ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
InfallibleTArray<nsString>* dictionaries,
|
||||
ClipboardCapabilities* clipboardCaps,
|
||||
DomainPolicyClone* domainPolicy,
|
||||
OwningSerializedStructuredCloneBuffer* initialData)
|
||||
StructuredCloneData* aInitialData)
|
||||
{
|
||||
nsCOMPtr<nsIIOService> io(do_GetIOService());
|
||||
MOZ_ASSERT(io, "No IO service?");
|
||||
@@ -3271,12 +3271,11 @@ ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
|
||||
return false;
|
||||
}
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (!buffer.write(jsapi.cx(), init)) {
|
||||
ErrorResult rv;
|
||||
aInitialData->Write(jsapi.cx(), init, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer.steal(&initialData->data, &initialData->dataLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4091,7 +4090,7 @@ ContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals)
|
||||
nsTArray<StructuredCloneData>* aRetvals)
|
||||
{
|
||||
return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows),
|
||||
aPrincipal, aRetvals);
|
||||
@@ -4102,7 +4101,7 @@ ContentParent::RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals)
|
||||
nsTArray<StructuredCloneData>* aRetvals)
|
||||
{
|
||||
return nsIContentParent::RecvRpcMessage(aMsg, aData, Move(aCpows), aPrincipal,
|
||||
aRetvals);
|
||||
@@ -4335,12 +4334,12 @@ ContentParent::DoLoadMessageManagerScript(const nsAString& aURL,
|
||||
bool
|
||||
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aHelper,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForParent(this, aData, data)) {
|
||||
if (!BuildClonedMessageDataForParent(this, aHelper, data)) {
|
||||
return false;
|
||||
}
|
||||
InfallibleTArray<CpowEntry> cpows;
|
||||
|
||||
@@ -82,7 +82,6 @@ class ContentParent final : public PContentParent
|
||||
typedef mozilla::ipc::TestShellParent TestShellParent;
|
||||
typedef mozilla::ipc::URIParams URIParams;
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
|
||||
public:
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
@@ -198,7 +197,7 @@ public:
|
||||
bool aRunInGlobalScope) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool CheckPermission(const nsAString& aPermission) override;
|
||||
@@ -568,7 +567,7 @@ private:
|
||||
InfallibleTArray<nsString>* dictionaries,
|
||||
ClipboardCapabilities* clipboardCaps,
|
||||
DomainPolicyClone* domainPolicy,
|
||||
OwningSerializedStructuredCloneBuffer* initialData) override;
|
||||
StructuredCloneData* initialData) override;
|
||||
|
||||
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) override;
|
||||
|
||||
@@ -724,12 +723,12 @@ private:
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals) override;
|
||||
nsTArray<StructuredCloneData>* aRetvals) override;
|
||||
virtual bool RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals) override;
|
||||
nsTArray<StructuredCloneData>* aRetvals) override;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
|
||||
@@ -63,7 +63,7 @@ using mozilla::WritingMode from "mozilla/WritingModes.h";
|
||||
using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h";
|
||||
using nsIWidget::TouchPointerState from "nsIWidget.h";
|
||||
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
|
||||
using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
|
||||
using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
|
||||
using mozilla::EventMessage from "mozilla/EventForwards.h";
|
||||
using nsEventStatus from "mozilla/EventForwards.h";
|
||||
using nsSizeMode from "nsIWidgetListener.h";
|
||||
@@ -180,11 +180,11 @@ parent:
|
||||
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (OwningSerializedStructuredCloneBuffer[] retval);
|
||||
returns (StructuredCloneData[] retval);
|
||||
|
||||
prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (OwningSerializedStructuredCloneBuffer[] retval);
|
||||
returns (StructuredCloneData[] retval);
|
||||
|
||||
/**
|
||||
* Notifies chrome that there is a focus change involving an editable
|
||||
|
||||
@@ -85,7 +85,7 @@ using gfxIntSize from "nsSize.h";
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
|
||||
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
|
||||
using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
|
||||
using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
@@ -676,7 +676,7 @@ parent:
|
||||
returns (bool isOffline, bool isConnected, bool isLangRTL, nsString[] dictionaries,
|
||||
ClipboardCapabilities clipboardCaps,
|
||||
DomainPolicyClone domainPolicy,
|
||||
OwningSerializedStructuredCloneBuffer initialData);
|
||||
StructuredCloneData initialData);
|
||||
|
||||
sync CreateChildProcess(IPCTabContext context,
|
||||
ProcessPriority priority,
|
||||
@@ -791,11 +791,11 @@ parent:
|
||||
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (OwningSerializedStructuredCloneBuffer[] retval);
|
||||
returns (StructuredCloneData[] retval);
|
||||
|
||||
prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (OwningSerializedStructuredCloneBuffer[] retval);
|
||||
returns (StructuredCloneData[] retval);
|
||||
|
||||
ShowAlertNotification(nsString imageUrl,
|
||||
nsString title,
|
||||
|
||||
@@ -16,7 +16,7 @@ include PTabContext;
|
||||
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
|
||||
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
|
||||
using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
|
||||
using struct mozilla::OwningSerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
|
||||
using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -40,7 +40,7 @@ prio(normal upto urgent) sync protocol PContentBridge
|
||||
parent:
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (OwningSerializedStructuredCloneBuffer[] retval);
|
||||
returns (StructuredCloneData[] retval);
|
||||
both:
|
||||
// Both the parent and the child can construct the PBrowser.
|
||||
// See the comment in PContent::PBrowser().
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "StructuredCloneData.h"
|
||||
|
||||
#include "nsIDOMDOMException.h"
|
||||
#include "nsIMutable.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "StructuredCloneTags.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace ipc {
|
||||
|
||||
bool
|
||||
StructuredCloneData::Copy(const StructuredCloneData& aData)
|
||||
{
|
||||
if (!aData.mData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t* data = static_cast<uint64_t*>(js_malloc(aData.mDataLength));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, aData.mData, aData.mDataLength);
|
||||
|
||||
mData = data;
|
||||
mDataLength = aData.mDataLength;
|
||||
mDataOwned = eJSAllocated;
|
||||
|
||||
MOZ_ASSERT(BlobImpls().IsEmpty());
|
||||
BlobImpls().AppendElements(aData.BlobImpls());
|
||||
|
||||
MOZ_ASSERT(GetImages().IsEmpty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StructuredCloneData::Read(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv)
|
||||
{
|
||||
MOZ_ASSERT(mData);
|
||||
|
||||
nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
MOZ_ASSERT(global);
|
||||
|
||||
ReadFromBuffer(global, aCx, mData, mDataLength, aValue, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
StructuredCloneData::Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue,
|
||||
ErrorResult &aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
|
||||
StructuredCloneHelper::Write(aCx, aValue, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBuffer->steal(&mData, &mDataLength);
|
||||
mBuffer = nullptr;
|
||||
mDataOwned = eJSAllocated;
|
||||
}
|
||||
|
||||
void
|
||||
StructuredCloneData::WriteIPCParams(Message* aMsg) const
|
||||
{
|
||||
WriteParam(aMsg, mDataLength);
|
||||
|
||||
if (mDataLength) {
|
||||
// Structured clone data must be 64-bit aligned.
|
||||
aMsg->WriteBytes(mData, mDataLength, sizeof(uint64_t));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneData::ReadIPCParams(const IPC::Message* aMsg,
|
||||
void** aIter)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
|
||||
if (!ReadParam(aMsg, aIter, &mDataLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mDataLength) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char** buffer =
|
||||
const_cast<const char**>(reinterpret_cast<char**>(&mData));
|
||||
// Structured clone data must be 64-bit aligned.
|
||||
if (!aMsg->ReadBytes(aIter, buffer, mDataLength, sizeof(uint64_t))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t* data = static_cast<uint64_t*>(js_malloc(mDataLength));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, mData, mDataLength);
|
||||
mData = data;
|
||||
mDataOwned = eJSAllocated;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneData::CopyExternalData(const void* aData,
|
||||
size_t aDataLength)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
uint64_t* data = static_cast<uint64_t*>(js_malloc(aDataLength));
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, aData, aDataLength);
|
||||
mData = data;
|
||||
mDataLength = aDataLength;
|
||||
mDataOwned = eJSAllocated;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ipc_StructuredCloneData_h
|
||||
#define mozilla_dom_ipc_StructuredCloneData_h
|
||||
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
|
||||
namespace IPC {
|
||||
class Message;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace ipc {
|
||||
|
||||
class StructuredCloneData : public StructuredCloneHelper
|
||||
{
|
||||
public:
|
||||
StructuredCloneData()
|
||||
: StructuredCloneHelper(StructuredCloneHelper::CloningSupported,
|
||||
StructuredCloneHelper::TransferringNotSupported,
|
||||
StructuredCloneHelper::DifferentProcess)
|
||||
, mData(nullptr)
|
||||
, mDataLength(0)
|
||||
, mDataOwned(eNone)
|
||||
{}
|
||||
|
||||
StructuredCloneData(const StructuredCloneData&) = delete;
|
||||
|
||||
~StructuredCloneData()
|
||||
{
|
||||
if (mDataOwned == eJSAllocated) {
|
||||
js_free(mData);
|
||||
}
|
||||
}
|
||||
|
||||
StructuredCloneData&
|
||||
operator=(const StructuredCloneData& aOther) = delete;
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& BlobImpls() const
|
||||
{
|
||||
return mBlobImplArray;
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<BlobImpl>>& BlobImpls()
|
||||
{
|
||||
return mBlobImplArray;
|
||||
}
|
||||
|
||||
bool Copy(const StructuredCloneData& aData);
|
||||
|
||||
void Read(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
ErrorResult &aRv);
|
||||
|
||||
void Write(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue,
|
||||
ErrorResult &aRv);
|
||||
|
||||
void UseExternalData(uint64_t* aData, size_t aDataLength)
|
||||
{
|
||||
MOZ_ASSERT(!mData);
|
||||
mData = aData;
|
||||
mDataLength = aDataLength;
|
||||
MOZ_ASSERT(mDataOwned == eNone);
|
||||
}
|
||||
|
||||
bool CopyExternalData(const void* aData, size_t aDataLength);
|
||||
|
||||
uint64_t* Data() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
size_t DataLength() const
|
||||
{
|
||||
return mDataLength;
|
||||
}
|
||||
|
||||
// For IPC serialization
|
||||
void WriteIPCParams(IPC::Message* aMessage) const;
|
||||
bool ReadIPCParams(const IPC::Message* aMessage, void** aIter);
|
||||
|
||||
private:
|
||||
uint64_t* mData;
|
||||
size_t mDataLength;
|
||||
enum {
|
||||
eNone,
|
||||
eJSAllocated,
|
||||
} mDataOwned;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ipc_StructuredCloneData_h
|
||||
@@ -1,140 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "StructuredCloneUtils.h"
|
||||
|
||||
#include "nsIDOMDOMException.h"
|
||||
#include "nsIMutable.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "StructuredCloneTags.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
Error(JSContext* aCx, uint32_t aErrorId)
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
NS_DOMStructuredCloneError(aCx, aErrorId);
|
||||
} else {
|
||||
Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
uint32_t aData, void* aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aClosure);
|
||||
|
||||
StructuredCloneClosure* closure =
|
||||
static_cast<StructuredCloneClosure*>(aClosure);
|
||||
|
||||
if (aTag == SCTAG_DOM_BLOB) {
|
||||
// nsRefPtr<File> needs to go out of scope before toObjectOrNull() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
// can GC (because in some cases it can!), and a return statement with a
|
||||
// JSObject* type means that JSObject* is on the stack as a raw pointer
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
MOZ_ASSERT(aData < closure->mBlobImpls.Length());
|
||||
nsRefPtr<BlobImpl> blobImpl = closure->mBlobImpls[aData];
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// Blob should not be mutable.
|
||||
bool isMutable;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
|
||||
MOZ_ASSERT(!isMutable);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let's create a new blob with the correct parent.
|
||||
nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
MOZ_ASSERT(global);
|
||||
|
||||
nsRefPtr<Blob> newBlob = Blob::Create(global, blobImpl);
|
||||
if (!ToJSValue(aCx, newBlob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return &val.toObject();
|
||||
}
|
||||
|
||||
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj, void* aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aClosure);
|
||||
|
||||
StructuredCloneClosure* closure =
|
||||
static_cast<StructuredCloneClosure*>(aClosure);
|
||||
|
||||
// See if the wrapped native is a File/Blob.
|
||||
{
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob)) &&
|
||||
NS_SUCCEEDED(blob->SetMutable(false)) &&
|
||||
JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
|
||||
closure->mBlobImpls.Length())) {
|
||||
closure->mBlobImpls.AppendElement(blob->Impl());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks gCallbacks = {
|
||||
Read,
|
||||
Write,
|
||||
Error,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
bool
|
||||
ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
|
||||
const StructuredCloneClosure& aClosure,
|
||||
JS::MutableHandle<JS::Value> aClone)
|
||||
{
|
||||
void* closure = &const_cast<StructuredCloneClosure&>(aClosure);
|
||||
return !!JS_ReadStructuredClone(aCx, aData, aDataLength,
|
||||
JS_STRUCTURED_CLONE_VERSION, aClone,
|
||||
&gCallbacks, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
StructuredCloneClosure& aClosure)
|
||||
{
|
||||
return aBuffer.write(aCx, aSource, &gCallbacks, &aClosure);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -1,55 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_StructuredCloneUtils_h
|
||||
#define mozilla_dom_StructuredCloneUtils_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct
|
||||
StructuredCloneClosure
|
||||
{
|
||||
nsTArray<nsRefPtr<BlobImpl>> mBlobImpls;
|
||||
};
|
||||
|
||||
struct
|
||||
StructuredCloneData
|
||||
{
|
||||
StructuredCloneData() : mData(nullptr), mDataLength(0) {}
|
||||
uint64_t* mData;
|
||||
size_t mDataLength;
|
||||
StructuredCloneClosure mClosure;
|
||||
};
|
||||
|
||||
bool
|
||||
ReadStructuredClone(JSContext* aCx, uint64_t* aData, size_t aDataLength,
|
||||
const StructuredCloneClosure& aClosure,
|
||||
JS::MutableHandle<JS::Value> aClone);
|
||||
|
||||
inline bool
|
||||
ReadStructuredClone(JSContext* aCx, const StructuredCloneData& aData,
|
||||
JS::MutableHandle<JS::Value> aClone)
|
||||
{
|
||||
return ReadStructuredClone(aCx, aData.mData, aData.mDataLength,
|
||||
aData.mClosure, aClone);
|
||||
}
|
||||
|
||||
bool
|
||||
WriteStructuredClone(JSContext* aCx, JS::Handle<JS::Value> aSource,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
StructuredCloneClosure& aClosure);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_StructuredCloneUtils_h
|
||||
+14
-12
@@ -75,7 +75,7 @@
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
#include "PuppetWidget.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "StructuredCloneData.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "ipc/nsGUIEventIPC.h"
|
||||
@@ -229,15 +229,16 @@ TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JS::Value> json(cx, JS::NullValue());
|
||||
StructuredCloneData cloneData;
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
StructuredCloneData data;
|
||||
if (JS_ParseJSON(cx,
|
||||
static_cast<const char16_t*>(aJSONData.BeginReading()),
|
||||
aJSONData.Length(),
|
||||
&json)) {
|
||||
WriteStructuredClone(cx, json, buffer, cloneData.mClosure);
|
||||
cloneData.mData = buffer.data();
|
||||
cloneData.mDataLength = buffer.nbytes();
|
||||
ErrorResult rv;
|
||||
data.Write(cx, json, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||
@@ -246,7 +247,7 @@ TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
|
||||
aMessageName, false, &cloneData, nullptr, nullptr, nullptr);
|
||||
aMessageName, false, &data, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2396,12 +2397,13 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||
{
|
||||
if (mTabChildGlobal) {
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||
StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
|
||||
StructuredCloneData data;
|
||||
UnpackClonedMessageDataForChild(aData, data);
|
||||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||
CrossProcessCpowHolder cpows(Manager(), aCpows);
|
||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
|
||||
aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||
aMessage, false, &data, &cpows, aPrincipal, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2823,10 +2825,10 @@ TabChild::SetTabId(const TabId& aTabId)
|
||||
bool
|
||||
TabChild::DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
ClonedMessageData data;
|
||||
@@ -2849,7 +2851,7 @@ TabChild::DoSendBlockingMessage(JSContext* aCx,
|
||||
bool
|
||||
TabChild::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
||||
+3
-9
@@ -228,7 +228,6 @@ class TabChild final : public TabChildBase,
|
||||
public nsITooltipListener
|
||||
{
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
|
||||
typedef mozilla::layers::APZEventState APZEventState;
|
||||
typedef mozilla::layers::SetTargetAPZCCallback SetTargetAPZCCallback;
|
||||
@@ -277,14 +276,14 @@ public:
|
||||
*/
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
const mozilla::dom::StructuredCloneData& aData,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
|
||||
@@ -522,11 +521,6 @@ protected:
|
||||
private:
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*
|
||||
* |aOwnOrContainingAppId| is the app-id of our frame or of the closest app
|
||||
* frame in the hierarchy which contains us.
|
||||
*
|
||||
* |aIsBrowserElement| indicates whether we're a browser (but not an app).
|
||||
*/
|
||||
TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
|
||||
+18
-12
@@ -78,7 +78,7 @@
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "private/pprio.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
#include "StructuredCloneUtils.h"
|
||||
#include "StructuredCloneData.h"
|
||||
#include "ColorPickerParent.h"
|
||||
#include "FilePickerParent.h"
|
||||
#include "TabChild.h"
|
||||
@@ -1806,7 +1806,7 @@ TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
// FIXME Permission check for TabParent in Content process
|
||||
nsIPrincipal* principal = aPrincipal;
|
||||
@@ -1818,9 +1818,11 @@ TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||
}
|
||||
}
|
||||
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForParent(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(Manager(), aCpows);
|
||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aRetVal);
|
||||
return ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1828,7 +1830,7 @@ TabParent::RecvRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
// FIXME Permission check for TabParent in Content process
|
||||
nsIPrincipal* principal = aPrincipal;
|
||||
@@ -1840,9 +1842,11 @@ TabParent::RecvRpcMessage(const nsString& aMessage,
|
||||
}
|
||||
}
|
||||
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForParent(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(Manager(), aCpows);
|
||||
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aRetVal);
|
||||
return ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1861,9 +1865,11 @@ TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||
}
|
||||
}
|
||||
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForParent(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(Manager(), aCpows);
|
||||
return ReceiveMessage(aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||
return ReceiveMessage(aMessage, false, &data, &cpows, aPrincipal, nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -2590,10 +2596,10 @@ TabParent::RecvDispatchFocusToTopLevelWindow()
|
||||
bool
|
||||
TabParent::ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
StructuredCloneData* aData,
|
||||
CpowHolder* aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
|
||||
if (frameLoader && frameLoader->GetFrameMessageManager()) {
|
||||
@@ -2604,7 +2610,7 @@ TabParent::ReceiveMessage(const nsString& aMessage,
|
||||
frameLoader,
|
||||
aMessage,
|
||||
aSync,
|
||||
aCloneData,
|
||||
aData,
|
||||
aCpows,
|
||||
aPrincipal,
|
||||
aRetVal);
|
||||
|
||||
+8
-6
@@ -66,7 +66,10 @@ class ClonedMessageData;
|
||||
class nsIContentParent;
|
||||
class Element;
|
||||
class DataTransfer;
|
||||
struct StructuredCloneData;
|
||||
|
||||
namespace ipc {
|
||||
class StructuredCloneData;
|
||||
} // ipc namespace
|
||||
|
||||
class TabParent final : public PBrowserParent
|
||||
, public nsIDOMEventListener
|
||||
@@ -78,7 +81,6 @@ class TabParent final : public PBrowserParent
|
||||
, public nsAPostRefreshObserver
|
||||
{
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
|
||||
virtual ~TabParent();
|
||||
|
||||
@@ -152,12 +154,12 @@ public:
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal) override;
|
||||
nsTArray<ipc::StructuredCloneData>* aRetVal) override;
|
||||
virtual bool RecvRpcMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetVal) override;
|
||||
nsTArray<ipc::StructuredCloneData>* aRetVal) override;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
@@ -433,10 +435,10 @@ public:
|
||||
protected:
|
||||
bool ReceiveMessage(const nsString& aMessage,
|
||||
bool aSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
ipc::StructuredCloneData* aData,
|
||||
mozilla::jsipc::CpowHolder* aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aJSONRetVal = nullptr);
|
||||
nsTArray<ipc::StructuredCloneData>* aJSONRetVal = nullptr);
|
||||
|
||||
virtual bool RecvAsyncAuthPrompt(const nsCString& aUri,
|
||||
const nsString& aRealm,
|
||||
|
||||
+2
-2
@@ -19,6 +19,7 @@ EXPORTS.mozilla.dom.ipc += [
|
||||
'BlobParent.h',
|
||||
'IdType.h',
|
||||
'nsIRemoteBlob.h',
|
||||
'StructuredCloneData.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
@@ -35,7 +36,6 @@ EXPORTS.mozilla.dom += [
|
||||
'NuwaChild.h',
|
||||
'NuwaParent.h',
|
||||
'PermissionMessageUtils.h',
|
||||
'StructuredCloneUtils.h',
|
||||
'TabChild.h',
|
||||
'TabContext.h',
|
||||
'TabMessageUtils.h',
|
||||
@@ -67,7 +67,7 @@ UNIFIED_SOURCES += [
|
||||
'PreallocatedProcessManager.cpp',
|
||||
'ProcessPriorityManager.cpp',
|
||||
'ScreenManagerParent.cpp',
|
||||
'StructuredCloneUtils.cpp',
|
||||
'StructuredCloneData.cpp',
|
||||
'TabChild.cpp',
|
||||
'TabContext.cpp',
|
||||
'TabMessageUtils.cpp',
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
|
||||
#include "nsPrintfCString.h"
|
||||
@@ -117,10 +117,12 @@ nsIContentChild::RecvAsyncMessage(const nsString& aMsg,
|
||||
{
|
||||
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::GetChildProcessManager();
|
||||
if (cpm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
||||
ipc::StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForChild(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(this, aCpows);
|
||||
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()), nullptr,
|
||||
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||
aMsg, false, &data, &cpows, aPrincipal, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include "mozilla/dom/ContentBridgeParent.h"
|
||||
#include "mozilla/dom/PTabContext.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
@@ -187,7 +187,7 @@ nsIContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals)
|
||||
nsTArray<ipc::StructuredCloneData>* aRetvals)
|
||||
{
|
||||
// FIXME Permission check in Content process
|
||||
nsIPrincipal* principal = aPrincipal;
|
||||
@@ -201,10 +201,12 @@ nsIContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||
if (ppm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
ipc::StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForParent(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(this, aCpows);
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
|
||||
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
|
||||
aMsg, true, &data, &cpows, aPrincipal, aRetvals);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -214,7 +216,7 @@ nsIContentParent::RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals)
|
||||
nsTArray<ipc::StructuredCloneData>* aRetvals)
|
||||
{
|
||||
// FIXME Permission check in Content process
|
||||
nsIPrincipal* principal = aPrincipal;
|
||||
@@ -228,10 +230,12 @@ nsIContentParent::RecvRpcMessage(const nsString& aMsg,
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||
if (ppm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
ipc::StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForParent(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(this, aCpows);
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
|
||||
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
|
||||
aMsg, true, &data, &cpows, aPrincipal, aRetvals);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -254,10 +258,12 @@ nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||
if (ppm) {
|
||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||
ipc::StructuredCloneData data;
|
||||
ipc::UnpackClonedMessageDataForParent(aData, data);
|
||||
|
||||
CrossProcessCpowHolder cpows(this, aCpows);
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
|
||||
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
|
||||
aMsg, false, &data, &cpows, aPrincipal, nullptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,6 @@ class nsIContentParent : public nsISupports
|
||||
, public mozilla::dom::ipc::MessageManagerCallback
|
||||
, public CPOWManagerGetter
|
||||
{
|
||||
typedef mozilla::OwningSerializedStructuredCloneBuffer OwningSerializedStructuredCloneBuffer;
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTPARENT_IID)
|
||||
|
||||
@@ -104,12 +102,12 @@ protected: // IPDL methods
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals);
|
||||
nsTArray<ipc::StructuredCloneData>* aRetvals);
|
||||
virtual bool RecvRpcMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<OwningSerializedStructuredCloneBuffer>* aRetvals);
|
||||
nsTArray<ipc::StructuredCloneData>* aRetvals);
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsISafeOutputStream.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
@@ -140,9 +140,12 @@ public:
|
||||
event->SetTrusted(true);
|
||||
event->SetSource(mPort);
|
||||
|
||||
nsTArray<nsRefPtr<MessagePortBase>> ports;
|
||||
mData->TakeTransferredPorts(ports);
|
||||
|
||||
nsRefPtr<MessagePortList> portList =
|
||||
new MessagePortList(static_cast<dom::Event*>(event.get()),
|
||||
mData->GetTransferredPorts());
|
||||
ports);
|
||||
event->SetPorts(portList);
|
||||
|
||||
bool dummy;
|
||||
|
||||
@@ -51,14 +51,6 @@ SharedMessagePortMessage::Write(JSContext* aCx,
|
||||
return;
|
||||
}
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = BlobImpls();
|
||||
for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) {
|
||||
if (!blobImpls[i]->MayBeClonedToOtherThreads()) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FallibleTArray<uint8_t> cloneData;
|
||||
|
||||
MoveBufferDataToArray(cloneData, aRv);
|
||||
|
||||
@@ -23,7 +23,8 @@ public:
|
||||
nsTArray<uint8_t> mData;
|
||||
|
||||
SharedMessagePortMessage()
|
||||
: StructuredCloneHelper(CloningSupported, TransferringSupported)
|
||||
: StructuredCloneHelper(CloningSupported, TransferringSupported,
|
||||
DifferentProcess)
|
||||
{}
|
||||
|
||||
void Read(nsISupports* aParent,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIPushClient.h"
|
||||
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "nsContentCID.h"
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ private:
|
||||
|
||||
nsCOMPtr<nsIWorkerHolder> mWifiWorker;
|
||||
|
||||
nsRefPtr<ipc::KeyStore> mKeyStore;
|
||||
nsRefPtr<mozilla::ipc::KeyStore> mKeyStore;
|
||||
|
||||
bool mShutdown;
|
||||
};
|
||||
|
||||
@@ -26,6 +26,8 @@ interface HTMLIFrameElement : HTMLElement {
|
||||
attribute DOMString width;
|
||||
[SetterThrows, Pure]
|
||||
attribute DOMString height;
|
||||
[SetterThrows, Pure, Pref="network.http.enablePerElementReferrer"]
|
||||
attribute DOMString referrer;
|
||||
readonly attribute Document? contentDocument;
|
||||
readonly attribute WindowProxy? contentWindow;
|
||||
};
|
||||
|
||||
@@ -224,7 +224,8 @@ public:
|
||||
const nsAString& aRevisionId,
|
||||
ErrorResult& aRv)
|
||||
: DataStoreProxyRunnable(aWorkerPrivate, aBackingStore, aWorkerPromise)
|
||||
, StructuredCloneHelper(CloningNotSupported, TransferringNotSupported)
|
||||
, StructuredCloneHelper(CloningNotSupported, TransferringNotSupported,
|
||||
SameProcessDifferentThread)
|
||||
, mId(aId)
|
||||
, mRevisionId(aRevisionId)
|
||||
, mRv(aRv)
|
||||
@@ -285,7 +286,8 @@ public:
|
||||
const nsAString& aRevisionId,
|
||||
ErrorResult& aRv)
|
||||
: DataStoreProxyRunnable(aWorkerPrivate, aBackingStore, aWorkerPromise)
|
||||
, StructuredCloneHelper(CloningNotSupported, TransferringNotSupported)
|
||||
, StructuredCloneHelper(CloningNotSupported, TransferringNotSupported,
|
||||
SameProcessDifferentThread)
|
||||
, mId(aId)
|
||||
, mRevisionId(aRevisionId)
|
||||
, mRv(aRv)
|
||||
|
||||
@@ -1683,27 +1683,24 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
NS_ASSERTION(global, "Must have a global by now!");
|
||||
JS::Rooted<JSObject*> global(aCx);
|
||||
|
||||
// Determine whether we want to be discarding source on this global to save
|
||||
// memory. It would make more sense to do this when we create the global, but
|
||||
// the information behind UsesSystemPrincipal() et al isn't finalized until
|
||||
// the call to SetPrincipal during the first script load. After that, however,
|
||||
// it never changes. So we can just idempotently set the bits here.
|
||||
//
|
||||
// Note that we read a pref that is cached on the main thread. This is benignly
|
||||
// racey.
|
||||
if (xpc::ShouldDiscardSystemSource()) {
|
||||
bool discard = aWorkerPrivate->UsesSystemPrincipal() ||
|
||||
aWorkerPrivate->IsInPrivilegedApp();
|
||||
JS::CompartmentOptionsRef(global).setDiscardSource(discard);
|
||||
if (mIsWorkerScript) {
|
||||
WorkerGlobalScope* globalScope =
|
||||
aWorkerPrivate->GetOrCreateGlobalScope(aCx);
|
||||
if (NS_WARN_IF(!globalScope)) {
|
||||
NS_WARNING("Failed to make global!");
|
||||
return false;
|
||||
}
|
||||
|
||||
global.set(globalScope->GetWrapper());
|
||||
} else {
|
||||
global.set(JS::CurrentGlobalOrNull(aCx));
|
||||
}
|
||||
|
||||
// Similar to the above.
|
||||
if (xpc::ExtraWarningsForSystemJS() && aWorkerPrivate->UsesSystemPrincipal()) {
|
||||
JS::CompartmentOptionsRef(global).extraWarningsOverride().set(true);
|
||||
}
|
||||
MOZ_ASSERT(global);
|
||||
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
|
||||
for (uint32_t index = mFirstIndex; index <= mLastIndex; index++) {
|
||||
ScriptLoadInfo& loadInfo = loadInfos.ElementAt(index);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerStructuredClone.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@@ -73,24 +72,18 @@ ServiceWorkerClient::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProt
|
||||
|
||||
namespace {
|
||||
|
||||
class ServiceWorkerClientPostMessageRunnable final : public nsRunnable
|
||||
class ServiceWorkerClientPostMessageRunnable final
|
||||
: public nsRunnable
|
||||
, public StructuredCloneHelper
|
||||
{
|
||||
uint64_t mWindowId;
|
||||
JSAutoStructuredCloneBuffer mBuffer;
|
||||
WorkerStructuredCloneClosure mClosure;
|
||||
|
||||
public:
|
||||
ServiceWorkerClientPostMessageRunnable(uint64_t aWindowId,
|
||||
JSAutoStructuredCloneBuffer&& aData,
|
||||
WorkerStructuredCloneClosure& aClosure)
|
||||
: mWindowId(aWindowId),
|
||||
mBuffer(Move(aData))
|
||||
{
|
||||
mClosure.mClonedObjects.SwapElements(aClosure.mClonedObjects);
|
||||
mClosure.mClonedImages.SwapElements(aClosure.mClonedImages);
|
||||
MOZ_ASSERT(aClosure.mMessagePorts.IsEmpty());
|
||||
mClosure.mMessagePortIdentifiers.SwapElements(aClosure.mMessagePortIdentifiers);
|
||||
}
|
||||
explicit ServiceWorkerClientPostMessageRunnable(uint64_t aWindowId)
|
||||
: StructuredCloneHelper(CloningSupported, TransferringSupported,
|
||||
SameProcessDifferentThread)
|
||||
, mWindowId(aWindowId)
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
@@ -123,40 +116,40 @@ private:
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// Release reference to objects that were AddRef'd for
|
||||
// cloning into worker when array goes out of scope.
|
||||
WorkerStructuredCloneClosure closure;
|
||||
closure.mClonedObjects.SwapElements(mClosure.mClonedObjects);
|
||||
closure.mClonedImages.SwapElements(mClosure.mClonedImages);
|
||||
MOZ_ASSERT(mClosure.mMessagePorts.IsEmpty());
|
||||
closure.mMessagePortIdentifiers.SwapElements(mClosure.mMessagePortIdentifiers);
|
||||
closure.mParentWindow = do_QueryInterface(aTargetContainer->GetParentObject());
|
||||
|
||||
JS::Rooted<JS::Value> messageData(aCx);
|
||||
if (!mBuffer.read(aCx, &messageData,
|
||||
WorkerStructuredCloneCallbacks(), &closure)) {
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
ErrorResult rv;
|
||||
Read(aTargetContainer->GetParentObject(), aCx, &messageData, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(aCx, rv.StealNSResult());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMMessageEvent> event = new MessageEvent(aTargetContainer,
|
||||
nullptr, nullptr);
|
||||
nsresult rv =
|
||||
event->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
false /* non-bubbling */,
|
||||
false /* not cancelable */,
|
||||
messageData,
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(aCx, rv);
|
||||
nsRefPtr<MessageEvent> event = new MessageEvent(aTargetContainer,
|
||||
nullptr, nullptr);
|
||||
rv = event->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
false /* non-bubbling */,
|
||||
false /* not cancelable */,
|
||||
messageData,
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
nullptr);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(aCx, rv.StealNSResult());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<MessagePortBase>> ports;
|
||||
TakeTransferredPorts(ports);
|
||||
|
||||
nsRefPtr<MessagePortList> portList =
|
||||
new MessagePortList(static_cast<dom::Event*>(event.get()),
|
||||
ports);
|
||||
event->SetPorts(portList);
|
||||
|
||||
event->SetTrusted(true);
|
||||
bool status = false;
|
||||
aTargetContainer->DispatchEvent(event, &status);
|
||||
aTargetContainer->DispatchEvent(static_cast<dom::Event*>(event.get()),
|
||||
&status);
|
||||
|
||||
if (!status) {
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -194,22 +187,17 @@ ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
transferable.setObject(*array);
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks = WorkerStructuredCloneCallbacks();
|
||||
nsRefPtr<ServiceWorkerClientPostMessageRunnable> runnable =
|
||||
new ServiceWorkerClientPostMessageRunnable(mWindowId);
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (!buffer.write(aCx, aMessage, transferable, callbacks, &closure)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
runnable->Write(aCx, aMessage, transferable, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ServiceWorkerClientPostMessageRunnable> runnable =
|
||||
new ServiceWorkerClientPostMessageRunnable(mWindowId, Move(buffer),
|
||||
closure);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
aRv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/ErrorEvent.h"
|
||||
#include "mozilla/dom/Headers.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/Navigator.h"
|
||||
|
||||
+61
-629
@@ -45,15 +45,10 @@
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/LoadContext.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/ErrorEvent.h"
|
||||
#include "mozilla/dom/ErrorEventBinding.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
@@ -62,26 +57,18 @@
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/PromiseDebugging.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/StructuredClone.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/WebCryptoCommon.h"
|
||||
#include "mozilla/dom/WorkerBinding.h"
|
||||
#include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/WorkerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "MultipartBlobImpl.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCycleCollector.h"
|
||||
#include "nsError.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsFormData.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
#include "nsJSUtils.h"
|
||||
@@ -113,7 +100,6 @@
|
||||
#include "WorkerFeature.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerScope.h"
|
||||
#include "WorkerStructuredClone.h"
|
||||
#include "WorkerThread.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
@@ -327,484 +313,6 @@ LogErrorToConsole(const nsAString& aMessage,
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
// Recursive!
|
||||
already_AddRefed<BlobImpl>
|
||||
EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl,
|
||||
PBackgroundChild* aManager = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
|
||||
if (!aManager) {
|
||||
aManager = BackgroundChild::GetForCurrentThread();
|
||||
MOZ_ASSERT(aManager);
|
||||
}
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = aBlobImpl;
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>* subBlobImpls =
|
||||
aBlobImpl->GetSubBlobImpls();
|
||||
|
||||
if (!subBlobImpls) {
|
||||
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl)) {
|
||||
// Always make sure we have a blob from an actor we can use on this
|
||||
// thread.
|
||||
BlobChild* blobChild = BlobChild::GetOrCreate(aManager, blobImpl);
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
blobImpl = blobChild->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
DebugOnly<bool> isMutable;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
|
||||
MOZ_ASSERT(!isMutable);
|
||||
} else {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
|
||||
}
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
const uint32_t subBlobCount = subBlobImpls->Length();
|
||||
MOZ_ASSERT(subBlobCount);
|
||||
|
||||
nsTArray<nsRefPtr<BlobImpl>> newSubBlobImpls;
|
||||
newSubBlobImpls.SetLength(subBlobCount);
|
||||
|
||||
bool newBlobImplNeeded = false;
|
||||
|
||||
for (uint32_t index = 0; index < subBlobCount; index++) {
|
||||
const nsRefPtr<BlobImpl>& subBlobImpl = subBlobImpls->ElementAt(index);
|
||||
MOZ_ASSERT(subBlobImpl);
|
||||
|
||||
nsRefPtr<BlobImpl>& newSubBlobImpl = newSubBlobImpls[index];
|
||||
|
||||
newSubBlobImpl = EnsureBlobForBackgroundManager(subBlobImpl, aManager);
|
||||
MOZ_ASSERT(newSubBlobImpl);
|
||||
|
||||
if (subBlobImpl != newSubBlobImpl) {
|
||||
newBlobImplNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (newBlobImplNeeded) {
|
||||
nsString contentType;
|
||||
blobImpl->GetType(contentType);
|
||||
|
||||
if (blobImpl->IsFile()) {
|
||||
nsString name;
|
||||
blobImpl->GetName(name);
|
||||
|
||||
blobImpl = new MultipartBlobImpl(newSubBlobImpls, name, contentType);
|
||||
} else {
|
||||
blobImpl = new MultipartBlobImpl(newSubBlobImpls, contentType);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
|
||||
}
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<Blob>
|
||||
ReadBlobOrFileNoWrap(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aReader);
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl;
|
||||
{
|
||||
BlobImpl* rawBlobImpl;
|
||||
MOZ_ALWAYS_TRUE(JS_ReadBytes(aReader, &rawBlobImpl, sizeof(rawBlobImpl)));
|
||||
|
||||
MOZ_ASSERT(rawBlobImpl);
|
||||
|
||||
blobImpl = rawBlobImpl;
|
||||
}
|
||||
|
||||
blobImpl = EnsureBlobForBackgroundManager(blobImpl);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
nsCOMPtr<nsISupports> parent;
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
parent = do_QueryInterface(scriptGlobal);
|
||||
} else {
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
WorkerGlobalScope* globalScope = workerPrivate->GlobalScope();
|
||||
MOZ_ASSERT(globalScope);
|
||||
|
||||
parent = do_QueryObject(globalScope);
|
||||
}
|
||||
|
||||
nsRefPtr<Blob> blob = Blob::Create(parent, blobImpl);
|
||||
return blob.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ReadBlobOrFile(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
JS::MutableHandle<JSObject*> aBlobOrFile)
|
||||
{
|
||||
nsRefPtr<Blob> blob = ReadBlobOrFileNoWrap(aCx, aReader);
|
||||
aBlobOrFile.set(blob->WrapObject(aCx, nullptr));
|
||||
}
|
||||
|
||||
// See WriteFormData for serialization format.
|
||||
void
|
||||
ReadFormData(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
uint32_t aCount,
|
||||
JS::MutableHandle<JSObject*> aFormData)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aReader);
|
||||
MOZ_ASSERT(!aFormData);
|
||||
|
||||
nsCOMPtr<nsISupports> parent;
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
parent = do_QueryInterface(scriptGlobal);
|
||||
} else {
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
workerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
WorkerGlobalScope* globalScope = workerPrivate->GlobalScope();
|
||||
MOZ_ASSERT(globalScope);
|
||||
|
||||
parent = do_QueryObject(globalScope);
|
||||
}
|
||||
|
||||
nsRefPtr<nsFormData> formData = new nsFormData(parent);
|
||||
MOZ_ASSERT(formData);
|
||||
|
||||
Optional<nsAString> thirdArg;
|
||||
|
||||
uint32_t isFile;
|
||||
uint32_t dummy;
|
||||
for (uint32_t i = 0; i < aCount; ++i) {
|
||||
MOZ_ALWAYS_TRUE(JS_ReadUint32Pair(aReader, &isFile, &dummy));
|
||||
|
||||
nsAutoString name;
|
||||
MOZ_ALWAYS_TRUE(ReadString(aReader, name));
|
||||
|
||||
if (isFile) {
|
||||
// Read out the tag since the blob reader isn't expecting it.
|
||||
MOZ_ALWAYS_TRUE(JS_ReadUint32Pair(aReader, &dummy, &dummy));
|
||||
nsRefPtr<Blob> blob = ReadBlobOrFileNoWrap(aCx, aReader);
|
||||
MOZ_ASSERT(blob);
|
||||
formData->Append(name, *blob, thirdArg);
|
||||
} else {
|
||||
nsAutoString value;
|
||||
MOZ_ALWAYS_TRUE(ReadString(aReader, value));
|
||||
formData->Append(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
aFormData.set(formData->WrapObject(aCx, nullptr));
|
||||
}
|
||||
|
||||
bool
|
||||
WriteBlobOrFile(JSStructuredCloneWriter* aWriter,
|
||||
BlobImpl* aBlobImpl,
|
||||
WorkerStructuredCloneClosure& aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aWriter);
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
|
||||
if (!aBlobImpl->MayBeClonedToOtherThreads()) {
|
||||
NS_WARNING("Not all the blob implementations can be sent between threads.");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = EnsureBlobForBackgroundManager(aBlobImpl);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
aBlobImpl = blobImpl;
|
||||
|
||||
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_BLOB, 0)) ||
|
||||
NS_WARN_IF(!JS_WriteBytes(aWriter, &aBlobImpl, sizeof(aBlobImpl)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aClosure.mClonedObjects.AppendElement(aBlobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
// A FormData is serialized as:
|
||||
// - A pair of ints (tag identifying it as a FormData, number of elements in
|
||||
// the FormData)
|
||||
// - for each (key, value) pair:
|
||||
// - pair of ints (is value a file?, 0). If not a file, value is a string.
|
||||
// - string name
|
||||
// - if value is a file:
|
||||
// - write the file/blob
|
||||
// - else:
|
||||
// - string value
|
||||
bool
|
||||
WriteFormData(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter,
|
||||
nsFormData* aFormData,
|
||||
WorkerStructuredCloneClosure& aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aWriter);
|
||||
MOZ_ASSERT(aFormData);
|
||||
|
||||
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_FORMDATA, aFormData->Length()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS Closure final
|
||||
{
|
||||
JSContext* mCx;
|
||||
JSStructuredCloneWriter* mWriter;
|
||||
WorkerStructuredCloneClosure& mClones;
|
||||
|
||||
public:
|
||||
Closure(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||
WorkerStructuredCloneClosure& aClones)
|
||||
: mCx(aCx), mWriter(aWriter), mClones(aClones)
|
||||
{ }
|
||||
|
||||
static bool
|
||||
Write(const nsString& aName, bool isFile, const nsString& aValue,
|
||||
File* aFile, void* aClosure)
|
||||
{
|
||||
Closure* closure = static_cast<Closure*>(aClosure);
|
||||
if (!JS_WriteUint32Pair(closure->mWriter, /* a file? */ (uint32_t) isFile, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WriteString(closure->mWriter, aName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isFile) {
|
||||
if (!WriteBlobOrFile(closure->mWriter, aFile->Impl(),
|
||||
closure->mClones)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!WriteString(closure->mWriter, aValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Closure closure(aCx, aWriter, aClosure);
|
||||
return aFormData->ForEach(Closure::Write, &closure);
|
||||
}
|
||||
|
||||
struct WorkerStructuredCloneCallbacks
|
||||
{
|
||||
static JSObject*
|
||||
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
uint32_t aData, void* aClosure)
|
||||
{
|
||||
// See if object is a nsIDOMBlob pointer.
|
||||
if (aTag == DOMWORKER_SCTAG_BLOB) {
|
||||
MOZ_ASSERT(!aData);
|
||||
|
||||
JS::Rooted<JSObject*> blobOrFile(aCx);
|
||||
ReadBlobOrFile(aCx, aReader, &blobOrFile);
|
||||
|
||||
return blobOrFile;
|
||||
}
|
||||
|
||||
// See if the object is an ImageData.
|
||||
if (aTag == SCTAG_DOM_IMAGEDATA) {
|
||||
MOZ_ASSERT(!aData);
|
||||
return ReadStructuredCloneImageData(aCx, aReader);
|
||||
}
|
||||
|
||||
// See if the object is a FormData.
|
||||
if (aTag == DOMWORKER_SCTAG_FORMDATA) {
|
||||
JS::Rooted<JSObject*> formData(aCx);
|
||||
// aData is the entry count.
|
||||
ReadFormData(aCx, aReader, aData, &formData);
|
||||
return formData;
|
||||
}
|
||||
|
||||
// See if the object is an ImageBitmap.
|
||||
if (aTag == SCTAG_DOM_IMAGEBITMAP) {
|
||||
NS_ASSERTION(aClosure, "Null pointer!");
|
||||
|
||||
// Get the current global object.
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(closure->mParentWindow);
|
||||
// aData is the index of the cloned image.
|
||||
return ImageBitmap::ReadStructuredClone(aCx, aReader, parent,
|
||||
closure->mClonedImages, aData);
|
||||
}
|
||||
|
||||
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj, void* aClosure)
|
||||
{
|
||||
NS_ASSERTION(aClosure, "Null pointer!");
|
||||
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
|
||||
// See if this is a Blob/File object.
|
||||
{
|
||||
nsRefPtr<Blob> blob;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
if (WriteBlobOrFile(aWriter, blobImpl, *closure)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if this is an ImageData object.
|
||||
{
|
||||
ImageData* imageData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, aObj, imageData))) {
|
||||
return WriteStructuredCloneImageData(aCx, aWriter, imageData);
|
||||
}
|
||||
}
|
||||
|
||||
// See if this is a FormData object.
|
||||
{
|
||||
nsFormData* formData = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(FormData, aObj, formData))) {
|
||||
if (WriteFormData(aCx, aWriter, formData, *closure)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if this is an ImageBitmap object.
|
||||
{
|
||||
ImageBitmap* imageBitmap = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, aObj, imageBitmap))) {
|
||||
return ImageBitmap::WriteStructuredClone(aWriter,
|
||||
closure->mClonedImages,
|
||||
imageBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
|
||||
}
|
||||
|
||||
static void
|
||||
Error(JSContext* aCx, uint32_t /* aErrorId */)
|
||||
{
|
||||
Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
}
|
||||
|
||||
static bool
|
||||
ReadTransfer(JSContext* aCx, JSStructuredCloneReader* aReader,
|
||||
uint32_t aTag, void* aContent, uint64_t aExtraData,
|
||||
void* aClosure, JS::MutableHandle<JSObject*> aReturnObject)
|
||||
{
|
||||
MOZ_ASSERT(aClosure);
|
||||
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
|
||||
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||
MOZ_ASSERT(!aContent);
|
||||
MOZ_ASSERT(aExtraData < closure->mMessagePortIdentifiers.Length());
|
||||
|
||||
ErrorResult rv;
|
||||
nsRefPtr<MessagePortBase> port =
|
||||
dom::MessagePort::Create(closure->mParentWindow,
|
||||
closure->mMessagePortIdentifiers[aExtraData],
|
||||
rv);
|
||||
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
closure->mMessagePorts.AppendElement(port);
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!GetOrCreateDOMReflector(aCx, port, &value)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
return false;
|
||||
}
|
||||
|
||||
aReturnObject.set(&value.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
Transfer(JSContext* aCx, JS::Handle<JSObject*> aObj, void* aClosure,
|
||||
uint32_t* aTag, JS::TransferableOwnership* aOwnership,
|
||||
void** aContent, uint64_t *aExtraData)
|
||||
{
|
||||
MOZ_ASSERT(aClosure);
|
||||
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
|
||||
MessagePortBase* port;
|
||||
nsresult rv = UNWRAP_OBJECT(MessagePort, aObj, port);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_WARN_IF(closure->mTransferredPorts.Contains(port))) {
|
||||
// No duplicates.
|
||||
return false;
|
||||
}
|
||||
|
||||
MessagePortIdentifier identifier;
|
||||
if (!port->CloneAndDisentangle(identifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
closure->mMessagePortIdentifiers.AppendElement(identifier);
|
||||
closure->mTransferredPorts.AppendElement(port);
|
||||
|
||||
*aTag = SCTAG_DOM_MAP_MESSAGEPORT;
|
||||
*aOwnership = JS::SCTAG_TMO_CUSTOM;
|
||||
*aContent = nullptr;
|
||||
*aExtraData = closure->mMessagePortIdentifiers.Length() - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeTransfer(uint32_t aTag, JS::TransferableOwnership aOwnership,
|
||||
void *aContent, uint64_t aExtraData, void* aClosure)
|
||||
{
|
||||
if (aTag == SCTAG_DOM_MAP_MESSAGEPORT) {
|
||||
MOZ_ASSERT(aClosure);
|
||||
MOZ_ASSERT(!aContent);
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
|
||||
MOZ_ASSERT(aExtraData < closure->mMessagePortIdentifiers.Length());
|
||||
dom::MessagePort::ForceClose(closure->mMessagePortIdentifiers[aExtraData]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const JSStructuredCloneCallbacks gWorkerStructuredCloneCallbacks = {
|
||||
WorkerStructuredCloneCallbacks::Read,
|
||||
WorkerStructuredCloneCallbacks::Write,
|
||||
WorkerStructuredCloneCallbacks::Error,
|
||||
WorkerStructuredCloneCallbacks::ReadTransfer,
|
||||
WorkerStructuredCloneCallbacks::Transfer,
|
||||
WorkerStructuredCloneCallbacks::FreeTransfer
|
||||
};
|
||||
|
||||
class MainThreadReleaseRunnable final : public nsRunnable
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsISupports>> mDoomed;
|
||||
@@ -983,21 +491,12 @@ private:
|
||||
virtual bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||
{
|
||||
WorkerGlobalScope* globalScope =
|
||||
aWorkerPrivate->GetOrCreateGlobalScope(aCx);
|
||||
if (!globalScope) {
|
||||
NS_WARNING("Failed to make global!");
|
||||
if (!scriptloader::LoadMainScript(aCx, mScriptURL, WorkerScript)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx, globalScope->GetWrapper());
|
||||
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
bool result = scriptloader::LoadMainScript(aCx, mScriptURL, WorkerScript);
|
||||
if (result) {
|
||||
aWorkerPrivate->SetWorkerScriptExecutedSuccessfully();
|
||||
}
|
||||
return result;
|
||||
aWorkerPrivate->SetWorkerScriptExecutedSuccessfully();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1093,9 +592,8 @@ private:
|
||||
};
|
||||
|
||||
class MessageEventRunnable final : public WorkerRunnable
|
||||
, public StructuredCloneHelper
|
||||
{
|
||||
JSAutoStructuredCloneBuffer mBuffer;
|
||||
WorkerStructuredCloneClosure mClosure;
|
||||
uint64_t mMessagePortSerial;
|
||||
bool mToMessagePort;
|
||||
|
||||
@@ -1107,24 +605,13 @@ public:
|
||||
TargetAndBusyBehavior aBehavior,
|
||||
bool aToMessagePort, uint64_t aMessagePortSerial)
|
||||
: WorkerRunnable(aWorkerPrivate, aBehavior)
|
||||
, StructuredCloneHelper(CloningSupported, TransferringSupported,
|
||||
SameProcessDifferentThread)
|
||||
, mMessagePortSerial(aMessagePortSerial)
|
||||
, mToMessagePort(aToMessagePort)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Write(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||
JS::Handle<JS::Value> aTransferredValue,
|
||||
const JSStructuredCloneCallbacks *aCallbacks)
|
||||
{
|
||||
bool ok = mBuffer.write(aCx, aValue, aTransferredValue, aCallbacks,
|
||||
&mClosure);
|
||||
// This hashtable has to be empty because it could contain MessagePort
|
||||
// objects that cannot be freed on a different thread.
|
||||
mClosure.mTransferredPorts.Clear();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void
|
||||
SetMessageSource(ServiceWorkerClientInfo* aSource)
|
||||
{
|
||||
@@ -1135,49 +622,44 @@ public:
|
||||
DispatchDOMEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
DOMEventTargetHelper* aTarget, bool aIsMainThread)
|
||||
{
|
||||
// Release reference to objects that were AddRef'd for
|
||||
// cloning into worker when array goes out of scope.
|
||||
WorkerStructuredCloneClosure closure;
|
||||
closure.mClonedObjects.SwapElements(mClosure.mClonedObjects);
|
||||
closure.mClonedImages.SwapElements(mClosure.mClonedImages);
|
||||
MOZ_ASSERT(mClosure.mMessagePorts.IsEmpty());
|
||||
closure.mMessagePortIdentifiers.SwapElements(mClosure.mMessagePortIdentifiers);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> parent;
|
||||
if (aIsMainThread) {
|
||||
closure.mParentWindow = do_QueryInterface(aTarget->GetParentObject());
|
||||
parent = do_QueryInterface(aTarget->GetParentObject());
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> messageData(aCx);
|
||||
if (!mBuffer.read(aCx, &messageData,
|
||||
workers::WorkerStructuredCloneCallbacks(),
|
||||
&closure)) {
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
ErrorResult rv;
|
||||
Read(parent, aCx, &messageData, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(aCx, rv.StealNSResult());
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<MessageEvent> event = new MessageEvent(aTarget, nullptr, nullptr);
|
||||
nsresult rv =
|
||||
event->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
false /* non-bubbling */,
|
||||
false /* non-cancelable */,
|
||||
messageData,
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
nullptr);
|
||||
rv = event->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
false /* non-bubbling */,
|
||||
false /* cancelable */,
|
||||
messageData,
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
nullptr);
|
||||
if (mEventSource) {
|
||||
nsRefPtr<ServiceWorkerClient> client =
|
||||
new ServiceWorkerWindowClient(aTarget, *mEventSource);
|
||||
event->SetSource(client);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(aCx, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(aCx, rv.StealNSResult());
|
||||
return false;
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<MessagePortBase>> ports;
|
||||
TakeTransferredPorts(ports);
|
||||
|
||||
event->SetTrusted(true);
|
||||
event->SetPorts(new MessagePortList(static_cast<dom::Event*>(event.get()),
|
||||
closure.mMessagePorts));
|
||||
ports));
|
||||
nsCOMPtr<nsIDOMEvent> domEvent = do_QueryObject(event);
|
||||
|
||||
nsEventStatus dummy = nsEventStatus_eIgnore;
|
||||
@@ -1202,8 +684,7 @@ private:
|
||||
return
|
||||
aWorkerPrivate->DispatchMessageEventToMessagePort(aCx,
|
||||
mMessagePortSerial,
|
||||
Move(mBuffer),
|
||||
mClosure);
|
||||
*this);
|
||||
}
|
||||
|
||||
if (aWorkerPrivate->IsFrozen()) {
|
||||
@@ -3311,9 +2792,8 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||
WorkerRunnable::WorkerThreadModifyBusyCount,
|
||||
aToMessagePort, aMessagePortSerial);
|
||||
|
||||
if (!runnable->Write(aCx, aMessage, transferable,
|
||||
&gWorkerStructuredCloneCallbacks)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
runnable->Write(aCx, aMessage, transferable, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3356,45 +2836,10 @@ template <class Derived>
|
||||
bool
|
||||
WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
JSContext* aCx, uint64_t aMessagePortSerial,
|
||||
JSAutoStructuredCloneBuffer&& aBuffer,
|
||||
WorkerStructuredCloneClosure& aClosure)
|
||||
StructuredCloneHelper& aHelper)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer(Move(aBuffer));
|
||||
|
||||
class MOZ_STACK_CLASS AutoCloneBufferCleaner final
|
||||
{
|
||||
public:
|
||||
AutoCloneBufferCleaner(JSAutoStructuredCloneBuffer& aBuffer,
|
||||
const JSStructuredCloneCallbacks* aCallbacks,
|
||||
WorkerStructuredCloneClosure& aClosure)
|
||||
: mBuffer(aBuffer)
|
||||
, mCallbacks(aCallbacks)
|
||||
, mClosure(aClosure)
|
||||
{}
|
||||
|
||||
~AutoCloneBufferCleaner()
|
||||
{
|
||||
mBuffer.clear(mCallbacks, &mClosure);
|
||||
}
|
||||
|
||||
private:
|
||||
JSAutoStructuredCloneBuffer& mBuffer;
|
||||
const JSStructuredCloneCallbacks* mCallbacks;
|
||||
WorkerStructuredCloneClosure& mClosure;
|
||||
};
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
closure.mClonedObjects.SwapElements(aClosure.mClonedObjects);
|
||||
closure.mClonedImages.SwapElements(aClosure.mClonedImages);
|
||||
MOZ_ASSERT(aClosure.mMessagePorts.IsEmpty());
|
||||
closure.mMessagePortIdentifiers.SwapElements(aClosure.mMessagePortIdentifiers);
|
||||
|
||||
AutoCloneBufferCleaner bufferCleaner(buffer,
|
||||
&gWorkerStructuredCloneCallbacks,
|
||||
closure);
|
||||
|
||||
SharedWorker* sharedWorker;
|
||||
if (!mSharedWorkers.Get(aMessagePortSerial, &sharedWorker)) {
|
||||
// SharedWorker has already been unregistered?
|
||||
@@ -3408,7 +2853,7 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
return true;
|
||||
}
|
||||
|
||||
closure.mParentWindow = do_QueryInterface(port->GetParentObject());
|
||||
nsCOMPtr<nsISupports> parent = do_QueryInterface(port->GetParentObject());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(port->GetParentObject()))) {
|
||||
@@ -3416,24 +2861,27 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
}
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
ErrorResult rv;
|
||||
JS::Rooted<JS::Value> data(cx);
|
||||
if (!buffer.read(cx, &data, &gWorkerStructuredCloneCallbacks,
|
||||
&closure)) {
|
||||
aHelper.Read(parent, cx, &data, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(cx, rv.StealNSResult());
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<MessageEvent> event = new MessageEvent(port, nullptr, nullptr);
|
||||
nsresult rv =
|
||||
event->InitMessageEvent(NS_LITERAL_STRING("message"), false, false, data,
|
||||
EmptyString(), EmptyString(), nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, rv);
|
||||
rv = event->InitMessageEvent(NS_LITERAL_STRING("message"), false, false, data,
|
||||
EmptyString(), EmptyString(), nullptr);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(cx, rv.StealNSResult());
|
||||
return false;
|
||||
}
|
||||
|
||||
event->SetTrusted(true);
|
||||
nsTArray<nsRefPtr<MessagePortBase>> ports;
|
||||
aHelper.TakeTransferredPorts(ports);
|
||||
|
||||
event->SetPorts(new MessagePortList(port, closure.mMessagePorts));
|
||||
event->SetTrusted(true);
|
||||
event->SetPorts(new MessagePortList(port, ports));
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
CallQueryInterface(event.get(), getter_AddRefs(domEvent));
|
||||
@@ -3441,8 +2889,8 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
|
||||
bool ignored;
|
||||
rv = port->DispatchEvent(domEvent, &ignored);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
xpc::Throw(cx, rv.StealNSResult());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5936,7 +5384,9 @@ WorkerPrivate::RunCurrentSyncLoop()
|
||||
MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(mThread, false));
|
||||
|
||||
// Now *might* be a good time to GC. Let the JS engine make the decision.
|
||||
JS_MaybeGC(cx);
|
||||
if (JS::CurrentGlobalOrNull(cx)) {
|
||||
JS_MaybeGC(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6082,9 +5532,8 @@ WorkerPrivate::PostMessageToParentInternal(
|
||||
WorkerRunnable::ParentThreadUnchangedBusyCount,
|
||||
aToMessagePort, aMessagePortSerial);
|
||||
|
||||
if (!runnable->Write(aCx, aMessage, transferable,
|
||||
&gWorkerStructuredCloneCallbacks)) {
|
||||
aRv = NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
runnable->Write(aCx, aMessage, transferable, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6166,7 +5615,9 @@ WorkerPrivate::EnterDebuggerEventLoop()
|
||||
runnable->Release();
|
||||
|
||||
// Now *might* be a good time to GC. Let the JS engine make the decision.
|
||||
JS_MaybeGC(cx);
|
||||
if (JS::CurrentGlobalOrNull(cx)) {
|
||||
JS_MaybeGC(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6414,7 +5865,8 @@ WorkerPrivate::ReportError(JSContext* aCx, const char* aMessage,
|
||||
// if there was an error in the close handler or if we ran out of memory.
|
||||
bool fireAtScope = mErrorHandlerRecursionCount == 1 &&
|
||||
!mCloseHandlerStarted &&
|
||||
errorNumber != JSMSG_OUT_OF_MEMORY;
|
||||
errorNumber != JSMSG_OUT_OF_MEMORY &&
|
||||
JS::CurrentGlobalOrNull(aCx);
|
||||
|
||||
if (!ReportErrorRunnable::ReportError(aCx, this, fireAtScope, nullptr, message,
|
||||
filename, line, lineNumber,
|
||||
@@ -6803,7 +6255,7 @@ WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
if (!JS::CurrentGlobalOrNull(aCx)) {
|
||||
if (!GlobalScope()) {
|
||||
// We haven't compiled anything yet. Just bail out.
|
||||
return;
|
||||
}
|
||||
@@ -7052,13 +6504,16 @@ WorkerPrivate::GetOrCreateGlobalScope(JSContext* aCx)
|
||||
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
|
||||
// RegisterBindings() can spin a nested event loop so we have to set mScope
|
||||
// before calling it, and we have to make sure to unset mScope if it fails.
|
||||
mScope = Move(globalScope);
|
||||
|
||||
if (!RegisterBindings(aCx, global)) {
|
||||
mScope = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS_FireOnNewGlobalObject(aCx, global);
|
||||
|
||||
mScope = globalScope.forget();
|
||||
}
|
||||
|
||||
return mScope;
|
||||
@@ -7225,30 +6680,7 @@ GetWorkerCrossThreadDispatcher(JSContext* aCx, JS::Value aWorker)
|
||||
return w->GetCrossThreadDispatcher();
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks*
|
||||
WorkerStructuredCloneCallbacks()
|
||||
{
|
||||
return &gWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
|
||||
// Force instantiation.
|
||||
template class WorkerPrivateParent<WorkerPrivate>;
|
||||
|
||||
WorkerStructuredCloneClosure::WorkerStructuredCloneClosure()
|
||||
{}
|
||||
|
||||
WorkerStructuredCloneClosure::~WorkerStructuredCloneClosure()
|
||||
{}
|
||||
|
||||
void
|
||||
WorkerStructuredCloneClosure::Clear()
|
||||
{
|
||||
mParentWindow = nullptr;
|
||||
mClonedObjects.Clear();
|
||||
mClonedImages.Clear();
|
||||
mMessagePorts.Clear();
|
||||
mMessagePortIdentifiers.Clear();
|
||||
mTransferredPorts.Clear();
|
||||
}
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
@@ -28,12 +28,10 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
|
||||
#include "Queue.h"
|
||||
#include "WorkerFeature.h"
|
||||
|
||||
class JSAutoStructuredCloneBuffer;
|
||||
class nsIChannel;
|
||||
class nsIDocument;
|
||||
class nsIEventTarget;
|
||||
@@ -52,6 +50,7 @@ struct RuntimeStats;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Function;
|
||||
class StructuredCloneHelper;
|
||||
} // namespace dom
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
@@ -74,7 +73,6 @@ class WorkerDebuggerGlobalScope;
|
||||
class WorkerGlobalScope;
|
||||
class WorkerPrivate;
|
||||
class WorkerRunnable;
|
||||
class WorkerStructuredCloneClosure;
|
||||
class WorkerThread;
|
||||
|
||||
// SharedMutex is a small wrapper around an (internal) reference-counted Mutex
|
||||
@@ -350,8 +348,7 @@ public:
|
||||
DispatchMessageEventToMessagePort(
|
||||
JSContext* aCx,
|
||||
uint64_t aMessagePortSerial,
|
||||
JSAutoStructuredCloneBuffer&& aBuffer,
|
||||
WorkerStructuredCloneClosure& aClosure);
|
||||
StructuredCloneHelper& aHelper);
|
||||
|
||||
void
|
||||
UpdateRuntimeOptions(JSContext* aCx,
|
||||
@@ -1511,17 +1508,6 @@ IsCurrentThreadRunningChromeWorker();
|
||||
JSContext*
|
||||
GetCurrentThreadJSContext();
|
||||
|
||||
enum WorkerStructuredDataType
|
||||
{
|
||||
DOMWORKER_SCTAG_BLOB = SCTAG_DOM_MAX,
|
||||
DOMWORKER_SCTAG_FORMDATA = SCTAG_DOM_MAX + 1,
|
||||
|
||||
DOMWORKER_SCTAG_END
|
||||
};
|
||||
|
||||
const JSStructuredCloneCallbacks*
|
||||
WorkerStructuredCloneCallbacks();
|
||||
|
||||
class AutoSyncLoopHolder
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
|
||||
@@ -418,6 +418,20 @@ DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
|
||||
JS::CompartmentOptions options;
|
||||
mWorkerPrivate->CopyJSCompartmentOptions(options);
|
||||
|
||||
const bool usesSystemPrincipal = mWorkerPrivate->UsesSystemPrincipal();
|
||||
|
||||
// Note that xpc::ShouldDiscardSystemSource() and
|
||||
// xpc::ExtraWarningsForSystemJS() read prefs that are cached on the main
|
||||
// thread. This is benignly racey.
|
||||
const bool discardSource = (usesSystemPrincipal ||
|
||||
mWorkerPrivate->IsInPrivilegedApp()) &&
|
||||
xpc::ShouldDiscardSystemSource();
|
||||
const bool extraWarnings = usesSystemPrincipal &&
|
||||
xpc::ExtraWarningsForSystemJS();
|
||||
|
||||
options.setDiscardSource(discardSource)
|
||||
.extraWarningsOverride().set(extraWarnings);
|
||||
|
||||
return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
|
||||
options,
|
||||
GetWorkerPrincipal(),
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_workers_WorkerStructuredClone_h
|
||||
#define mozilla_dom_workers_WorkerStructuredClone_h
|
||||
|
||||
#include "Workers.h"
|
||||
#include "mozilla/dom/PMessagePort.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
class MessagePortBase;
|
||||
|
||||
namespace workers {
|
||||
|
||||
// This class is implemented in WorkerPrivate.cpp
|
||||
class WorkerStructuredCloneClosure final
|
||||
{
|
||||
private:
|
||||
WorkerStructuredCloneClosure(const WorkerStructuredCloneClosure&) = delete;
|
||||
WorkerStructuredCloneClosure & operator=(const WorkerStructuredCloneClosure&) = delete;
|
||||
|
||||
public:
|
||||
WorkerStructuredCloneClosure();
|
||||
~WorkerStructuredCloneClosure();
|
||||
|
||||
void Clear();
|
||||
|
||||
// This can be null if the MessagePort is created in a worker.
|
||||
nsCOMPtr<nsPIDOMWindow> mParentWindow;
|
||||
|
||||
nsTArray<nsCOMPtr<nsISupports>> mClonedObjects;
|
||||
|
||||
// This is used for sharing the backend of ImageBitmaps.
|
||||
// The layers::Image object must be thread-safely reference-counted.
|
||||
// The layers::Image object will not be written ever via any ImageBitmap
|
||||
// instance, so no race condition will occur.
|
||||
nsTArray<nsRefPtr<layers::Image>> mClonedImages;
|
||||
|
||||
// The transferred ports.
|
||||
nsTArray<nsRefPtr<MessagePortBase>> mMessagePorts;
|
||||
|
||||
// Information for the transferring.
|
||||
nsTArray<MessagePortIdentifier> mMessagePortIdentifiers;
|
||||
|
||||
// To avoid duplicates in the transferred ports.
|
||||
nsTArray<nsRefPtr<MessagePortBase>> mTransferredPorts;
|
||||
};
|
||||
|
||||
} // workers namespace
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_workers_WorkerStructuredClone_h
|
||||
+170
-197
@@ -18,6 +18,7 @@
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/ProgressEvent.h"
|
||||
#include "mozilla/dom/StructuredCloneHelper.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFormData.h"
|
||||
@@ -27,7 +28,6 @@
|
||||
#include "RuntimeService.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerStructuredClone.h"
|
||||
#include "XMLHttpRequestUpload.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@@ -175,6 +175,117 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class WorkerThreadProxySyncRunnable : public nsRunnable
|
||||
{
|
||||
protected:
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsRefPtr<Proxy> mProxy;
|
||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||
|
||||
private:
|
||||
class ResponseRunnable final: public MainThreadStopSyncLoopRunnable
|
||||
{
|
||||
nsRefPtr<Proxy> mProxy;
|
||||
nsresult mErrorCode;
|
||||
|
||||
public:
|
||||
ResponseRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
|
||||
nsresult aErrorCode)
|
||||
: MainThreadStopSyncLoopRunnable(aWorkerPrivate, aProxy->GetEventTarget(),
|
||||
NS_SUCCEEDED(aErrorCode)),
|
||||
mProxy(aProxy), mErrorCode(aErrorCode)
|
||||
{
|
||||
MOZ_ASSERT(aProxy);
|
||||
}
|
||||
|
||||
private:
|
||||
~ResponseRunnable()
|
||||
{ }
|
||||
|
||||
virtual void
|
||||
MaybeSetException(JSContext* aCx) override
|
||||
{
|
||||
MOZ_ASSERT(NS_FAILED(mErrorCode));
|
||||
|
||||
Throw(aCx, mErrorCode);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
WorkerThreadProxySyncRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy)
|
||||
: mWorkerPrivate(aWorkerPrivate), mProxy(aProxy)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aProxy);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
bool
|
||||
Dispatch(JSContext* aCx)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
|
||||
mSyncLoopTarget = syncLoop.EventTarget();
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(this))) {
|
||||
JS_ReportError(aCx, "Failed to dispatch to main thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return syncLoop.Run();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WorkerThreadProxySyncRunnable()
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
MainThreadRun() = 0;
|
||||
|
||||
private:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
};
|
||||
|
||||
class SendRunnable final
|
||||
: public WorkerThreadProxySyncRunnable
|
||||
, public StructuredCloneHelper
|
||||
{
|
||||
nsString mStringBody;
|
||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||
bool mHasUploadListeners;
|
||||
|
||||
public:
|
||||
SendRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
|
||||
const nsAString& aStringBody)
|
||||
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy)
|
||||
, StructuredCloneHelper(CloningSupported, TransferringNotSupported,
|
||||
SameProcessDifferentThread)
|
||||
, mStringBody(aStringBody)
|
||||
, mHasUploadListeners(false)
|
||||
{
|
||||
}
|
||||
|
||||
void SetHaveUploadListeners(bool aHasUploadListeners)
|
||||
{
|
||||
mHasUploadListeners = aHasUploadListeners;
|
||||
}
|
||||
|
||||
void SetSyncLoopTarget(nsIEventTarget* aSyncLoopTarget)
|
||||
{
|
||||
mSyncLoopTarget = aSyncLoopTarget;
|
||||
}
|
||||
|
||||
private:
|
||||
~SendRunnable()
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
MainThreadRun() override;
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
||||
namespace {
|
||||
@@ -410,11 +521,10 @@ private:
|
||||
};
|
||||
|
||||
class EventRunnable final : public MainThreadProxyRunnable
|
||||
, public StructuredCloneHelper
|
||||
{
|
||||
nsString mType;
|
||||
nsString mResponseType;
|
||||
JSAutoStructuredCloneBuffer mResponseBuffer;
|
||||
WorkerStructuredCloneClosure mResponseClosure;
|
||||
JS::Heap<JS::Value> mResponse;
|
||||
nsString mResponseText;
|
||||
nsString mResponseURL;
|
||||
@@ -456,17 +566,21 @@ public:
|
||||
|
||||
EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType,
|
||||
bool aLengthComputable, uint64_t aLoaded, uint64_t aTotal)
|
||||
: MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy), mType(aType),
|
||||
mResponse(JS::UndefinedValue()), mLoaded(aLoaded), mTotal(aTotal),
|
||||
mEventStreamId(aProxy->mInnerEventStreamId), mStatus(0), mReadyState(0),
|
||||
mUploadEvent(aUploadEvent), mProgressEvent(true),
|
||||
: MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy),
|
||||
StructuredCloneHelper(CloningSupported, TransferringNotSupported,
|
||||
SameProcessDifferentThread),
|
||||
mType(aType), mResponse(JS::UndefinedValue()), mLoaded(aLoaded),
|
||||
mTotal(aTotal), mEventStreamId(aProxy->mInnerEventStreamId), mStatus(0),
|
||||
mReadyState(0), mUploadEvent(aUploadEvent), mProgressEvent(true),
|
||||
mLengthComputable(aLengthComputable), mUseCachedArrayBufferResponse(false),
|
||||
mResponseTextResult(NS_OK), mStatusResult(NS_OK), mResponseResult(NS_OK)
|
||||
{ }
|
||||
|
||||
EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType)
|
||||
: MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy), mType(aType),
|
||||
mResponse(JS::UndefinedValue()), mLoaded(0), mTotal(0),
|
||||
: MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy),
|
||||
StructuredCloneHelper(CloningSupported, TransferringNotSupported,
|
||||
SameProcessDifferentThread),
|
||||
mType(aType), mResponse(JS::UndefinedValue()), mLoaded(0), mTotal(0),
|
||||
mEventStreamId(aProxy->mInnerEventStreamId), mStatus(0), mReadyState(0),
|
||||
mUploadEvent(aUploadEvent), mProgressEvent(false), mLengthComputable(0),
|
||||
mUseCachedArrayBufferResponse(false), mResponseTextResult(NS_OK),
|
||||
@@ -484,80 +598,6 @@ private:
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
|
||||
};
|
||||
|
||||
class WorkerThreadProxySyncRunnable : public nsRunnable
|
||||
{
|
||||
protected:
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsRefPtr<Proxy> mProxy;
|
||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||
|
||||
private:
|
||||
class ResponseRunnable final: public MainThreadStopSyncLoopRunnable
|
||||
{
|
||||
nsRefPtr<Proxy> mProxy;
|
||||
nsresult mErrorCode;
|
||||
|
||||
public:
|
||||
ResponseRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
|
||||
nsresult aErrorCode)
|
||||
: MainThreadStopSyncLoopRunnable(aWorkerPrivate, aProxy->GetEventTarget(),
|
||||
NS_SUCCEEDED(aErrorCode)),
|
||||
mProxy(aProxy), mErrorCode(aErrorCode)
|
||||
{
|
||||
MOZ_ASSERT(aProxy);
|
||||
}
|
||||
|
||||
private:
|
||||
~ResponseRunnable()
|
||||
{ }
|
||||
|
||||
virtual void
|
||||
MaybeSetException(JSContext* aCx) override
|
||||
{
|
||||
MOZ_ASSERT(NS_FAILED(mErrorCode));
|
||||
|
||||
Throw(aCx, mErrorCode);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
WorkerThreadProxySyncRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy)
|
||||
: mWorkerPrivate(aWorkerPrivate), mProxy(aProxy)
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aProxy);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
bool
|
||||
Dispatch(JSContext* aCx)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
|
||||
mSyncLoopTarget = syncLoop.EventTarget();
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(this))) {
|
||||
JS_ReportError(aCx, "Failed to dispatch to main thread!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return syncLoop.Run();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WorkerThreadProxySyncRunnable()
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
MainThreadRun() = 0;
|
||||
|
||||
private:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
};
|
||||
|
||||
class SyncTeardownRunnable final : public WorkerThreadProxySyncRunnable
|
||||
{
|
||||
public:
|
||||
@@ -791,39 +831,6 @@ private:
|
||||
MainThreadRunInternal();
|
||||
};
|
||||
|
||||
class SendRunnable final : public WorkerThreadProxySyncRunnable
|
||||
{
|
||||
nsString mStringBody;
|
||||
JSAutoStructuredCloneBuffer mBody;
|
||||
WorkerStructuredCloneClosure mClosure;
|
||||
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
|
||||
bool mHasUploadListeners;
|
||||
|
||||
public:
|
||||
SendRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
|
||||
const nsAString& aStringBody, JSAutoStructuredCloneBuffer&& aBody,
|
||||
WorkerStructuredCloneClosure& aClosure,
|
||||
nsIEventTarget* aSyncLoopTarget, bool aHasUploadListeners)
|
||||
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy)
|
||||
, mStringBody(aStringBody)
|
||||
, mBody(Move(aBody))
|
||||
, mSyncLoopTarget(aSyncLoopTarget)
|
||||
, mHasUploadListeners(aHasUploadListeners)
|
||||
{
|
||||
mClosure.mClonedObjects.SwapElements(aClosure.mClonedObjects);
|
||||
mClosure.mClonedImages.SwapElements(aClosure.mClonedImages);
|
||||
MOZ_ASSERT(aClosure.mMessagePorts.IsEmpty());
|
||||
MOZ_ASSERT(aClosure.mMessagePortIdentifiers.IsEmpty());
|
||||
}
|
||||
|
||||
private:
|
||||
~SendRunnable()
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
MainThreadRun() override;
|
||||
};
|
||||
|
||||
class SetRequestHeaderRunnable final : public WorkerThreadProxySyncRunnable
|
||||
{
|
||||
nsCString mHeader;
|
||||
@@ -1227,21 +1234,11 @@ EventRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
}
|
||||
|
||||
if (doClone) {
|
||||
// Anything subject to GC must be cloned.
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
workers::WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
if (mResponseBuffer.write(aCx, response, transferable, callbacks,
|
||||
&closure)) {
|
||||
mResponseClosure.mClonedObjects.SwapElements(closure.mClonedObjects);
|
||||
mResponseClosure.mClonedImages.SwapElements(closure.mClonedImages);
|
||||
MOZ_ASSERT(mResponseClosure.mMessagePorts.IsEmpty());
|
||||
MOZ_ASSERT(mResponseClosure.mMessagePortIdentifiers.IsEmpty());
|
||||
} else {
|
||||
ErrorResult rv;
|
||||
Write(aCx, response, transferable, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
NS_WARNING("Failed to clone response!");
|
||||
mResponseResult = NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
mResponseResult = rv.StealNSResult();
|
||||
mProxy->mArrayBufferResponseWasTransferred = false;
|
||||
}
|
||||
}
|
||||
@@ -1336,22 +1333,14 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
state->mResponseResult = mResponseResult;
|
||||
|
||||
if (NS_SUCCEEDED(mResponseResult)) {
|
||||
if (mResponseBuffer.data()) {
|
||||
if (HasBeenWritten()) {
|
||||
MOZ_ASSERT(mResponse.isUndefined());
|
||||
|
||||
JSAutoStructuredCloneBuffer responseBuffer(Move(mResponseBuffer));
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
workers::WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
closure.mClonedObjects.SwapElements(mResponseClosure.mClonedObjects);
|
||||
closure.mClonedImages.SwapElements(mResponseClosure.mClonedImages);
|
||||
MOZ_ASSERT(mResponseClosure.mMessagePorts.IsEmpty());
|
||||
MOZ_ASSERT(mResponseClosure.mMessagePortIdentifiers.IsEmpty());
|
||||
|
||||
ErrorResult rv;
|
||||
JS::Rooted<JS::Value> response(aCx);
|
||||
if (!responseBuffer.read(aCx, &response, callbacks, &closure)) {
|
||||
Read(nullptr, aCx, &response, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1517,32 +1506,25 @@ SendRunnable::MainThreadRun()
|
||||
{
|
||||
nsCOMPtr<nsIVariant> variant;
|
||||
|
||||
if (mBody.data()) {
|
||||
if (HasBeenWritten()) {
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
MOZ_ASSERT(xpc);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
workers::WorkerStructuredCloneCallbacks();
|
||||
ErrorResult rv;
|
||||
|
||||
JS::Rooted<JS::Value> body(cx);
|
||||
if (mBody.read(cx, &body, callbacks, &mClosure)) {
|
||||
if (NS_FAILED(xpc->JSValToVariant(cx, body, getter_AddRefs(variant)))) {
|
||||
rv = NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
Read(nullptr, cx, &body, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
mBody.clear();
|
||||
mClosure.Clear();
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = xpc->JSValToVariant(cx, body, getter_AddRefs(variant));
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIWritableVariant> wvariant =
|
||||
@@ -1845,11 +1827,10 @@ XMLHttpRequest::Unpin()
|
||||
}
|
||||
|
||||
void
|
||||
XMLHttpRequest::SendInternal(const nsAString& aStringBody,
|
||||
JSAutoStructuredCloneBuffer&& aBody,
|
||||
WorkerStructuredCloneClosure& aClosure,
|
||||
XMLHttpRequest::SendInternal(SendRunnable* aRunnable,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aRunnable);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
// No send() calls when open is running.
|
||||
@@ -1879,10 +1860,10 @@ XMLHttpRequest::SendInternal(const nsAString& aStringBody,
|
||||
|
||||
JSContext* cx = mWorkerPrivate->GetJSContext();
|
||||
|
||||
nsRefPtr<SendRunnable> runnable =
|
||||
new SendRunnable(mWorkerPrivate, mProxy, aStringBody, Move(aBody),
|
||||
aClosure, syncLoopTarget, hasUploadListeners);
|
||||
if (!runnable->Dispatch(cx)) {
|
||||
aRunnable->SetSyncLoopTarget(syncLoopTarget);
|
||||
aRunnable->SetHaveUploadListeners(hasUploadListeners);
|
||||
|
||||
if (!aRunnable->Dispatch(cx)) {
|
||||
// Dispatch() may have spun the event loop and we may have already unrooted.
|
||||
// If so we don't want autoUnpin to try again.
|
||||
if (!mRooted) {
|
||||
@@ -2109,11 +2090,11 @@ XMLHttpRequest::Send(ErrorResult& aRv)
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing to clone.
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
WorkerStructuredCloneClosure closure;
|
||||
nsRefPtr<SendRunnable> sendRunnable =
|
||||
new SendRunnable(mWorkerPrivate, mProxy, NullString());
|
||||
|
||||
SendInternal(NullString(), Move(buffer), closure, aRv);
|
||||
// Nothing to clone.
|
||||
SendInternal(sendRunnable, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2131,11 +2112,11 @@ XMLHttpRequest::Send(const nsAString& aBody, ErrorResult& aRv)
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing to clone.
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
WorkerStructuredCloneClosure closure;
|
||||
nsRefPtr<SendRunnable> sendRunnable =
|
||||
new SendRunnable(mWorkerPrivate, mProxy, aBody);
|
||||
|
||||
SendInternal(aBody, Move(buffer), closure, aRv);
|
||||
// Nothing to clone.
|
||||
SendInternal(sendRunnable, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2171,18 +2152,15 @@ XMLHttpRequest::Send(JS::Handle<JSObject*> aBody, ErrorResult& aRv)
|
||||
valToClone.setString(bodyStr);
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
WorkerStructuredCloneCallbacks();
|
||||
nsRefPtr<SendRunnable> sendRunnable =
|
||||
new SendRunnable(mWorkerPrivate, mProxy, EmptyString());
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (!buffer.write(cx, valToClone, callbacks, &closure)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
sendRunnable->Write(cx, valToClone, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendInternal(EmptyString(), Move(buffer), closure, aRv);
|
||||
SendInternal(sendRunnable, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2215,18 +2193,15 @@ XMLHttpRequest::Send(Blob& aBody, ErrorResult& aRv)
|
||||
return;
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
WorkerStructuredCloneCallbacks();
|
||||
nsRefPtr<SendRunnable> sendRunnable =
|
||||
new SendRunnable(mWorkerPrivate, mProxy, EmptyString());
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
if (!buffer.write(cx, value, callbacks, &closure)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
sendRunnable->Write(cx, value, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendInternal(EmptyString(), Move(buffer), closure, aRv);
|
||||
SendInternal(sendRunnable, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2251,17 +2226,15 @@ XMLHttpRequest::Send(nsFormData& aBody, ErrorResult& aRv)
|
||||
return;
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
WorkerStructuredCloneCallbacks();
|
||||
nsRefPtr<SendRunnable> sendRunnable =
|
||||
new SendRunnable(mWorkerPrivate, mProxy, EmptyString());
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
WorkerStructuredCloneClosure closure;
|
||||
if (!buffer.write(cx, value, callbacks, &closure)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
sendRunnable->Write(cx, value, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SendInternal(EmptyString(), Move(buffer), closure, aRv);
|
||||
SendInternal(sendRunnable, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
|
||||
#include "js/StructuredClone.h"
|
||||
#include "nsXMLHttpRequest.h"
|
||||
|
||||
namespace mozilla {
|
||||
@@ -26,9 +25,9 @@ class Blob;
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
class Proxy;
|
||||
class SendRunnable;
|
||||
class XMLHttpRequestUpload;
|
||||
class WorkerPrivate;
|
||||
class WorkerStructuredCloneClosure;
|
||||
|
||||
class XMLHttpRequest final: public nsXHREventTarget,
|
||||
public WorkerFeature
|
||||
@@ -291,9 +290,7 @@ private:
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
SendInternal(const nsAString& aStringBody,
|
||||
JSAutoStructuredCloneBuffer&& aBody,
|
||||
WorkerStructuredCloneClosure& aClosure,
|
||||
SendInternal(SendRunnable* aRunnable,
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
|
||||
@@ -3220,7 +3220,7 @@ gfxMissingFontRecorder::Flush()
|
||||
}
|
||||
mNotifiedFonts[i] |= (1 << j);
|
||||
if (!fontNeeded.IsEmpty()) {
|
||||
fontNeeded.Append(PRUnichar(','));
|
||||
fontNeeded.Append(char16_t(','));
|
||||
}
|
||||
uint32_t tag = GetScriptTagForCode(i * 32 + j);
|
||||
fontNeeded.Append(char16_t(tag >> 24));
|
||||
|
||||
@@ -1,533 +0,0 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BluetoothDaemonConnection.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include "mozilla/ipc/BluetoothDaemonConnectionConsumer.h"
|
||||
#include "mozilla/ipc/DataSocket.h"
|
||||
#include "mozilla/ipc/UnixSocketConnector.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#ifdef CHROMIUM_LOG
|
||||
#undef CHROMIUM_LOG
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
#include <android/log.h>
|
||||
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args);
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define IODEBUG true
|
||||
#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
// The connection to the Bluetooth daemon is established
|
||||
// using an abstract socket name. The \0 prefix will be added
|
||||
// by the |Connect| method.
|
||||
static const char sBluetoothdSocketName[] = "bluez_hal_socket";
|
||||
|
||||
//
|
||||
// BluetoothDaemonPDU
|
||||
//
|
||||
|
||||
BluetoothDaemonPDU::BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode,
|
||||
uint16_t aPayloadSize)
|
||||
: UnixSocketIOBuffer(HEADER_SIZE + aPayloadSize)
|
||||
, mConsumer(nullptr)
|
||||
, mUserData(nullptr)
|
||||
{
|
||||
uint8_t* data = Append(HEADER_SIZE);
|
||||
MOZ_ASSERT(data);
|
||||
|
||||
// Setup PDU header
|
||||
data[OFF_SERVICE] = aService;
|
||||
data[OFF_OPCODE] = aOpcode;
|
||||
memcpy(data + OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize));
|
||||
}
|
||||
|
||||
BluetoothDaemonPDU::BluetoothDaemonPDU(size_t aPayloadSize)
|
||||
: UnixSocketIOBuffer(HEADER_SIZE + aPayloadSize)
|
||||
, mConsumer(nullptr)
|
||||
, mUserData(nullptr)
|
||||
{ }
|
||||
|
||||
void
|
||||
BluetoothDaemonPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode,
|
||||
uint16_t& aPayloadSize)
|
||||
{
|
||||
memcpy(&aService, GetData(OFF_SERVICE), sizeof(aService));
|
||||
memcpy(&aOpcode, GetData(OFF_OPCODE), sizeof(aOpcode));
|
||||
memcpy(&aPayloadSize, GetData(OFF_LENGTH), sizeof(aPayloadSize));
|
||||
}
|
||||
|
||||
ssize_t
|
||||
BluetoothDaemonPDU::Send(int aFd)
|
||||
{
|
||||
struct iovec iv;
|
||||
memset(&iv, 0, sizeof(iv));
|
||||
iv.iov_base = GetData(GetLeadingSpace());
|
||||
iv.iov_len = GetSize();
|
||||
|
||||
struct msghdr msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = &iv;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = nullptr;
|
||||
msg.msg_controllen = 0;
|
||||
|
||||
ssize_t res = TEMP_FAILURE_RETRY(sendmsg(aFd, &msg, 0));
|
||||
if (res < 0) {
|
||||
MOZ_ASSERT(errno != EBADF); /* internal error */
|
||||
OnError("sendmsg", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Consume(res);
|
||||
|
||||
if (mConsumer) {
|
||||
// We successfully sent a PDU, now store the
|
||||
// result runnable in the consumer.
|
||||
mConsumer->StoreUserData(*this);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
|
||||
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
|
||||
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
|
||||
|
||||
ssize_t
|
||||
BluetoothDaemonPDU::Receive(int aFd)
|
||||
{
|
||||
struct iovec iv;
|
||||
memset(&iv, 0, sizeof(iv));
|
||||
iv.iov_base = GetData(0);
|
||||
iv.iov_len = GetAvailableSpace();
|
||||
|
||||
uint8_t cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||
|
||||
struct msghdr msg;
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.msg_iov = &iv;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf);
|
||||
|
||||
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL));
|
||||
if (res < 0) {
|
||||
MOZ_ASSERT(errno != EBADF); /* internal error */
|
||||
OnError("recvmsg", errno);
|
||||
return -1;
|
||||
}
|
||||
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SetRange(0, res);
|
||||
|
||||
struct cmsghdr *chdr = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) {
|
||||
if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) {
|
||||
continue;
|
||||
}
|
||||
// Retrieve sent file descriptor. If multiple file descriptors
|
||||
// have been sent, we close all but the final one.
|
||||
mReceivedFd = *(static_cast<int*>(CMSG_DATA(chdr)));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
BluetoothDaemonPDU::AcquireFd()
|
||||
{
|
||||
return mReceivedFd.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonPDU::UpdateHeader()
|
||||
{
|
||||
size_t len = GetPayloadSize();
|
||||
if (len >= MAX_PAYLOAD_LENGTH) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
uint16_t len16 = static_cast<uint16_t>(len);
|
||||
|
||||
memcpy(GetData(OFF_LENGTH), &len16, sizeof(len16));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
size_t
|
||||
BluetoothDaemonPDU::GetPayloadSize() const
|
||||
{
|
||||
MOZ_ASSERT(GetSize() >= HEADER_SIZE);
|
||||
|
||||
return GetSize() - HEADER_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonPDU::OnError(const char* aFunction, int aErrno)
|
||||
{
|
||||
CHROMIUM_LOG("%s failed with error %d (%s)",
|
||||
aFunction, aErrno, strerror(aErrno));
|
||||
}
|
||||
|
||||
//
|
||||
// BluetoothDaemonPDUConsumer
|
||||
//
|
||||
|
||||
BluetoothDaemonPDUConsumer::BluetoothDaemonPDUConsumer()
|
||||
{ }
|
||||
|
||||
BluetoothDaemonPDUConsumer::~BluetoothDaemonPDUConsumer()
|
||||
{ }
|
||||
|
||||
//
|
||||
// BluetoothDaemonConnectionIO
|
||||
//
|
||||
|
||||
class BluetoothDaemonConnectionIO final
|
||||
: public UnixSocketWatcher
|
||||
, public ConnectionOrientedSocketIO
|
||||
{
|
||||
public:
|
||||
BluetoothDaemonConnectionIO(MessageLoop* aIOLoop, int aFd,
|
||||
ConnectionStatus aConnectionStatus,
|
||||
BluetoothDaemonConnection* aConnection,
|
||||
BluetoothDaemonPDUConsumer* aConsumer);
|
||||
|
||||
// Task callback methods
|
||||
//
|
||||
|
||||
void Send(UnixSocketIOBuffer* aBuffer);
|
||||
|
||||
void OnSocketCanReceiveWithoutBlocking() override;
|
||||
void OnSocketCanSendWithoutBlocking() override;
|
||||
|
||||
void OnConnected() override;
|
||||
void OnError(const char* aFunction, int aErrno) override;
|
||||
|
||||
// Methods for |ConnectionOrientedSocketIO|
|
||||
//
|
||||
|
||||
nsresult Accept(int aFd,
|
||||
const struct sockaddr* aAddress,
|
||||
socklen_t aAddressLength) override;
|
||||
|
||||
// Methods for |DataSocketIO|
|
||||
//
|
||||
|
||||
nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override;
|
||||
void ConsumeBuffer() override;
|
||||
void DiscardBuffer() override;
|
||||
|
||||
// Methods for |SocketIOBase|
|
||||
//
|
||||
|
||||
SocketBase* GetSocketBase() override;
|
||||
|
||||
bool IsShutdownOnMainThread() const override;
|
||||
bool IsShutdownOnIOThread() const override;
|
||||
|
||||
void ShutdownOnMainThread() override;
|
||||
void ShutdownOnIOThread() override;
|
||||
|
||||
private:
|
||||
BluetoothDaemonConnection* mConnection;
|
||||
BluetoothDaemonPDUConsumer* mConsumer;
|
||||
nsAutoPtr<BluetoothDaemonPDU> mPDU;
|
||||
bool mShuttingDownOnIOThread;
|
||||
};
|
||||
|
||||
BluetoothDaemonConnectionIO::BluetoothDaemonConnectionIO(
|
||||
MessageLoop* aIOLoop, int aFd,
|
||||
ConnectionStatus aConnectionStatus,
|
||||
BluetoothDaemonConnection* aConnection,
|
||||
BluetoothDaemonPDUConsumer* aConsumer)
|
||||
: UnixSocketWatcher(aIOLoop, aFd, aConnectionStatus)
|
||||
, mConnection(aConnection)
|
||||
, mConsumer(aConsumer)
|
||||
, mShuttingDownOnIOThread(false)
|
||||
{
|
||||
MOZ_ASSERT(mConnection);
|
||||
MOZ_ASSERT(mConsumer);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::Send(UnixSocketIOBuffer* aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(aBuffer);
|
||||
|
||||
EnqueueData(aBuffer);
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::OnSocketCanReceiveWithoutBlocking()
|
||||
{
|
||||
ssize_t res = ReceiveData(GetFd());
|
||||
if (res < 0) {
|
||||
/* I/O error */
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
} else if (!res) {
|
||||
/* EOF or peer shutdown */
|
||||
RemoveWatchers(READ_WATCHER);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::OnSocketCanSendWithoutBlocking()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
|
||||
MOZ_ASSERT(!IsShutdownOnIOThread());
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(SendPendingData(GetFd())))) {
|
||||
RemoveWatchers(WRITE_WATCHER);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::OnConnected()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::OnError(const char* aFunction, int aErrno)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
|
||||
UnixFdWatcher::OnError(aFunction, aErrno);
|
||||
|
||||
// Clean up watchers, status, fd
|
||||
Close();
|
||||
|
||||
// Tell the main thread we've errored
|
||||
NS_DispatchToMainThread(
|
||||
new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
|
||||
}
|
||||
|
||||
// |ConnectionOrientedSocketIO|
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonConnectionIO::Accept(int aFd,
|
||||
const struct sockaddr* aAddress,
|
||||
socklen_t aAddressLength)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTING);
|
||||
|
||||
// File-descriptor setup
|
||||
|
||||
if (TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, O_NONBLOCK)) < 0) {
|
||||
OnError("fcntl", errno);
|
||||
ScopedClose cleanupFd(aFd);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
SetSocket(aFd, SOCKET_IS_CONNECTED);
|
||||
|
||||
// Signal success
|
||||
OnConnected();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// |DataSocketIO|
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonConnectionIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(aBuffer);
|
||||
|
||||
if (!mPDU) {
|
||||
/* There's only one PDU for receiving. We reuse it every time. */
|
||||
mPDU = new BluetoothDaemonPDU(BluetoothDaemonPDU::MAX_PAYLOAD_LENGTH);
|
||||
}
|
||||
*aBuffer = mPDU.get();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::ConsumeBuffer()
|
||||
{
|
||||
MOZ_ASSERT(mConsumer);
|
||||
|
||||
mConsumer->Handle(*mPDU);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::DiscardBuffer()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
// |SocketIOBase|
|
||||
|
||||
SocketBase*
|
||||
BluetoothDaemonConnectionIO::GetSocketBase()
|
||||
{
|
||||
return mConnection;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothDaemonConnectionIO::IsShutdownOnMainThread() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
return mConnection == nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothDaemonConnectionIO::IsShutdownOnIOThread() const
|
||||
{
|
||||
return mShuttingDownOnIOThread;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::ShutdownOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsShutdownOnMainThread());
|
||||
|
||||
mConnection = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnectionIO::ShutdownOnIOThread()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
Close(); // will also remove fd from I/O loop
|
||||
mShuttingDownOnIOThread = true;
|
||||
}
|
||||
|
||||
//
|
||||
// BluetoothDaemonConnection
|
||||
//
|
||||
|
||||
BluetoothDaemonConnection::BluetoothDaemonConnection(
|
||||
BluetoothDaemonPDUConsumer* aPDUConsumer,
|
||||
BluetoothDaemonConnectionConsumer* aConsumer,
|
||||
int aIndex)
|
||||
: mPDUConsumer(aPDUConsumer)
|
||||
, mConsumer(aConsumer)
|
||||
, mIndex(aIndex)
|
||||
, mIO(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mConsumer);
|
||||
}
|
||||
|
||||
BluetoothDaemonConnection::~BluetoothDaemonConnection()
|
||||
{ }
|
||||
|
||||
// |ConnectionOrientedSocket|
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonConnection::PrepareAccept(UnixSocketConnector* aConnector,
|
||||
ConnectionOrientedSocketIO*& aIO)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mIO);
|
||||
|
||||
// |BluetoothDaemonConnection| now owns the connector, but doesn't
|
||||
// actually use it. So the connector is stored in an auto pointer
|
||||
// to be deleted at the end of the method.
|
||||
nsAutoPtr<UnixSocketConnector> connector(aConnector);
|
||||
|
||||
SetConnectionStatus(SOCKET_CONNECTING);
|
||||
|
||||
mIO = new BluetoothDaemonConnectionIO(
|
||||
XRE_GetIOMessageLoop(), -1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
|
||||
this, mPDUConsumer);
|
||||
aIO = mIO;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// |DataSocket|
|
||||
|
||||
void
|
||||
BluetoothDaemonConnection::SendSocketData(UnixSocketIOBuffer* aBuffer)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mIO);
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new SocketIOSendTask<BluetoothDaemonConnectionIO,
|
||||
UnixSocketIOBuffer>(mIO, aBuffer));
|
||||
}
|
||||
|
||||
// |SocketBase|
|
||||
|
||||
void
|
||||
BluetoothDaemonConnection::Close()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mIO) {
|
||||
CHROMIUM_LOG("Bluetooth daemon already disconnected!");
|
||||
return;
|
||||
}
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
|
||||
|
||||
mIO = nullptr;
|
||||
|
||||
NotifyDisconnect();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnection::OnConnectSuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mConsumer->OnConnectSuccess(mIndex);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnection::OnConnectError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mConsumer->OnConnectError(mIndex);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonConnection::OnDisconnect()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mConsumer->OnDisconnect(mIndex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_ipc_bluetooth_BluetoothDaemonConnection_h
|
||||
#define mozilla_ipc_bluetooth_BluetoothDaemonConnection_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/ipc/ConnectionOrientedSocket.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class BluetoothDaemonConnectionConsumer;
|
||||
class BluetoothDaemonConnectionIO;
|
||||
class BluetoothDaemonPDUConsumer;
|
||||
|
||||
/*
|
||||
* |BlutoothDaemonPDU| represents a single PDU that is transfered from or to
|
||||
* the Bluetooth daemon. Each PDU contains exactly one command.
|
||||
*
|
||||
* A PDU as the following format
|
||||
*
|
||||
* | 1 | 1 | 2 | n |
|
||||
* | service | opcode | payload length | payload |
|
||||
*
|
||||
* Service and Opcode each require 1 byte, the payload length requires 2
|
||||
* bytes, and the payload requires the number of bytes as stored in the
|
||||
* payload-length field.
|
||||
*
|
||||
* Each service and opcode can have a different payload with individual
|
||||
* length. For the exact details of the Bluetooth protocol, please refer
|
||||
* to
|
||||
*
|
||||
* https://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/hal-ipc-api.txt?id=5.24
|
||||
*
|
||||
*/
|
||||
class BluetoothDaemonPDU final : public UnixSocketIOBuffer
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
OFF_SERVICE = 0,
|
||||
OFF_OPCODE = 1,
|
||||
OFF_LENGTH = 2,
|
||||
OFF_PAYLOAD = 4,
|
||||
HEADER_SIZE = OFF_PAYLOAD,
|
||||
MAX_PAYLOAD_LENGTH = 1 << 16
|
||||
};
|
||||
|
||||
BluetoothDaemonPDU(uint8_t aService, uint8_t aOpcode,
|
||||
uint16_t aPayloadSize);
|
||||
BluetoothDaemonPDU(size_t aPayloadSize);
|
||||
|
||||
void SetConsumer(BluetoothDaemonPDUConsumer* aConsumer)
|
||||
{
|
||||
mConsumer = aConsumer;
|
||||
}
|
||||
|
||||
void SetUserData(void* aUserData)
|
||||
{
|
||||
mUserData = aUserData;
|
||||
}
|
||||
|
||||
void* GetUserData() const
|
||||
{
|
||||
return mUserData;
|
||||
}
|
||||
|
||||
void GetHeader(uint8_t& aService, uint8_t& aOpcode,
|
||||
uint16_t& aPayloadSize);
|
||||
|
||||
ssize_t Send(int aFd) override;
|
||||
ssize_t Receive(int aFd) override;
|
||||
|
||||
int AcquireFd();
|
||||
|
||||
nsresult UpdateHeader();
|
||||
|
||||
private:
|
||||
size_t GetPayloadSize() const;
|
||||
void OnError(const char* aFunction, int aErrno);
|
||||
|
||||
BluetoothDaemonPDUConsumer* mConsumer;
|
||||
void* mUserData;
|
||||
ScopedClose mReceivedFd;
|
||||
};
|
||||
|
||||
/*
|
||||
* |BluetoothDaemonPDUConsumer| processes incoming PDUs from the Bluetooth
|
||||
* daemon. Please note that its method |Handle| runs on a different than the
|
||||
* main thread.
|
||||
*/
|
||||
class BluetoothDaemonPDUConsumer
|
||||
{
|
||||
public:
|
||||
virtual ~BluetoothDaemonPDUConsumer();
|
||||
|
||||
virtual void Handle(BluetoothDaemonPDU& aPDU) = 0;
|
||||
virtual void StoreUserData(const BluetoothDaemonPDU& aPDU) = 0;
|
||||
|
||||
protected:
|
||||
BluetoothDaemonPDUConsumer();
|
||||
};
|
||||
|
||||
/*
|
||||
* |BluetoothDaemonConnection| represents the socket to connect to the
|
||||
* Bluetooth daemon. It offers connection establishment and sending
|
||||
* PDUs. PDU receiving is performed by |BluetoothDaemonPDUConsumer|.
|
||||
*/
|
||||
class BluetoothDaemonConnection : public ConnectionOrientedSocket
|
||||
{
|
||||
public:
|
||||
BluetoothDaemonConnection(BluetoothDaemonPDUConsumer* aPDUConsumer,
|
||||
BluetoothDaemonConnectionConsumer* aConsumer,
|
||||
int aIndex);
|
||||
virtual ~BluetoothDaemonConnection();
|
||||
|
||||
// Methods for |ConnectionOrientedSocket|
|
||||
//
|
||||
|
||||
nsresult PrepareAccept(UnixSocketConnector* aConnector,
|
||||
ConnectionOrientedSocketIO*& aIO) override;
|
||||
|
||||
// Methods for |DataSocket|
|
||||
//
|
||||
|
||||
void SendSocketData(UnixSocketIOBuffer* aBuffer) override;
|
||||
|
||||
// Methods for |SocketBase|
|
||||
//
|
||||
|
||||
void Close() override;
|
||||
void OnConnectSuccess() override;
|
||||
void OnConnectError() override;
|
||||
void OnDisconnect() override;
|
||||
|
||||
private:
|
||||
BluetoothDaemonPDUConsumer* mPDUConsumer;
|
||||
BluetoothDaemonConnectionConsumer* mConsumer;
|
||||
int mIndex;
|
||||
BluetoothDaemonConnectionIO* mIO;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user