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:
2022-03-18 12:44:46 +08:00
parent a06231e9d4
commit 36b2354fd4
148 changed files with 8207 additions and 5397 deletions
+11 -2
View File
@@ -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);
}
+6 -2
View File
@@ -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
+420 -74
View File
@@ -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,
+61 -26
View File
@@ -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
+2
View File
@@ -46,6 +46,8 @@ enum StructuredCloneTags {
SCTAG_DOM_RTC_CERTIFICATE,
SCTAG_DOM_FORMDATA,
SCTAG_DOM_MAX
};
+24 -4
View File
@@ -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"),
+5 -2
View File
@@ -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;
+109 -95
View File
@@ -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);
}
}
+21 -28
View File
@@ -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;
};
+5 -8
View File
@@ -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)
{
+4 -4
View File
@@ -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;
+19 -70
View File
@@ -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;
}
+2 -12
View File
@@ -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;
};
+1
View File
@@ -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]
+141 -2
View File
@@ -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() {
+33
View File
@@ -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');
}
}
+6
View File
@@ -107,6 +107,12 @@ BluetoothGattClientInterface::BluetoothGattClientInterface()
BluetoothGattClientInterface::~BluetoothGattClientInterface()
{ }
BluetoothGattServerInterface::BluetoothGattServerInterface()
{ }
BluetoothGattServerInterface::~BluetoothGattServerInterface()
{ }
BluetoothGattInterface::BluetoothGattInterface()
{ }
+5 -8
View File
@@ -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();
+179
View File
@@ -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
//
+5 -24
View File
@@ -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
-25
View File
@@ -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;
+251 -114
View File
@@ -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));
}
}
+124 -58
View File
@@ -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
+29 -20
View File
@@ -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
+119 -92
View File
@@ -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);
}
+20 -1
View File
@@ -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 {
+44
View File
@@ -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*
+25 -10
View File
@@ -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
+105 -86
View File
@@ -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);
}
+28 -4
View File
@@ -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
+2 -9
View File
@@ -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;
}
+1 -1
View File
@@ -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"
+2 -2
View File
@@ -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
+9
View File
@@ -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();
-1
View File
@@ -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"
+1 -1
View File
@@ -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);
+1 -2
View File
@@ -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,
+8 -7
View File
@@ -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
View File
@@ -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;
+4 -5
View File
@@ -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,
+3 -3
View File
@@ -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
+4 -4
View File
@@ -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,
+2 -2
View File
@@ -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().
+146
View File
@@ -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
+101
View File
@@ -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
-140
View File
@@ -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
-55
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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',
+5 -3
View File
@@ -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;
}
+15 -9
View File
@@ -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;
}
+2 -4
View File
@@ -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,
+2 -1
View File
@@ -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"
+4 -1
View File
@@ -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,
+1
View File
@@ -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"
+1
View File
@@ -20,6 +20,7 @@
#include "nsIPrincipal.h"
#include "nsIPushClient.h"
#include "nsComponentManagerUtils.h"
#include "nsFrameMessageManager.h"
#include "nsContentCID.h"
+1 -1
View File
@@ -64,7 +64,7 @@ private:
nsCOMPtr<nsIWorkerHolder> mWifiWorker;
nsRefPtr<ipc::KeyStore> mKeyStore;
nsRefPtr<mozilla::ipc::KeyStore> mKeyStore;
bool mShutdown;
};
+2
View File
@@ -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;
};
+4 -2
View File
@@ -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)
+15 -18
View File
@@ -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);
+40 -52
View File
@@ -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;
}
}
+1
View File
@@ -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
View File
@@ -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
+2 -16
View File
@@ -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;
+14
View File
@@ -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(),
-63
View File
@@ -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
View File
@@ -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
+2 -5
View File
@@ -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);
};
+1 -1
View File
@@ -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));
-533
View File
@@ -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);
}
}
}
-151
View File
@@ -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