Merge m-c to fx-team. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-09-11 18:25:23 -04:00
commit a0c175fd75
163 changed files with 5912 additions and 5606 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Merge day clobber
Bug 1061489: Updated moz.build requires CLOBBER

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="fe92ddd450e03b38edb2d465de7897971d68ac68">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "d39431f7b119e5cac505e63375ba929ac72eb681",
"revision": "62c1693326443d61bfa405d41d95d05281053cfa",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7c22462206967693ab96b6af1627ba6925f5723f"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e3b9d0d6516177636965d97c63c60981a24a0662"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6cb5e0100d70313e4922c8d34bf20dcdd66ef616"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -293,8 +293,6 @@ public:
static void InitCCCallbacks();
static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
void *aData);
static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
void* aData);
protected:
virtual ~FragmentOrElement();

View File

@ -37,7 +37,6 @@ class nsIContent;
class nsIDocument;
class nsIDOMElement;
class nsIDOMNodeList;
class nsIDOMUserDataHandler;
class nsIEditor;
class nsIFrame;
class nsIMutationObserver;
@ -245,8 +244,7 @@ private:
// Categories of node properties
// 0 is global.
#define DOM_USER_DATA 1
#define DOM_USER_DATA_HANDLER 2
#define SMIL_MAPPED_ATTR_ANIMVAL 3
#define SMIL_MAPPED_ATTR_ANIMVAL 2
// IID for the nsINode interface
#define NS_INODE_IID \
@ -1145,20 +1143,18 @@ protected:
public:
/**
* Associate an object aData to aKey on this node. If aData is null any
* previously registered object and UserDataHandler associated to aKey on
* this node will be removed.
* previously registered object associated to aKey on this node will
* be removed.
* Should only be used to implement the DOM Level 3 UserData API.
*
* @param aKey the key to associate the object to
* @param aData the object to associate to aKey on this node (may be null)
* @param aHandler the UserDataHandler to call when the node is
* cloned/deleted/imported/renamed (may be null)
* @param aResult [out] the previously registered object for aKey on this
* node, if any
* @return whether adding the object and UserDataHandler succeeded
* @return whether adding the object succeeded
*/
nsresult SetUserData(const nsAString& aKey, nsIVariant* aData,
nsIDOMUserDataHandler* aHandler, nsIVariant** aResult);
nsIVariant** aResult);
/**
* Get the UserData object registered for a Key on this node, if any.
@ -1649,7 +1645,6 @@ public:
nsDOMAttributeMap* GetAttributes();
void SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void GetUserData(JSContext* aCx, const nsAString& aKey,
@ -2045,9 +2040,9 @@ ToCanonicalSupports(nsINode* aPointer)
{ \
return nsINode::IsEqualNode(aArg, aResult); \
} \
NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) __VA_ARGS__ \
NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIVariant** aResult) __VA_ARGS__ \
{ \
return nsINode::SetUserData(aKey, aData, aHandler, aResult); \
return nsINode::SetUserData(aKey, aData, aResult); \
} \
NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) __VA_ARGS__ \
{ \

View File

@ -18,7 +18,6 @@
#include "nsDOMString.h"
#include "nsIContentInlines.h"
#include "nsIDocument.h"
#include "nsIDOMUserDataHandler.h"
#include "nsGkAtoms.h"
#include "nsCOMArray.h"
#include "nsNameSpaceManager.h"

View File

@ -93,7 +93,6 @@
#include "nsNodeInfoManager.h"
#include "nsICategoryManager.h"
#include "nsIDOMDocumentType.h"
#include "nsIDOMUserDataHandler.h"
#include "nsGenericHTMLElement.h"
#include "nsIEditor.h"
#include "nsIEditorIMESupport.h"

View File

@ -88,7 +88,6 @@
#include "nsNodeInfoManager.h"
#include "nsICategoryManager.h"
#include "nsIDOMUserDataHandler.h"
#include "nsGenericHTMLElement.h"
#include "nsIEditor.h"
#include "nsIEditorIMESupport.h"
@ -1420,13 +1419,6 @@ FragmentOrElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
xpc_MarkInCCGeneration(static_cast<nsISupports*>(aChild), *gen);
}
void
FragmentOrElement::MarkUserDataHandler(void* aObject, nsIAtom* aKey,
void* aChild, void* aData)
{
xpc_TryUnmarkWrappedGrayObject(static_cast<nsISupports*>(aChild));
}
void
FragmentOrElement::MarkNodeChildren(nsINode* aNode)
{
@ -1445,9 +1437,6 @@ FragmentOrElement::MarkNodeChildren(nsINode* aNode)
ownerDoc->PropertyTable(DOM_USER_DATA)->
Enumerate(aNode, FragmentOrElement::MarkUserData,
&nsCCUncollectableMarker::sGeneration);
ownerDoc->PropertyTable(DOM_USER_DATA_HANDLER)->
Enumerate(aNode, FragmentOrElement::MarkUserDataHandler,
&nsCCUncollectableMarker::sGeneration);
}
}

View File

@ -84,15 +84,6 @@ MarkUserData(void* aNode, nsIAtom* aKey, void* aValue, void* aData)
}
}
static void
MarkUserDataHandler(void* aNode, nsIAtom* aKey, void* aValue, void* aData)
{
nsIDocument* d = static_cast<nsINode*>(aNode)->GetCurrentDoc();
if (d && nsCCUncollectableMarker::InGeneration(d->GetMarkedCCGeneration())) {
Element::MarkUserDataHandler(aNode, aKey, aValue, aData);
}
}
static void
MarkChildMessageManagers(nsIMessageBroadcaster* aMM)
{
@ -208,9 +199,6 @@ MarkContentViewer(nsIContentViewer* aViewer, bool aCleanupJS,
}
static_cast<nsGlobalWindow*>(win.get())->UnmarkGrayTimers();
}
doc->PropertyTable(DOM_USER_DATA_HANDLER)->
EnumerateAll(MarkUserDataHandler, &nsCCUncollectableMarker::sGeneration);
} else if (aPrepareForCC) {
// Unfortunately we need to still mark user data just before running CC so
// that it has the right generation.

View File

@ -108,7 +108,6 @@
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsIDOMUserDataHandler.h"
#include "nsIDOMXULCommandEvent.h"
#include "nsIDragService.h"
#include "nsIEditor.h"

View File

@ -102,7 +102,6 @@
#include "nsBidiUtils.h"
#include "nsIDOMUserDataHandler.h"
#include "nsIDOMXPathNSResolver.h"
#include "nsIParserService.h"
#include "nsContentCreatorFunctions.h"
@ -6381,15 +6380,6 @@ nsIDocument::ImportNode(nsINode& aNode, bool aDeep, ErrorResult& rv) const
if (rv.Failed()) {
return nullptr;
}
nsIDocument *ownerDoc = imported->OwnerDoc();
rv = nsNodeUtils::CallUserDataHandlers(nodesWithProperties, ownerDoc,
nsIDOMUserDataHandler::NODE_IMPORTED,
true);
if (rv.Failed()) {
return nullptr;
}
return newNode.forget();
}
default:
@ -7338,30 +7328,6 @@ BlastSubtreeToPieces(nsINode *aNode)
}
}
class nsUserDataCaller : public nsRunnable
{
public:
nsUserDataCaller(nsCOMArray<nsINode>& aNodesWithProperties,
nsIDocument* aOwnerDoc)
: mNodesWithProperties(aNodesWithProperties),
mOwnerDoc(aOwnerDoc)
{
}
NS_IMETHOD Run()
{
nsNodeUtils::CallUserDataHandlers(mNodesWithProperties, mOwnerDoc,
nsIDOMUserDataHandler::NODE_ADOPTED,
false);
return NS_OK;
}
private:
nsCOMArray<nsINode> mNodesWithProperties;
nsCOMPtr<nsIDocument> mOwnerDoc;
};
NS_IMETHODIMP
nsDocument::AdoptNode(nsIDOMNode *aAdoptedNode, nsIDOMNode **aResult)
{
@ -7546,11 +7512,6 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
}
}
if (nodesWithProperties.Count()) {
nsContentUtils::AddScriptRunner(new nsUserDataCaller(nodesWithProperties,
this));
}
NS_ASSERTION(adoptedNode->OwnerDoc() == this,
"Should still be in the document we just got adopted into");

View File

@ -24,7 +24,6 @@
#include "nsIDOMText.h"
#include "nsCOMPtr.h"
#include "nsDOMString.h"
#include "nsIDOMUserDataHandler.h"
#include "nsChangeHint.h"
#include "nsCOMArray.h"
#include "nsNodeUtils.h"

View File

@ -58,7 +58,6 @@
#include "nsIDOMEventListener.h"
#include "nsIDOMMutationEvent.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMUserDataHandler.h"
#include "nsIEditor.h"
#include "nsIEditorIMESupport.h"
#include "nsILinkHandler.h"
@ -737,8 +736,7 @@ SetUserDataProperty(uint16_t aCategory, nsINode *aNode, nsIAtom *aKey,
}
nsresult
nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData,
nsIDOMUserDataHandler *aHandler, nsIVariant **aResult)
nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData, nsIVariant **aResult)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eGetSetUserData);
*aResult = nullptr;
@ -760,31 +758,13 @@ nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData,
// Take over ownership of the old data from the property table.
nsCOMPtr<nsIVariant> oldData = dont_AddRef(static_cast<nsIVariant*>(data));
if (aData && aHandler) {
nsCOMPtr<nsIDOMUserDataHandler> oldHandler;
rv = SetUserDataProperty(DOM_USER_DATA_HANDLER, this, key, aHandler,
getter_AddRefs(oldHandler));
if (NS_FAILED(rv)) {
// We failed to set the handler, remove the data.
DeleteProperty(DOM_USER_DATA, key);
return rv;
}
}
else {
DeleteProperty(DOM_USER_DATA_HANDLER, key);
}
oldData.swap(*aResult);
return NS_OK;
}
void
nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
@ -795,7 +775,7 @@ nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
}
nsCOMPtr<nsIVariant> oldData;
aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData));
aError = SetUserData(aKey, data, getter_AddRefs(oldData));
if (aError.Failed()) {
return;
}
@ -2714,12 +2694,8 @@ nsINode::WrapObject(JSContext *aCx)
already_AddRefed<nsINode>
nsINode::CloneNode(bool aDeep, ErrorResult& aError)
{
bool callUserDataHandlers = NodeType() != nsIDOMNode::DOCUMENT_NODE ||
!static_cast<nsIDocument*>(this)->CreatingStaticClone();
nsCOMPtr<nsINode> result;
aError = nsNodeUtils::CloneNodeImpl(this, aDeep, callUserDataHandlers,
getter_AddRefs(result));
aError = nsNodeUtils::CloneNodeImpl(this, aDeep, getter_AddRefs(result));
return result.forget();
}

View File

@ -11,7 +11,6 @@
#include "mozilla/dom/Element.h"
#include "nsIMutationObserver.h"
#include "nsIDocument.h"
#include "nsIDOMUserDataHandler.h"
#include "mozilla/EventListenerManager.h"
#include "nsIXPConnect.h"
#include "pldhash.h"
@ -271,85 +270,12 @@ nsNodeUtils::LastRelease(nsINode* aNode)
FragmentOrElement::RemoveBlackMarkedNode(aNode);
}
struct MOZ_STACK_CLASS nsHandlerData
{
uint16_t mOperation;
nsCOMPtr<nsIDOMNode> mSource;
nsCOMPtr<nsIDOMNode> mDest;
};
static void
CallHandler(void *aObject, nsIAtom *aKey, void *aHandler, void *aData)
{
nsHandlerData *handlerData = static_cast<nsHandlerData*>(aData);
nsCOMPtr<nsIDOMUserDataHandler> handler =
static_cast<nsIDOMUserDataHandler*>(aHandler);
nsINode *node = static_cast<nsINode*>(aObject);
nsCOMPtr<nsIVariant> data =
static_cast<nsIVariant*>(node->GetProperty(DOM_USER_DATA, aKey));
NS_ASSERTION(data, "Handler without data?");
nsAutoString key;
aKey->ToString(key);
handler->Handle(handlerData->mOperation, key, data, handlerData->mSource,
handlerData->mDest);
}
/* static */
nsresult
nsNodeUtils::CallUserDataHandlers(nsCOMArray<nsINode> &aNodesWithProperties,
nsIDocument *aOwnerDocument,
uint16_t aOperation, bool aCloned)
{
NS_PRECONDITION(!aCloned || (aNodesWithProperties.Count() % 2 == 0),
"Expected aNodesWithProperties to contain original and "
"cloned nodes.");
if (!nsContentUtils::IsSafeToRunScript()) {
nsContentUtils::WarnScriptWasIgnored(aOwnerDocument);
if (nsContentUtils::IsChromeDoc(aOwnerDocument)) {
NS_WARNING("Fix the caller! Userdata callback disabled.");
} else {
NS_ERROR("This is unsafe! Fix the caller! Userdata callback disabled.");
}
return NS_OK;
}
nsPropertyTable *table = aOwnerDocument->PropertyTable(DOM_USER_DATA_HANDLER);
// Keep the document alive, just in case one of the handlers causes it to go
// away.
nsCOMPtr<nsIDocument> ownerDoc = aOwnerDocument;
nsHandlerData handlerData;
handlerData.mOperation = aOperation;
uint32_t i, count = aNodesWithProperties.Count();
for (i = 0; i < count; ++i) {
nsINode *nodeWithProperties = aNodesWithProperties[i];
nsresult rv;
handlerData.mSource = do_QueryInterface(nodeWithProperties, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (aCloned) {
handlerData.mDest = do_QueryInterface(aNodesWithProperties[++i], &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
table->Enumerate(nodeWithProperties, CallHandler, &handlerData);
}
return NS_OK;
}
static void
NoteUserData(void *aObject, nsIAtom *aKey, void *aXPCOMChild, void *aData)
{
nsCycleCollectionTraversalCallback* cb =
static_cast<nsCycleCollectionTraversalCallback*>(aData);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "[user data (or handler)]");
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "[user data]");
cb->NoteXPCOMChild(static_cast<nsISupports*>(aXPCOMChild));
}
@ -360,14 +286,11 @@ nsNodeUtils::TraverseUserData(nsINode* aNode,
{
nsIDocument* ownerDoc = aNode->OwnerDoc();
ownerDoc->PropertyTable(DOM_USER_DATA)->Enumerate(aNode, NoteUserData, &aCb);
ownerDoc->PropertyTable(DOM_USER_DATA_HANDLER)->Enumerate(aNode, NoteUserData, &aCb);
}
/* static */
nsresult
nsNodeUtils::CloneNodeImpl(nsINode *aNode, bool aDeep,
bool aCallUserDataHandlers,
nsINode **aResult)
nsNodeUtils::CloneNodeImpl(nsINode *aNode, bool aDeep, nsINode **aResult)
{
*aResult = nullptr;
@ -377,14 +300,7 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNode, bool aDeep,
getter_AddRefs(newNode));
NS_ENSURE_SUCCESS(rv, rv);
if (aCallUserDataHandlers) {
rv = CallUserDataHandlers(nodesWithProperties, aNode->OwnerDoc(),
nsIDOMUserDataHandler::NODE_CLONED, true);
NS_ENSURE_SUCCESS(rv, rv);
}
newNode.swap(*aResult);
return NS_OK;
}
@ -548,11 +464,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
}
}
// XXX If there are any attribute nodes on this element with UserDataHandlers
// we should technically adopt/clone/import such attribute nodes and notify
// those handlers. However we currently don't have code to do so without
// also notifying when it's not safe so we're not doing that at this time.
if (aDeep && (!aClone || !aNode->IsNodeOfType(nsINode::eATTRIBUTE))) {
// aNode's children.
for (nsIContent* cloneChild = aNode->GetFirstChild();
@ -634,7 +545,6 @@ nsNodeUtils::UnlinkUserData(nsINode *aNode)
// delete the document.
nsCOMPtr<nsIDocument> document = aNode->OwnerDoc();
document->PropertyTable(DOM_USER_DATA)->DeleteAllPropertiesFor(aNode);
document->PropertyTable(DOM_USER_DATA_HANDLER)->DeleteAllPropertiesFor(aNode);
}
bool

View File

@ -14,7 +14,6 @@
struct CharacterDataChangeInfo;
class nsIVariant;
class nsIDOMNode;
class nsIDOMUserDataHandler;
template<class E> class nsCOMArray;
class nsCycleCollectionTraversalCallback;
@ -198,29 +197,9 @@ public:
}
/**
* Call registered userdata handlers for operation aOperation for the nodes in
* aNodesWithProperties. If aCloned is true aNodesWithProperties should
* contain both the original and the cloned nodes (and only the userdata
* handlers registered for the original nodes will be called).
* Helper for the cycle collector to traverse the DOM UserData for aNode.
*
* @param aNodesWithProperties Contains the nodes that might have properties
* registered on them. If aCloned is true every
* one of those nodes should be immediately
* followed in the array by the cloned node.
* @param aOwnerDocument The ownerDocument of the original nodes.
* @param aOperation The operation to call a userdata handler for.
* @param aCloned If true aNodesWithProperties will contain both original
* and cloned nodes.
*/
static nsresult CallUserDataHandlers(nsCOMArray<nsINode> &aNodesWithProperties,
nsIDocument *aOwnerDocument,
uint16_t aOperation, bool aCloned);
/**
* Helper for the cycle collector to traverse the DOM UserData and
* UserDataHandlers for aNode.
*
* @param aNode the node to traverse UserData and UserDataHandlers for
* @param aNode the node to traverse UserData for
* @param aCb the cycle collection callback
*/
static void TraverseUserData(nsINode* aNode,
@ -232,17 +211,14 @@ public:
*
* @param aNode the node to clone
* @param aDeep if true all descendants will be cloned too
* @param aCallUserDataHandlers if true, user data handlers will be called
* @param aResult the clone
*/
static nsresult CloneNodeImpl(nsINode *aNode, bool aDeep,
bool aCallUserDataHandlers,
nsINode **aResult);
static nsresult CloneNodeImpl(nsINode *aNode, bool aDeep, nsINode **aResult);
/**
* Release the UserData and UserDataHandlers for aNode.
* Release the UserData for aNode.
*
* @param aNode the node to release the UserData and UserDataHandlers for
* @param aNode the node to release the UserData for
*/
static void UnlinkUserData(nsINode *aNode);

View File

@ -60,7 +60,6 @@
// DOM core includes
#include "nsError.h"
#include "nsIDOMUserDataHandler.h"
#include "nsIDOMXULButtonElement.h"
#include "nsIDOMXULCheckboxElement.h"
#include "nsIDOMXULPopupElement.h"
@ -179,7 +178,6 @@ DOMCI_DATA_NO_CLASS(ChromeMessageSender)
DOMCI_DATA_NO_CLASS(DOMPrototype)
DOMCI_DATA_NO_CLASS(DOMConstructor)
DOMCI_DATA_NO_CLASS(UserDataHandler)
DOMCI_DATA_NO_CLASS(XULControlElement)
DOMCI_DATA_NO_CLASS(XULLabeledControlElement)
DOMCI_DATA_NO_CLASS(XULButtonElement)
@ -336,8 +334,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(UserDataHandler, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULLabeledControlElement, nsDOMGenericSH,
@ -865,10 +861,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(UserDataHandler, nsIDOMUserDataHandler)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMUserDataHandler)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControlElement, nsIDOMXULControlElement)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULControlElement)
DOM_CLASSINFO_MAP_END

View File

@ -67,7 +67,6 @@ DOMCI_CLASS(CSSPageRule)
DOMCI_CLASS(CSSFontFeatureValuesRule)
DOMCI_CLASS(UserDataHandler)
DOMCI_CLASS(XULControlElement)
DOMCI_CLASS(XULLabeledControlElement)
DOMCI_CLASS(XULButtonElement)

View File

@ -28,7 +28,6 @@
#include "nsCycleCollector.h"
#include "nsIXPConnect.h"
#include "nsJSUtils.h"
#include "MainThreadUtils.h"
#include "nsISupportsImpl.h"
#include "qsObjectHelper.h"
#include "xpcpublic.h"

View File

@ -1790,6 +1790,5 @@ addExternalIface('StackFrame', nativeType='nsIStackFrame',
headerFile='nsIException.h', notflattened=True)
addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
notflattened=True)
addExternalIface('UserDataHandler')
addExternalIface('XPathNSResolver')
addExternalIface('XULCommandDispatcher')

View File

@ -0,0 +1,109 @@
/* -*- 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 "BluetoothInterface.h"
#ifdef MOZ_B2G_BT_BLUEDROID
#include "BluetoothHALInterface.h"
#endif
BEGIN_BLUETOOTH_NAMESPACE
//
// Socket Interface
//
BluetoothSocketInterface::~BluetoothSocketInterface()
{ }
//
// Handsfree Interface
//
// Notification handling
//
BluetoothHandsfreeNotificationHandler::
~BluetoothHandsfreeNotificationHandler()
{ }
// Interface
//
BluetoothHandsfreeInterface::BluetoothHandsfreeInterface()
{ }
BluetoothHandsfreeInterface::~BluetoothHandsfreeInterface()
{ }
//
// Bluetooth Advanced Audio Interface
//
// Notification handling
//
BluetoothA2dpNotificationHandler::~BluetoothA2dpNotificationHandler()
{ }
// Interface
//
BluetoothA2dpInterface::BluetoothA2dpInterface()
{ }
BluetoothA2dpInterface::~BluetoothA2dpInterface()
{ }
//
// Bluetooth AVRCP Interface
//
// Notification handling
//
BluetoothAvrcpNotificationHandler::~BluetoothAvrcpNotificationHandler()
{ }
// Interface
//
BluetoothAvrcpInterface::BluetoothAvrcpInterface()
{ }
BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
{ }
// Notification handling
//
BluetoothNotificationHandler::~BluetoothNotificationHandler()
{ }
// Interface
//
BluetoothInterface*
BluetoothInterface::GetInstance()
{
/* Here's where we decide which implementation to use. Currently
* there is only Bluedroid, but others are possible. Having multiple
* interfaces built-in and selecting the correct one at runtime could
* also be an option.
*/
#ifdef MOZ_B2G_BT_BLUEDROID
return BluetoothHALInterface::GetInstance();
#else
return nullptr;
#endif
}
BluetoothInterface::BluetoothInterface()
{ }
BluetoothInterface::~BluetoothInterface()
{ }
END_BLUETOOTH_NAMESPACE

View File

@ -4,23 +4,14 @@
* 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_bluetooth_bluedroid_bluetoothinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothinterface_h__
#ifndef mozilla_dom_bluetooth_bluetoothinterface_h__
#define mozilla_dom_bluetooth_bluetoothinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include <hardware/bt_hf.h>
#include <hardware/bt_av.h>
#if ANDROID_VERSION >= 18
#include <hardware/bt_rc.h>
#endif
#include "BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothInterface;
//
// Socket Interface
//
@ -47,30 +38,24 @@ public:
class BluetoothSocketInterface
{
public:
friend class BluetoothInterface;
// Init and Cleanup is handled by BluetoothInterface
void Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes);
virtual void Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes) = 0;
void Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes);
virtual void Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes) = 0;
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
protected:
BluetoothSocketInterface(const btsock_interface_t* aInterface);
~BluetoothSocketInterface();
private:
const btsock_interface_t* mInterface;
virtual ~BluetoothSocketInterface();
};
//
@ -191,74 +176,70 @@ public:
class BluetoothHandsfreeInterface
{
public:
friend class BluetoothInterface;
void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler,
BluetoothHandsfreeResultHandler* aRes);
void Cleanup(BluetoothHandsfreeResultHandler* aRes);
virtual void Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0;
/* Connect / Disconnect */
void Connect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void ConnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void DisconnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
virtual void Connect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void Disconnect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void ConnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void DisconnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes) = 0;
/* Voice Recognition */
void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
virtual void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes) = 0;
/* Volume */
void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes);
virtual void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes) = 0;
/* Device status */
void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType,
int aSignal, int aBattChg,
BluetoothHandsfreeResultHandler* aRes);
virtual void DeviceStatusNotification(
BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType,
int aSignal, int aBattChg, BluetoothHandsfreeResultHandler* aRes) = 0;
/* Responses */
void CopsResponse(const char* aCops,
BluetoothHandsfreeResultHandler* aRes);
void CindResponse(int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, int aSignal,
int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes);
void FormattedAtResponse(const char* aRsp,
BluetoothHandsfreeResultHandler* aRes);
void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes);
void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes);
virtual void CopsResponse(const char* aCops,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void CindResponse(int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
int aSignal, int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void FormattedAtResponse(const char* aRsp,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes) = 0;
/* Phone State */
void PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes);
virtual void PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes) = 0;
protected:
BluetoothHandsfreeInterface(const bthf_interface_t* aInterface);
~BluetoothHandsfreeInterface();
private:
const bthf_interface_t* mInterface;
BluetoothHandsfreeInterface();
virtual ~BluetoothHandsfreeInterface();
};
//
@ -306,23 +287,18 @@ public:
class BluetoothA2dpInterface
{
public:
friend class BluetoothInterface;
virtual void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothA2dpResultHandler* aRes) = 0;
void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes);
void Cleanup(BluetoothA2dpResultHandler* aRes);
void Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
virtual void Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes) = 0;
virtual void Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes) = 0;
protected:
BluetoothA2dpInterface(const btav_interface_t* aInterface);
~BluetoothA2dpInterface();
private:
const btav_interface_t* mInterface;
BluetoothA2dpInterface();
virtual ~BluetoothA2dpInterface();
};
//
@ -428,61 +404,50 @@ public:
class BluetoothAvrcpInterface
{
public:
friend class BluetoothInterface;
virtual void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothAvrcpResultHandler* aRes) = 0;
void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes);
void Cleanup(BluetoothAvrcpResultHandler* aRes);
virtual void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes) = 0;
void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes);
void ListPlayerAppAttrRsp(int aNumAttr,
const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes);
void ListPlayerAppValueRsp(int aNumVal, uint8_t* aPVals,
BluetoothAvrcpResultHandler* aRes);
virtual void ListPlayerAppAttrRsp(
int aNumAttr, const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes) = 0;
virtual void ListPlayerAppValueRsp(int aNumVal, uint8_t* aPVals,
BluetoothAvrcpResultHandler* aRes) = 0;
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueRsp(uint8_t aNumAttrs,
const uint8_t* aIds, const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes);
virtual void GetPlayerAppValueRsp(uint8_t aNumAttrs, const uint8_t* aIds,
const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes) = 0;
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppAttrTextRsp(int aNumAttr,
const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes);
virtual void GetPlayerAppAttrTextRsp(int aNumAttr, const uint8_t* aIds,
const char** aTexts,
BluetoothAvrcpResultHandler* aRes) = 0;
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueTextRsp(int aNumVal,
const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes);
virtual void GetPlayerAppValueTextRsp(int aNumVal, const uint8_t* aIds,
const char** aTexts,
BluetoothAvrcpResultHandler* aRes) = 0;
void GetElementAttrRsp(uint8_t aNumAttr,
const BluetoothAvrcpElementAttribute* aAttr,
BluetoothAvrcpResultHandler* aRes);
virtual void GetElementAttrRsp(uint8_t aNumAttr,
const BluetoothAvrcpElementAttribute* aAttr,
BluetoothAvrcpResultHandler* aRes) = 0;
void SetPlayerAppValueRsp(BluetoothAvrcpStatus aRspStatus,
BluetoothAvrcpResultHandler* aRes);
virtual void SetPlayerAppValueRsp(BluetoothAvrcpStatus aRspStatus,
BluetoothAvrcpResultHandler* aRes) = 0;
void RegisterNotificationRsp(BluetoothAvrcpEvent aEvent,
BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes);
virtual void RegisterNotificationRsp(
BluetoothAvrcpEvent aEvent, BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes) = 0;
void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes);
virtual void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes) = 0;
protected:
BluetoothAvrcpInterface(
#if ANDROID_VERSION >= 18
const btrc_interface_t* aInterface
#endif
);
~BluetoothAvrcpInterface();
private:
#if ANDROID_VERSION >= 18
const btrc_interface_t* mInterface;
#endif
BluetoothAvrcpInterface();
virtual ~BluetoothAvrcpInterface();
};
//
@ -582,92 +547,86 @@ class BluetoothInterface
public:
static BluetoothInterface* GetInstance();
void Init(BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes);
void Cleanup(BluetoothResultHandler* aRes);
void Enable(BluetoothResultHandler* aRes);
void Disable(BluetoothResultHandler* aRes);
virtual void Init(BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothResultHandler* aRes) = 0;
virtual void Enable(BluetoothResultHandler* aRes) = 0;
virtual void Disable(BluetoothResultHandler* aRes) = 0;
/* Adapter Properties */
void GetAdapterProperties(BluetoothResultHandler* aRes);
void GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes);
void SetAdapterProperty(const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes);
virtual void GetAdapterProperties(BluetoothResultHandler* aRes) = 0;
virtual void GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes) = 0;
virtual void SetAdapterProperty(const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes) = 0;
/* Remote Device Properties */
void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes);
void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const nsAString& aName,
BluetoothResultHandler* aRes);
void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes);
virtual void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes) = 0;
virtual void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const nsAString& aName,
BluetoothResultHandler* aRes) = 0;
virtual void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes) = 0;
/* Remote Services */
void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16],
BluetoothResultHandler* aRes);
void GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes);
virtual void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16],
BluetoothResultHandler* aRes) = 0;
virtual void GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes) = 0;
/* Discovery */
void StartDiscovery(BluetoothResultHandler* aRes);
void CancelDiscovery(BluetoothResultHandler* aRes);
virtual void StartDiscovery(BluetoothResultHandler* aRes) = 0;
virtual void CancelDiscovery(BluetoothResultHandler* aRes) = 0;
/* Bonds */
void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
virtual void CreateBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes) = 0;
virtual void RemoveBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes) = 0;
virtual void CancelBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes) = 0;
/* Authentication */
void PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode,
BluetoothResultHandler* aRes);
virtual void PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode,
BluetoothResultHandler* aRes) = 0;
void SspReply(const nsAString& aBdAddr, const nsAString& aVariant,
bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes);
virtual void SspReply(const nsAString& aBdAddr, const nsAString& aVariant,
bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes) = 0;
/* DUT Mode */
void DutModeConfigure(bool aEnable, BluetoothResultHandler* aRes);
void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes);
virtual void DutModeConfigure(bool aEnable,
BluetoothResultHandler* aRes) = 0;
virtual void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes) = 0;
/* LE Mode */
void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes);
virtual void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes) = 0;
/* Profile Interfaces */
BluetoothSocketInterface* GetBluetoothSocketInterface();
BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface();
BluetoothA2dpInterface* GetBluetoothA2dpInterface();
BluetoothAvrcpInterface* GetBluetoothAvrcpInterface();
virtual BluetoothSocketInterface* GetBluetoothSocketInterface() = 0;
virtual BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface() = 0;
virtual BluetoothA2dpInterface* GetBluetoothA2dpInterface() = 0;
virtual BluetoothAvrcpInterface* GetBluetoothAvrcpInterface() = 0;
protected:
BluetoothInterface(const bt_interface_t* aInterface);
~BluetoothInterface();
private:
template <class T>
T* CreateProfileInterface();
template <class T>
T* GetProfileInterface();
const bt_interface_t* mInterface;
BluetoothInterface();
virtual ~BluetoothInterface();
};
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,184 @@
/* -*- 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 "BluetoothA2dpHALInterface.h"
#include "BluetoothHALHelpers.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable0<BluetoothA2dpResultHandler, void>
BluetoothA2dpHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothA2dpResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothA2dpHALErrorRunnable;
static nsresult
DispatchBluetoothA2dpHALResult(
BluetoothA2dpResultHandler* aRes,
void (BluetoothA2dpResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothA2dpHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothA2dpHALErrorRunnable(aRes,
&BluetoothA2dpResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothA2dpNotificationHandler* sA2dpNotificationHandler;
struct BluetoothA2dpHALCallback
{
class A2dpNotificationHandlerWrapper
{
public:
typedef BluetoothA2dpNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sA2dpNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable2<
A2dpNotificationHandlerWrapper, void,
BluetoothA2dpConnectionState, nsString,
BluetoothA2dpConnectionState, const nsAString&>
ConnectionStateNotification;
typedef BluetoothNotificationHALRunnable2<
A2dpNotificationHandlerWrapper, void,
BluetoothA2dpAudioState, nsString,
BluetoothA2dpAudioState, const nsAString&>
AudioStateNotification;
// Bluedroid A2DP callbacks
static void
ConnectionState(btav_connection_state_t aState, bt_bdaddr_t* aBdAddr)
{
ConnectionStateNotification::Dispatch(
&BluetoothA2dpNotificationHandler::ConnectionStateNotification,
aState, aBdAddr);
}
static void
AudioState(btav_audio_state_t aState, bt_bdaddr_t* aBdAddr)
{
AudioStateNotification::Dispatch(
&BluetoothA2dpNotificationHandler::AudioStateNotification,
aState, aBdAddr);
}
};
// Interface
//
BluetoothA2dpHALInterface::BluetoothA2dpHALInterface(
const btav_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothA2dpHALInterface::~BluetoothA2dpHALInterface()
{ }
void
BluetoothA2dpHALInterface::Init(
BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes)
{
static btav_callbacks_t sCallbacks = {
sizeof(sCallbacks),
BluetoothA2dpHALCallback::ConnectionState,
BluetoothA2dpHALCallback::AudioState
};
sA2dpNotificationHandler = aNotificationHandler;
bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothA2dpHALResult(aRes,
&BluetoothA2dpResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothA2dpHALInterface::Cleanup(BluetoothA2dpResultHandler* aRes)
{
mInterface->cleanup();
if (aRes) {
DispatchBluetoothA2dpHALResult(aRes,
&BluetoothA2dpResultHandler::Cleanup,
STATUS_SUCCESS);
}
}
void
BluetoothA2dpHALInterface::Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->connect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothA2dpHALResult(
aRes, &BluetoothA2dpResultHandler::Connect,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothA2dpHALInterface::Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->disconnect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothA2dpHALResult(
aRes, &BluetoothA2dpResultHandler::Disconnect,
ConvertDefault(status, STATUS_FAIL));
}
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,44 @@
/* -*- 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_dom_bluetooth_bluedroid_bluetootha2dphalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetootha2dphalinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_av.h>
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothA2dpHALInterface MOZ_FINAL
: public BluetoothA2dpInterface
{
public:
friend class BluetoothHALInterface;
void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes);
void Cleanup(BluetoothA2dpResultHandler* aRes);
void Connect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothA2dpResultHandler* aRes);
protected:
BluetoothA2dpHALInterface(const btav_interface_t* aInterface);
~BluetoothA2dpHALInterface();
private:
const btav_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -0,0 +1,593 @@
/* -*- 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 "BluetoothAvrcpHALInterface.h"
#include "BluetoothHALHelpers.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable0<BluetoothAvrcpResultHandler, void>
BluetoothAvrcpHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothAvrcpResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothAvrcpHALErrorRunnable;
static nsresult
DispatchBluetoothAvrcpHALResult(
BluetoothAvrcpResultHandler* aRes,
void (BluetoothAvrcpResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothAvrcpHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothAvrcpHALErrorRunnable(aRes,
&BluetoothAvrcpResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothAvrcpNotificationHandler* sAvrcpNotificationHandler;
struct BluetoothAvrcpCallback
{
class AvrcpNotificationHandlerWrapper
{
public:
typedef BluetoothAvrcpNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sAvrcpNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable0<AvrcpNotificationHandlerWrapper,
void>
GetPlayStatusNotification;
typedef BluetoothNotificationHALRunnable0<AvrcpNotificationHandlerWrapper,
void>
ListPlayerAppAttrNotification;
typedef BluetoothNotificationHALRunnable1<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpPlayerAttribute>
ListPlayerAppValuesNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
uint8_t, const BluetoothAvrcpPlayerAttribute*>
GetPlayerAppValueNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpPlayerAttribute>,
uint8_t, const BluetoothAvrcpPlayerAttribute*>
GetPlayerAppAttrsTextNotification;
typedef BluetoothNotificationHALRunnable3<AvrcpNotificationHandlerWrapper,
void,
uint8_t, uint8_t,
nsAutoArrayPtr<uint8_t>,
uint8_t, uint8_t, const uint8_t*>
GetPlayerAppValuesTextNotification;
typedef BluetoothNotificationHALRunnable1<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpPlayerSettings,
const BluetoothAvrcpPlayerSettings&>
SetPlayerAppValueNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper, void,
uint8_t, nsAutoArrayPtr<BluetoothAvrcpMediaAttribute>,
uint8_t, const BluetoothAvrcpMediaAttribute*>
GetElementAttrNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
BluetoothAvrcpEvent, uint32_t>
RegisterNotificationNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
nsString, unsigned long,
const nsAString&>
RemoteFeatureNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
uint8_t, uint8_t>
VolumeChangeNotification;
typedef BluetoothNotificationHALRunnable2<AvrcpNotificationHandlerWrapper,
void,
int, int>
PassthroughCmdNotification;
// Bluedroid AVRCP callbacks
#if ANDROID_VERSION >= 18
static void
GetPlayStatus()
{
GetPlayStatusNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayStatusNotification);
}
static void
ListPlayerAppAttr()
{
ListPlayerAppAttrNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::ListPlayerAppAttrNotification);
}
static void
ListPlayerAppValues(btrc_player_attr_t aAttrId)
{
ListPlayerAppValuesNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::ListPlayerAppValuesNotification,
aAttrId);
}
static void
GetPlayerAppValue(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
{
GetPlayerAppValueNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppValueNotification,
aNumAttrs, ConvertArray<btrc_player_attr_t>(aAttrs, aNumAttrs));
}
static void
GetPlayerAppAttrsText(uint8_t aNumAttrs, btrc_player_attr_t* aAttrs)
{
GetPlayerAppAttrsTextNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppAttrsTextNotification,
aNumAttrs, ConvertArray<btrc_player_attr_t>(aAttrs, aNumAttrs));
}
static void
GetPlayerAppValuesText(uint8_t aAttrId, uint8_t aNumVals, uint8_t* aVals)
{
GetPlayerAppValuesTextNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetPlayerAppValuesTextNotification,
aAttrId, aNumVals, ConvertArray<uint8_t>(aVals, aNumVals));
}
static void
SetPlayerAppValue(btrc_player_settings_t* aVals)
{
SetPlayerAppValueNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::SetPlayerAppValueNotification,
*aVals);
}
static void
GetElementAttr(uint8_t aNumAttrs, btrc_media_attr_t* aAttrs)
{
GetElementAttrNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::GetElementAttrNotification,
aNumAttrs, ConvertArray<btrc_media_attr_t>(aAttrs, aNumAttrs));
}
static void
RegisterNotification(btrc_event_id_t aEvent, uint32_t aParam)
{
RegisterNotificationNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::RegisterNotificationNotification,
aEvent, aParam);
}
#endif // ANDROID_VERSION >= 18
#if ANDROID_VERSION >= 19
static void
RemoteFeature(bt_bdaddr_t* aBdAddr, btrc_remote_features_t aFeatures)
{
RemoteFeatureNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::RemoteFeatureNotification,
aBdAddr, aFeatures);
}
static void
VolumeChange(uint8_t aVolume, uint8_t aCType)
{
VolumeChangeNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::VolumeChangeNotification,
aVolume, aCType);
}
static void
PassthroughCmd(int aId, int aKeyState)
{
PassthroughCmdNotification::Dispatch(
&BluetoothAvrcpNotificationHandler::PassthroughCmdNotification,
aId, aKeyState);
}
#endif // ANDROID_VERSION >= 19
};
// Interface
//
BluetoothAvrcpHALInterface::BluetoothAvrcpHALInterface(
#if ANDROID_VERSION >= 18
const btrc_interface_t* aInterface
#endif
)
#if ANDROID_VERSION >= 18
: mInterface(aInterface)
#endif
{
#if ANDROID_VERSION >= 18
MOZ_ASSERT(mInterface);
#endif
}
BluetoothAvrcpHALInterface::~BluetoothAvrcpHALInterface()
{ }
void
BluetoothAvrcpHALInterface::Init(
BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
static btrc_callbacks_t sCallbacks = {
sizeof(sCallbacks),
#if ANDROID_VERSION >= 19
BluetoothAvrcpCallback::RemoteFeature,
#endif
BluetoothAvrcpCallback::GetPlayStatus,
BluetoothAvrcpCallback::ListPlayerAppAttr,
BluetoothAvrcpCallback::ListPlayerAppValues,
BluetoothAvrcpCallback::GetPlayerAppValue,
BluetoothAvrcpCallback::GetPlayerAppAttrsText,
BluetoothAvrcpCallback::GetPlayerAppValuesText,
BluetoothAvrcpCallback::SetPlayerAppValue,
BluetoothAvrcpCallback::GetElementAttr,
BluetoothAvrcpCallback::RegisterNotification
#if ANDROID_VERSION >= 19
,
BluetoothAvrcpCallback::VolumeChange,
BluetoothAvrcpCallback::PassthroughCmd
#endif
};
#endif // ANDROID_VERSION >= 18
sAvrcpNotificationHandler = aNotificationHandler;
#if ANDROID_VERSION >= 18
bt_status_t status = mInterface->init(&sCallbacks);
#else
bt_status_t status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(aRes, &BluetoothAvrcpResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::Cleanup(BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
mInterface->cleanup();
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(aRes,
&BluetoothAvrcpResultHandler::Cleanup, STATUS_SUCCESS);
}
}
void
BluetoothAvrcpHALInterface::GetPlayStatusRsp(
ControlPlayStatus aPlayStatus, uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_play_status_t playStatus = BTRC_PLAYSTATE_STOPPED;
if (!(NS_FAILED(Convert(aPlayStatus, playStatus)))) {
status = mInterface->get_play_status_rsp(playStatus, aSongLen, aSongPos);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayStatusRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::ListPlayerAppAttrRsp(
int aNumAttr, const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
ConvertArray<BluetoothAvrcpPlayerAttribute> pAttrsArray(aPAttrs, aNumAttr);
nsAutoArrayPtr<btrc_player_attr_t> pAttrs;
if (NS_SUCCEEDED(Convert(pAttrsArray, pAttrs))) {
status = mInterface->list_player_app_attr_rsp(aNumAttr, pAttrs);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::ListPlayerAppAttrRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::ListPlayerAppValueRsp(
int aNumVal, uint8_t* aPVals, BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
bt_status_t status = mInterface->list_player_app_value_rsp(aNumVal, aPVals);
#else
bt_status_t status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::ListPlayerAppValueRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetPlayerAppValueRsp(
uint8_t aNumAttrs, const uint8_t* aIds, const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_settings_t pVals;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any player app values currently */) {
status = mInterface->get_player_app_value_rsp(&pVals);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppValueRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetPlayerAppAttrTextRsp(
int aNumAttr, const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_setting_text_t* aPAttrs;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any attributes currently */) {
status = mInterface->get_player_app_attr_text_rsp(aNumAttr, aPAttrs);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppAttrTextRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetPlayerAppValueTextRsp(
int aNumVal, const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_player_setting_text_t* pVals;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any values currently */) {
status = mInterface->get_player_app_value_text_rsp(aNumVal, pVals);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetPlayerAppValueTextRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::GetElementAttrRsp(
uint8_t aNumAttr, const BluetoothAvrcpElementAttribute* aAttrs,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
ConvertArray<BluetoothAvrcpElementAttribute> pAttrsArray(aAttrs, aNumAttr);
nsAutoArrayPtr<btrc_element_attr_val_t> pAttrs;
if (NS_SUCCEEDED(Convert(pAttrsArray, pAttrs))) {
status = mInterface->get_element_attr_rsp(aNumAttr, pAttrs);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::GetElementAttrRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::SetPlayerAppValueRsp(
BluetoothAvrcpStatus aRspStatus, BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
btrc_status_t rspStatus = BTRC_STS_BAD_CMD; // silences compiler warning
if (NS_SUCCEEDED(Convert(aRspStatus, rspStatus))) {
status = mInterface->set_player_app_value_rsp(rspStatus);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::SetPlayerAppValueRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::RegisterNotificationRsp(
BluetoothAvrcpEvent aEvent, BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes)
{
bt_status_t status;
#if ANDROID_VERSION >= 18
nsresult rv;
btrc_event_id_t event = { };
btrc_notification_type_t type = BTRC_NOTIFICATION_TYPE_INTERIM;
btrc_register_notification_t param;
switch (aEvent) {
case AVRCP_EVENT_PLAY_STATUS_CHANGED:
rv = Convert(aParam.mPlayStatus, param.play_status);
break;
case AVRCP_EVENT_TRACK_CHANGE:
MOZ_ASSERT(sizeof(aParam.mTrack) == sizeof(param.track));
memcpy(param.track, aParam.mTrack, sizeof(param.track));
rv = NS_OK;
break;
case AVRCP_EVENT_TRACK_REACHED_END:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
case AVRCP_EVENT_TRACK_REACHED_START:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
case AVRCP_EVENT_PLAY_POS_CHANGED:
param.song_pos = aParam.mSongPos;
rv = NS_OK;
break;
case AVRCP_EVENT_APP_SETTINGS_CHANGED:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
default:
NS_NOTREACHED("Unknown conversion");
rv = NS_ERROR_ILLEGAL_VALUE;
break;
}
if (NS_SUCCEEDED(rv) &&
NS_SUCCEEDED(Convert(aEvent, event)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->register_notification_rsp(event, type, &param);
} else {
status = BT_STATUS_PARM_INVALID;
}
#else
status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::RegisterNotificationRsp,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothAvrcpHALInterface::SetVolume(uint8_t aVolume,
BluetoothAvrcpResultHandler* aRes)
{
#if ANDROID_VERSION >= 19
bt_status_t status = mInterface->set_volume(aVolume);
#else
bt_status_t status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothAvrcpHALResult(
aRes, &BluetoothAvrcpResultHandler::SetVolume,
ConvertDefault(status, STATUS_FAIL));
}
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,84 @@
/* -*- 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_dom_bluetooth_bluedroid_bluetoothavrcphalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothavrcphalinterface_h__
#include <hardware/bluetooth.h>
#if ANDROID_VERSION >= 18
#include <hardware/bt_rc.h>
#endif
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothAvrcpHALInterface MOZ_FINAL
: public BluetoothAvrcpInterface
{
public:
friend class BluetoothHALInterface;
void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes);
void Cleanup(BluetoothAvrcpResultHandler* aRes);
void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos,
BluetoothAvrcpResultHandler* aRes);
void ListPlayerAppAttrRsp(int aNumAttr,
const BluetoothAvrcpPlayerAttribute* aPAttrs,
BluetoothAvrcpResultHandler* aRes);
void ListPlayerAppValueRsp(int aNumVal, uint8_t* aPVals,
BluetoothAvrcpResultHandler* aRes);
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueRsp(uint8_t aNumAttrs,
const uint8_t* aIds, const uint8_t* aValues,
BluetoothAvrcpResultHandler* aRes);
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppAttrTextRsp(int aNumAttr,
const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes);
/* TODO: redesign this interface once we actually use it */
void GetPlayerAppValueTextRsp(int aNumVal,
const uint8_t* aIds, const char** aTexts,
BluetoothAvrcpResultHandler* aRes);
void GetElementAttrRsp(uint8_t aNumAttr,
const BluetoothAvrcpElementAttribute* aAttr,
BluetoothAvrcpResultHandler* aRes);
void SetPlayerAppValueRsp(BluetoothAvrcpStatus aRspStatus,
BluetoothAvrcpResultHandler* aRes);
void RegisterNotificationRsp(BluetoothAvrcpEvent aEvent,
BluetoothAvrcpNotification aType,
const BluetoothAvrcpNotificationParam& aParam,
BluetoothAvrcpResultHandler* aRes);
void SetVolume(uint8_t aVolume, BluetoothAvrcpResultHandler* aRes);
protected:
BluetoothAvrcpHALInterface(
#if ANDROID_VERSION >= 18
const btrc_interface_t* aInterface
#endif
);
~BluetoothAvrcpHALInterface();
private:
#if ANDROID_VERSION >= 18
const btrc_interface_t* mInterface;
#endif
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -0,0 +1,298 @@
/* -*- 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 "BluetoothHALHelpers.h"
#define MAX_UUID_SIZE 16
BEGIN_BLUETOOTH_NAMESPACE
//
// Conversion
//
nsresult
Convert(const nsAString& aIn, bt_property_type_t& aOut)
{
if (aIn.EqualsLiteral("Name")) {
aOut = BT_PROPERTY_BDNAME;
} else if (aIn.EqualsLiteral("Discoverable")) {
aOut = BT_PROPERTY_ADAPTER_SCAN_MODE;
} else if (aIn.EqualsLiteral("DiscoverableTimeout")) {
aOut = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT;
} else {
BT_LOGR("Invalid property name: %s", NS_ConvertUTF16toUTF8(aIn).get());
return NS_ERROR_ILLEGAL_VALUE;
}
return NS_OK;
}
nsresult
Convert(ConvertNamedValue& aIn, bt_property_t& aOut)
{
nsresult rv = Convert(aIn.mNamedValue.name(), aOut.type);
if (NS_FAILED(rv)) {
return rv;
}
if (aIn.mNamedValue.value().type() == BluetoothValue::Tuint32_t) {
// Set discoverable timeout
aOut.val =
reinterpret_cast<void*>(aIn.mNamedValue.value().get_uint32_t());
} else if (aIn.mNamedValue.value().type() == BluetoothValue::TnsString) {
// Set name
aIn.mStringValue =
NS_ConvertUTF16toUTF8(aIn.mNamedValue.value().get_nsString());
aOut.val =
const_cast<void*>(static_cast<const void*>(aIn.mStringValue.get()));
aOut.len = strlen(static_cast<char*>(aOut.val));
} else if (aIn.mNamedValue.value().type() == BluetoothValue::Tbool) {
// Set scan mode
rv = Convert(aIn.mNamedValue.value().get_bool(), aIn.mScanMode);
if (NS_FAILED(rv)) {
return rv;
}
aOut.val = &aIn.mScanMode;
aOut.len = sizeof(aIn.mScanMode);
} else {
BT_LOGR("Invalid property value type");
return NS_ERROR_ILLEGAL_VALUE;
}
return NS_OK;
}
nsresult
Convert(const nsAString& aIn, bt_bdaddr_t& aOut)
{
NS_ConvertUTF16toUTF8 bdAddressUTF8(aIn);
const char* str = bdAddressUTF8.get();
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aOut.address); ++i, ++str) {
aOut.address[i] =
static_cast<uint8_t>(strtoul(str, const_cast<char**>(&str), 16));
}
return NS_OK;
}
nsresult
Convert(const nsAString& aIn, bt_ssp_variant_t& aOut)
{
if (aIn.EqualsLiteral("PasskeyConfirmation")) {
aOut = BT_SSP_VARIANT_PASSKEY_CONFIRMATION;
} else if (aIn.EqualsLiteral("PasskeyEntry")) {
aOut = BT_SSP_VARIANT_PASSKEY_ENTRY;
} else if (aIn.EqualsLiteral("Consent")) {
aOut = BT_SSP_VARIANT_CONSENT;
} else if (aIn.EqualsLiteral("PasskeyNotification")) {
aOut = BT_SSP_VARIANT_PASSKEY_NOTIFICATION;
} else {
BT_LOGR("Invalid SSP variant name: %s", NS_ConvertUTF16toUTF8(aIn).get());
aOut = BT_SSP_VARIANT_PASSKEY_CONFIRMATION; // silences compiler warning
return NS_ERROR_ILLEGAL_VALUE;
}
return NS_OK;
}
nsresult
Convert(const uint8_t aIn[16], bt_uuid_t& aOut)
{
if (sizeof(aOut.uu) != 16) {
return NS_ERROR_ILLEGAL_VALUE;
}
memcpy(aOut.uu, aIn, sizeof(aOut.uu));
return NS_OK;
}
nsresult
Convert(const bt_uuid_t& aIn, BluetoothUuid& aOut)
{
if (sizeof(aIn.uu) != sizeof(aOut.mUuid)) {
return NS_ERROR_ILLEGAL_VALUE;
}
memcpy(aOut.mUuid, aIn.uu, sizeof(aOut.mUuid));
return NS_OK;
}
nsresult
Convert(const nsAString& aIn, bt_pin_code_t& aOut)
{
if (aIn.Length() > MOZ_ARRAY_LENGTH(aOut.pin)) {
return NS_ERROR_ILLEGAL_VALUE;
}
NS_ConvertUTF16toUTF8 pinCodeUTF8(aIn);
const char* str = pinCodeUTF8.get();
nsAString::size_type i;
// Fill pin into aOut
for (i = 0; i < aIn.Length(); ++i, ++str) {
aOut.pin[i] = static_cast<uint8_t>(*str);
}
// Clear remaining bytes in aOut
size_t ntrailing =
(MOZ_ARRAY_LENGTH(aOut.pin) - aIn.Length()) * sizeof(aOut.pin[0]);
memset(aOut.pin + aIn.Length(), 0, ntrailing);
return NS_OK;
}
nsresult
Convert(const bt_bdaddr_t& aIn, nsAString& aOut)
{
char str[BLUETOOTH_ADDRESS_LENGTH + 1];
int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
static_cast<int>(aIn.address[0]),
static_cast<int>(aIn.address[1]),
static_cast<int>(aIn.address[2]),
static_cast<int>(aIn.address[3]),
static_cast<int>(aIn.address[4]),
static_cast<int>(aIn.address[5]));
if (res < 0) {
return NS_ERROR_ILLEGAL_VALUE;
} else if ((size_t)res >= sizeof(str)) {
return NS_ERROR_OUT_OF_MEMORY; /* string buffer too small */
}
aOut = NS_ConvertUTF8toUTF16(str);
return NS_OK;
}
nsresult
Convert(const bt_service_record_t& aIn, BluetoothServiceRecord& aOut)
{
nsresult rv = Convert(aIn.uuid, aOut.mUuid);
if (NS_FAILED(rv)) {
return rv;
}
aOut.mChannel = aIn.channel;
MOZ_ASSERT(sizeof(aIn.name) == sizeof(aOut.mName));
memcpy(aOut.mName, aIn.name, sizeof(aOut.mName));
return NS_OK;
}
#if ANDROID_VERSION >= 18
nsresult
Convert(const BluetoothAvrcpElementAttribute& aIn, btrc_element_attr_val_t& aOut)
{
const NS_ConvertUTF16toUTF8 value(aIn.mValue);
size_t len = std::min<size_t>(strlen(value.get()), sizeof(aOut.text) - 1);
memcpy(aOut.text, value.get(), len);
aOut.text[len] = '\0';
aOut.attr_id = aIn.mId;
return NS_OK;
}
nsresult
Convert(const btrc_player_settings_t& aIn, BluetoothAvrcpPlayerSettings& aOut)
{
aOut.mNumAttr = aIn.num_attr;
memcpy(aOut.mIds, aIn.attr_ids, aIn.num_attr);
memcpy(aOut.mValues, aIn.attr_values, aIn.num_attr);
return NS_OK;
}
#endif // ANDROID_VERSION >= 18
nsresult
Convert(const bt_property_t& aIn, BluetoothProperty& aOut)
{
/* type conversion */
nsresult rv = Convert(aIn.type, aOut.mType);
if (NS_FAILED(rv)) {
return rv;
}
/* value conversion */
switch (aOut.mType) {
case PROPERTY_BDNAME:
/* fall through */
case PROPERTY_REMOTE_FRIENDLY_NAME:
{
// We construct an nsCString here because bdname
// returned from Bluedroid is not 0-terminated.
aOut.mString = NS_ConvertUTF8toUTF16(
nsCString(static_cast<char*>(aIn.val), aIn.len));
}
break;
case PROPERTY_BDADDR:
rv = Convert(*static_cast<bt_bdaddr_t*>(aIn.val), aOut.mString);
break;
case PROPERTY_UUIDS:
{
size_t numUuids = aIn.len / MAX_UUID_SIZE;
ConvertArray<bt_uuid_t> array(
static_cast<bt_uuid_t*>(aIn.val), numUuids);
aOut.mUuidArray.SetLength(numUuids);
rv = Convert(array, aOut.mUuidArray);
}
break;
case PROPERTY_CLASS_OF_DEVICE:
/* fall through */
case PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
aOut.mUint32 = *static_cast<uint32_t*>(aIn.val);
break;
case PROPERTY_TYPE_OF_DEVICE:
rv = Convert(*static_cast<bt_device_type_t*>(aIn.val),
aOut.mDeviceType);
break;
case PROPERTY_SERVICE_RECORD:
rv = Convert(*static_cast<bt_service_record_t*>(aIn.val),
aOut.mServiceRecord);
break;
case PROPERTY_ADAPTER_SCAN_MODE:
rv = Convert(*static_cast<bt_scan_mode_t*>(aIn.val),
aOut.mScanMode);
break;
case PROPERTY_ADAPTER_BONDED_DEVICES:
{
size_t numAddresses = aIn.len / BLUETOOTH_ADDRESS_BYTES;
ConvertArray<bt_bdaddr_t> array(
static_cast<bt_bdaddr_t*>(aIn.val), numAddresses);
aOut.mStringArray.SetLength(numAddresses);
rv = Convert(array, aOut.mStringArray);
}
break;
case PROPERTY_REMOTE_RSSI:
aOut.mInt32 = *static_cast<int32_t*>(aIn.val);
break;
#if ANDROID_VERSION >= 18
case PROPERTY_REMOTE_VERSION_INFO:
rv = Convert(*static_cast<bt_remote_version_t*>(aIn.val),
aOut.mRemoteInfo);
break;
#endif
case PROPERTY_REMOTE_DEVICE_TIMESTAMP:
/* nothing to do */
break;
default:
/* mismatch with type conversion */
NS_NOTREACHED("Unhandled property type");
break;
}
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
END_BLUETOOTH_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,913 @@
/* -*- 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 "BluetoothHALInterface.h"
#include "BluetoothHALHelpers.h"
#include "BluetoothA2dpHALInterface.h"
#include "BluetoothAvrcpHALInterface.h"
#include "BluetoothHandsfreeHALInterface.h"
#include "BluetoothSocketHALInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
template<class T>
struct interface_traits
{ };
template<>
struct interface_traits<BluetoothSocketHALInterface>
{
typedef const btsock_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_SOCKETS_ID;
}
};
template<>
struct interface_traits<BluetoothHandsfreeHALInterface>
{
typedef const bthf_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_HANDSFREE_ID;
}
};
template<>
struct interface_traits<BluetoothA2dpHALInterface>
{
typedef const btav_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_ADVANCED_AUDIO_ID;
}
};
#if ANDROID_VERSION >= 18
template<>
struct interface_traits<BluetoothAvrcpHALInterface>
{
typedef const btrc_interface_t const_interface_type;
static const char* profile_id()
{
return BT_PROFILE_AV_RC_ID;
}
};
#endif
typedef
BluetoothHALInterfaceRunnable0<BluetoothResultHandler, void>
BluetoothHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothHALErrorRunnable;
static nsresult
DispatchBluetoothHALResult(BluetoothResultHandler* aRes,
void (BluetoothResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothHALErrorRunnable(
aRes, &BluetoothResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothNotificationHandler* sNotificationHandler;
struct BluetoothCallback
{
class NotificationHandlerWrapper
{
public:
typedef BluetoothNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable1<NotificationHandlerWrapper, void,
bool>
AdapterStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, int,
const BluetoothProperty*>
AdapterPropertiesNotification;
typedef BluetoothNotificationHALRunnable4<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, int,
nsAutoArrayPtr<BluetoothProperty>,
BluetoothStatus, const nsAString&,
int, const BluetoothProperty*>
RemoteDevicePropertiesNotification;
typedef BluetoothNotificationHALRunnable2<NotificationHandlerWrapper, void,
int,
nsAutoArrayPtr<BluetoothProperty>,
int, const BluetoothProperty*>
DeviceFoundNotification;
typedef BluetoothNotificationHALRunnable1<NotificationHandlerWrapper, void,
bool>
DiscoveryStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
const nsAString&, const nsAString&>
PinRequestNotification;
typedef BluetoothNotificationHALRunnable5<NotificationHandlerWrapper, void,
nsString, nsString, uint32_t,
nsString, uint32_t,
const nsAString&, const nsAString&,
uint32_t, const nsAString&>
SspRequestNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString,
BluetoothBondState,
BluetoothStatus, const nsAString&>
BondStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
BluetoothStatus, nsString, bool,
BluetoothStatus, const nsAString&>
AclStateChangedNotification;
typedef BluetoothNotificationHALRunnable3<NotificationHandlerWrapper, void,
uint16_t, nsAutoArrayPtr<uint8_t>,
uint8_t, uint16_t, const uint8_t*>
DutModeRecvNotification;
typedef BluetoothNotificationHALRunnable2<NotificationHandlerWrapper, void,
BluetoothStatus, uint16_t>
LeTestModeNotification;
// Bluedroid callbacks
static const bt_property_t*
AlignedProperties(bt_property_t* aProperties, size_t aNumProperties,
nsAutoArrayPtr<bt_property_t>& aPropertiesArray)
{
// See Bug 989976: consider aProperties address is not aligned. If
// it is aligned, we return the pointer directly; otherwise we make
// an aligned copy. The argument |aPropertiesArray| keeps track of
// the memory buffer.
if (!(reinterpret_cast<uintptr_t>(aProperties) % sizeof(void*))) {
return aProperties;
}
bt_property_t* properties = new bt_property_t[aNumProperties];
memcpy(properties, aProperties, aNumProperties * sizeof(*properties));
aPropertiesArray = properties;
return properties;
}
static void
AdapterStateChanged(bt_state_t aStatus)
{
AdapterStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::AdapterStateChangedNotification,
aStatus);
}
static void
AdapterProperties(bt_status_t aStatus, int aNumProperties,
bt_property_t* aProperties)
{
nsAutoArrayPtr<bt_property_t> propertiesArray;
AdapterPropertiesNotification::Dispatch(
&BluetoothNotificationHandler::AdapterPropertiesNotification,
ConvertDefault(aStatus, STATUS_FAIL), aNumProperties,
ConvertArray<bt_property_t>(
AlignedProperties(aProperties, aNumProperties, propertiesArray),
aNumProperties));
}
static void
RemoteDeviceProperties(bt_status_t aStatus, bt_bdaddr_t* aBdAddress,
int aNumProperties, bt_property_t* aProperties)
{
nsAutoArrayPtr<bt_property_t> propertiesArray;
RemoteDevicePropertiesNotification::Dispatch(
&BluetoothNotificationHandler::RemoteDevicePropertiesNotification,
ConvertDefault(aStatus, STATUS_FAIL), aBdAddress, aNumProperties,
ConvertArray<bt_property_t>(
AlignedProperties(aProperties, aNumProperties, propertiesArray),
aNumProperties));
}
static void
DeviceFound(int aNumProperties, bt_property_t* aProperties)
{
nsAutoArrayPtr<bt_property_t> propertiesArray;
DeviceFoundNotification::Dispatch(
&BluetoothNotificationHandler::DeviceFoundNotification,
aNumProperties,
ConvertArray<bt_property_t>(
AlignedProperties(aProperties, aNumProperties, propertiesArray),
aNumProperties));
}
static void
DiscoveryStateChanged(bt_discovery_state_t aState)
{
DiscoveryStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::DiscoveryStateChangedNotification,
aState);
}
static void
PinRequest(bt_bdaddr_t* aRemoteBdAddress,
bt_bdname_t* aRemoteBdName, uint32_t aRemoteClass)
{
PinRequestNotification::Dispatch(
&BluetoothNotificationHandler::PinRequestNotification,
aRemoteBdAddress, aRemoteBdName, aRemoteClass);
}
static void
SspRequest(bt_bdaddr_t* aRemoteBdAddress, bt_bdname_t* aRemoteBdName,
uint32_t aRemoteClass, bt_ssp_variant_t aPairingVariant,
uint32_t aPasskey)
{
SspRequestNotification::Dispatch(
&BluetoothNotificationHandler::SspRequestNotification,
aRemoteBdAddress, aRemoteBdName, aRemoteClass,
aPairingVariant, aPasskey);
}
static void
BondStateChanged(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
bt_bond_state_t aState)
{
BondStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::BondStateChangedNotification,
aStatus, aRemoteBdAddress, aState);
}
static void
AclStateChanged(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
bt_acl_state_t aState)
{
AclStateChangedNotification::Dispatch(
&BluetoothNotificationHandler::AclStateChangedNotification,
aStatus, aRemoteBdAddress, aState);
}
static void
ThreadEvt(bt_cb_thread_evt evt)
{
// This callback maintains internal state and is not exported.
}
static void
DutModeRecv(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen)
{
DutModeRecvNotification::Dispatch(
&BluetoothNotificationHandler::DutModeRecvNotification,
aOpcode, ConvertArray<uint8_t>(aBuf, aLen), aLen);
}
static void
LeTestMode(bt_status_t aStatus, uint16_t aNumPackets)
{
LeTestModeNotification::Dispatch(
&BluetoothNotificationHandler::LeTestModeNotification,
aStatus, aNumPackets);
}
};
// Interface
//
/* returns the container structure of a variable; _t is the container's
* type, _v the name of the variable, and _m is _v's field within _t
*/
#define container(_t, _v, _m) \
( (_t*)( ((const unsigned char*)(_v)) - offsetof(_t, _m) ) )
BluetoothHALInterface*
BluetoothHALInterface::GetInstance()
{
static BluetoothHALInterface* sBluetoothInterface;
if (sBluetoothInterface) {
return sBluetoothInterface;
}
/* get driver module */
const hw_module_t* module;
int err = hw_get_module(BT_HARDWARE_MODULE_ID, &module);
if (err) {
BT_WARNING("hw_get_module failed: %s", strerror(err));
return nullptr;
}
/* get device */
hw_device_t* device;
err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
if (err) {
BT_WARNING("open failed: %s", strerror(err));
return nullptr;
}
const bluetooth_device_t* bt_device =
container(bluetooth_device_t, device, common);
/* get interface */
const bt_interface_t* bt_interface = bt_device->get_bluetooth_interface();
if (!bt_interface) {
BT_WARNING("get_bluetooth_interface failed");
goto err_get_bluetooth_interface;
}
if (bt_interface->size != sizeof(*bt_interface)) {
BT_WARNING("interface of incorrect size");
goto err_bt_interface_size;
}
sBluetoothInterface = new BluetoothHALInterface(bt_interface);
return sBluetoothInterface;
err_bt_interface_size:
err_get_bluetooth_interface:
err = device->close(device);
if (err) {
BT_WARNING("close failed: %s", strerror(err));
}
return nullptr;
}
BluetoothHALInterface::BluetoothHALInterface(
const bt_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothHALInterface::~BluetoothHALInterface()
{ }
void
BluetoothHALInterface::Init(
BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes)
{
static bt_callbacks_t sBluetoothCallbacks = {
sizeof(sBluetoothCallbacks),
BluetoothCallback::AdapterStateChanged,
BluetoothCallback::AdapterProperties,
BluetoothCallback::RemoteDeviceProperties,
BluetoothCallback::DeviceFound,
BluetoothCallback::DiscoveryStateChanged,
BluetoothCallback::PinRequest,
BluetoothCallback::SspRequest,
BluetoothCallback::BondStateChanged,
BluetoothCallback::AclStateChanged,
BluetoothCallback::ThreadEvt,
BluetoothCallback::DutModeRecv,
#if ANDROID_VERSION >= 18
BluetoothCallback::LeTestMode
#endif
};
sNotificationHandler = aNotificationHandler;
int status = mInterface->init(&sBluetoothCallbacks);
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::Cleanup(BluetoothResultHandler* aRes)
{
mInterface->cleanup();
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Cleanup,
STATUS_SUCCESS);
}
sNotificationHandler = nullptr;
}
void
BluetoothHALInterface::Enable(BluetoothResultHandler* aRes)
{
int status = mInterface->enable();
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Enable,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::Disable(BluetoothResultHandler* aRes)
{
int status = mInterface->disable();
if (aRes) {
DispatchBluetoothHALResult(aRes, &BluetoothResultHandler::Disable,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Adapter Properties */
void
BluetoothHALInterface::GetAdapterProperties(BluetoothResultHandler* aRes)
{
int status = mInterface->get_adapter_properties();
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetAdapterProperties,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes)
{
int status;
bt_property_type_t type;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (false /* TODO: we don't support any values for aName currently */) {
status = mInterface->get_adapter_property(type);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetAdapterProperties,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::SetAdapterProperty(
const BluetoothNamedValue& aProperty, BluetoothResultHandler* aRes)
{
int status;
ConvertNamedValue convertProperty(aProperty);
bt_property_t property;
if (NS_SUCCEEDED(Convert(convertProperty, property))) {
status = mInterface->set_adapter_property(&property);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::SetAdapterProperty,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Remote Device Properties */
void
BluetoothHALInterface::GetRemoteDeviceProperties(
const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t addr;
if (NS_SUCCEEDED(Convert(aRemoteAddr, addr))) {
status = mInterface->get_remote_device_properties(&addr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteDeviceProperties,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::GetRemoteDeviceProperty(
const nsAString& aRemoteAddr, const nsAString& aName,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
bt_property_type_t name;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
false /* TODO: we don't support any values for aName currently */) {
status = mInterface->get_remote_device_property(&remoteAddr, name);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteDeviceProperty,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::SetRemoteDeviceProperty(
const nsAString& aRemoteAddr, const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
bt_property_t property;
/* FIXME: you need to implement the missing conversion functions */
NS_NOTREACHED("Conversion function missing");
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
false /* TODO: we don't support any values for aProperty currently */) {
status = mInterface->set_remote_device_property(&remoteAddr, &property);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::SetRemoteDeviceProperty,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Remote Services */
void
BluetoothHALInterface::GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16],
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
bt_uuid_t uuid;
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr)) &&
NS_SUCCEEDED(Convert(aUuid, uuid))) {
status = mInterface->get_remote_service_record(&remoteAddr, &uuid);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteServiceRecord,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t remoteAddr;
if (NS_SUCCEEDED(Convert(aRemoteAddr, remoteAddr))) {
status = mInterface->get_remote_services(&remoteAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::GetRemoteServices,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Discovery */
void
BluetoothHALInterface::StartDiscovery(BluetoothResultHandler* aRes)
{
int status = mInterface->start_discovery();
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::StartDiscovery,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::CancelDiscovery(BluetoothResultHandler* aRes)
{
int status = mInterface->cancel_discovery();
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::CancelDiscovery,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Bonds */
void
BluetoothHALInterface::CreateBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes)
{
bt_bdaddr_t bdAddr;
int status;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->create_bond(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::CreateBond,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::RemoveBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes)
{
bt_bdaddr_t bdAddr;
int status;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->remove_bond(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::RemoveBond,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::CancelBond(const nsAString& aBdAddr,
BluetoothResultHandler* aRes)
{
bt_bdaddr_t bdAddr;
int status;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->cancel_bond(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::CancelBond,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Authentication */
void
BluetoothHALInterface::PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t bdAddr;
uint8_t accept;
bt_pin_code_t pinCode;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) &&
NS_SUCCEEDED(Convert(aAccept, accept)) &&
NS_SUCCEEDED(Convert(aPinCode, pinCode))) {
status = mInterface->pin_reply(&bdAddr, accept, aPinCode.Length(),
&pinCode);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::PinReply,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::SspReply(const nsAString& aBdAddr,
const nsAString& aVariant,
bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes)
{
int status;
bt_bdaddr_t bdAddr;
bt_ssp_variant_t variant;
uint8_t accept;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) &&
NS_SUCCEEDED(Convert(aVariant, variant)) &&
NS_SUCCEEDED(Convert(aAccept, accept))) {
status = mInterface->ssp_reply(&bdAddr, variant, accept, aPasskey);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::SspReply,
ConvertDefault(status, STATUS_FAIL));
}
}
/* DUT Mode */
void
BluetoothHALInterface::DutModeConfigure(bool aEnable,
BluetoothResultHandler* aRes)
{
int status;
uint8_t enable;
if (NS_SUCCEEDED(Convert(aEnable, enable))) {
status = mInterface->dut_mode_configure(enable);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::DutModeConfigure,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHALInterface::DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes)
{
int status = mInterface->dut_mode_send(aOpcode, aBuf, aLen);
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::DutModeSend,
ConvertDefault(status, STATUS_FAIL));
}
}
/* LE Mode */
void
BluetoothHALInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes)
{
#if ANDROID_VERSION >= 18
int status = mInterface->le_test_mode(aOpcode, aBuf, aLen);
#else
int status = BT_STATUS_UNSUPPORTED;
#endif
if (aRes) {
DispatchBluetoothHALResult(aRes,
&BluetoothResultHandler::LeTestMode,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Profile Interfaces */
template <class T>
T*
BluetoothHALInterface::CreateProfileInterface()
{
typename interface_traits<T>::const_interface_type* interface =
reinterpret_cast<typename interface_traits<T>::const_interface_type*>(
mInterface->get_profile_interface(interface_traits<T>::profile_id()));
if (!interface) {
BT_WARNING("Bluetooth profile '%s' is not supported",
interface_traits<T>::profile_id());
return nullptr;
}
if (interface->size != sizeof(*interface)) {
BT_WARNING("interface of incorrect size");
return nullptr;
}
return new T(interface);
}
#if ANDROID_VERSION < 18
/*
* Bluedroid versions that don't support AVRCP will call this function
* to create an AVRCP interface. All interface methods will fail with
* the error constant STATUS_UNSUPPORTED.
*/
template <>
BluetoothAvrcpHALInterface*
BluetoothHALInterface::CreateProfileInterface<BluetoothAvrcpHALInterface>()
{
BT_WARNING("Bluetooth profile 'avrcp' is not supported");
return new BluetoothAvrcpHALInterface();
}
#endif
template <class T>
T*
BluetoothHALInterface::GetProfileInterface()
{
static T* sBluetoothProfileInterface;
if (sBluetoothProfileInterface) {
return sBluetoothProfileInterface;
}
sBluetoothProfileInterface = CreateProfileInterface<T>();
return sBluetoothProfileInterface;
}
BluetoothSocketInterface*
BluetoothHALInterface::GetBluetoothSocketInterface()
{
return GetProfileInterface<BluetoothSocketHALInterface>();
}
BluetoothHandsfreeInterface*
BluetoothHALInterface::GetBluetoothHandsfreeInterface()
{
return GetProfileInterface<BluetoothHandsfreeHALInterface>();
}
BluetoothA2dpInterface*
BluetoothHALInterface::GetBluetoothA2dpInterface()
{
return GetProfileInterface<BluetoothA2dpHALInterface>();
}
BluetoothAvrcpInterface*
BluetoothHALInterface::GetBluetoothAvrcpInterface()
{
return GetProfileInterface<BluetoothAvrcpHALInterface>();
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,110 @@
/* -*- 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_dom_bluetooth_bluedroid_bluetoothhalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothhalinterface_h__
#include <hardware/bluetooth.h>
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface MOZ_FINAL : public BluetoothInterface
{
public:
static BluetoothHALInterface* GetInstance();
void Init(BluetoothNotificationHandler* aNotificationHandler,
BluetoothResultHandler* aRes);
void Cleanup(BluetoothResultHandler* aRes);
void Enable(BluetoothResultHandler* aRes);
void Disable(BluetoothResultHandler* aRes);
/* Adapter Properties */
void GetAdapterProperties(BluetoothResultHandler* aRes);
void GetAdapterProperty(const nsAString& aName,
BluetoothResultHandler* aRes);
void SetAdapterProperty(const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes);
/* Remote Device Properties */
void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes);
void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const nsAString& aName,
BluetoothResultHandler* aRes);
void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
const BluetoothNamedValue& aProperty,
BluetoothResultHandler* aRes);
/* Remote Services */
void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
const uint8_t aUuid[16],
BluetoothResultHandler* aRes);
void GetRemoteServices(const nsAString& aRemoteAddr,
BluetoothResultHandler* aRes);
/* Discovery */
void StartDiscovery(BluetoothResultHandler* aRes);
void CancelDiscovery(BluetoothResultHandler* aRes);
/* Bonds */
void CreateBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
void RemoveBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
void CancelBond(const nsAString& aBdAddr, BluetoothResultHandler* aRes);
/* Authentication */
void PinReply(const nsAString& aBdAddr, bool aAccept,
const nsAString& aPinCode,
BluetoothResultHandler* aRes);
void SspReply(const nsAString& aBdAddr, const nsAString& aVariant,
bool aAccept, uint32_t aPasskey,
BluetoothResultHandler* aRes);
/* DUT Mode */
void DutModeConfigure(bool aEnable, BluetoothResultHandler* aRes);
void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes);
/* LE Mode */
void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
BluetoothResultHandler* aRes);
/* Profile Interfaces */
BluetoothSocketInterface* GetBluetoothSocketInterface();
BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface();
BluetoothA2dpInterface* GetBluetoothA2dpInterface();
BluetoothAvrcpInterface* GetBluetoothAvrcpInterface();
protected:
BluetoothHALInterface(const bt_interface_t* aInterface);
~BluetoothHALInterface();
private:
template <class T>
T* CreateProfileInterface();
template <class T>
T* GetProfileInterface();
const bt_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -0,0 +1,616 @@
/* -*- 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 "BluetoothHandsfreeHALInterface.h"
#include "BluetoothHALHelpers.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable0<BluetoothHandsfreeResultHandler, void>
BluetoothHandsfreeHALResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothHandsfreeResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothHandsfreeHALErrorRunnable;
static nsresult
DispatchBluetoothHandsfreeHALResult(
BluetoothHandsfreeResultHandler* aRes,
void (BluetoothHandsfreeResultHandler::*aMethod)(),
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothHandsfreeHALResultRunnable(aRes, aMethod);
} else {
runnable = new BluetoothHandsfreeHALErrorRunnable(aRes,
&BluetoothHandsfreeResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
// Notification handling
//
static BluetoothHandsfreeNotificationHandler* sHandsfreeNotificationHandler;
struct BluetoothHandsfreeHALCallback
{
class HandsfreeNotificationHandlerWrapper
{
public:
typedef BluetoothHandsfreeNotificationHandler ObjectType;
static ObjectType* GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
return sHandsfreeNotificationHandler;
}
};
// Notifications
typedef BluetoothNotificationHALRunnable2<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeConnectionState, nsString,
BluetoothHandsfreeConnectionState, const nsAString&>
ConnectionStateNotification;
typedef BluetoothNotificationHALRunnable2<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeAudioState, nsString,
BluetoothHandsfreeAudioState, const nsAString&>
AudioStateNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeVoiceRecognitionState>
VoiceRecognitionNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
AnswerCallNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
HangupCallNotification;
typedef BluetoothNotificationHALRunnable2<
HandsfreeNotificationHandlerWrapper, void,
BluetoothHandsfreeVolumeType, int>
VolumeNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, nsString, const nsAString&>
DialCallNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, char>
DtmfNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeNRECState>
NRECNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType>
CallHoldNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
CnumNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
CindNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
CopsNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
ClccNotification;
typedef BluetoothNotificationHALRunnable1<
HandsfreeNotificationHandlerWrapper, void, nsCString, const nsACString&>
UnknownAtNotification;
typedef BluetoothNotificationHALRunnable0<
HandsfreeNotificationHandlerWrapper, void>
KeyPressedNotification;
// Bluedroid Handsfree callbacks
static void
ConnectionState(bthf_connection_state_t aState, bt_bdaddr_t* aBdAddr)
{
ConnectionStateNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::ConnectionStateNotification,
aState, aBdAddr);
}
static void
AudioState(bthf_audio_state_t aState, bt_bdaddr_t* aBdAddr)
{
AudioStateNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::AudioStateNotification,
aState, aBdAddr);
}
static void
VoiceRecognition(bthf_vr_state_t aState)
{
VoiceRecognitionNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification,
aState);
}
static void
AnswerCall()
{
AnswerCallNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::AnswerCallNotification);
}
static void
HangupCall()
{
HangupCallNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::HangupCallNotification);
}
static void
Volume(bthf_volume_type_t aType, int aVolume)
{
VolumeNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::VolumeNotification,
aType, aVolume);
}
static void
DialCall(char* aNumber)
{
DialCallNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::DialCallNotification, aNumber);
}
static void
Dtmf(char aDtmf)
{
DtmfNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::DtmfNotification, aDtmf);
}
static void
NoiseReductionEchoCancellation(bthf_nrec_t aNrec)
{
NRECNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::NRECNotification, aNrec);
}
static void
CallHold(bthf_chld_type_t aChld)
{
CallHoldNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CallHoldNotification, aChld);
}
static void
Cnum()
{
CnumNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CnumNotification);
}
static void
Cind()
{
CindNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CindNotification);
}
static void
Cops()
{
CopsNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::CopsNotification);
}
static void
Clcc()
{
ClccNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::ClccNotification);
}
static void
UnknownAt(char* aAtString)
{
UnknownAtNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::UnknownAtNotification,
aAtString);
}
static void
KeyPressed()
{
KeyPressedNotification::Dispatch(
&BluetoothHandsfreeNotificationHandler::KeyPressedNotification);
}
};
// Interface
//
BluetoothHandsfreeHALInterface::BluetoothHandsfreeHALInterface(
const bthf_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothHandsfreeHALInterface::~BluetoothHandsfreeHALInterface()
{ }
void
BluetoothHandsfreeHALInterface::Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
BluetoothHandsfreeResultHandler* aRes)
{
static bthf_callbacks_t sCallbacks = {
sizeof(sCallbacks),
BluetoothHandsfreeHALCallback::ConnectionState,
BluetoothHandsfreeHALCallback::AudioState,
BluetoothHandsfreeHALCallback::VoiceRecognition,
BluetoothHandsfreeHALCallback::AnswerCall,
BluetoothHandsfreeHALCallback::HangupCall,
BluetoothHandsfreeHALCallback::Volume,
BluetoothHandsfreeHALCallback::DialCall,
BluetoothHandsfreeHALCallback::Dtmf,
BluetoothHandsfreeHALCallback::NoiseReductionEchoCancellation,
BluetoothHandsfreeHALCallback::CallHold,
BluetoothHandsfreeHALCallback::Cnum,
BluetoothHandsfreeHALCallback::Cind,
BluetoothHandsfreeHALCallback::Cops,
BluetoothHandsfreeHALCallback::Clcc,
BluetoothHandsfreeHALCallback::UnknownAt,
BluetoothHandsfreeHALCallback::KeyPressed
};
sHandsfreeNotificationHandler = aNotificationHandler;
bt_status_t status = mInterface->init(&sCallbacks);
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Init,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::Cleanup(
BluetoothHandsfreeResultHandler* aRes)
{
mInterface->cleanup();
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Cleanup, STATUS_SUCCESS);
}
}
/* Connect / Disconnect */
void
BluetoothHandsfreeHALInterface::Connect(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->connect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Connect,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::Disconnect(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->disconnect(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::Disconnect,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::ConnectAudio(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->connect_audio(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::ConnectAudio,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::DisconnectAudio(
const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bt_bdaddr_t bdAddr;
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr))) {
status = mInterface->disconnect_audio(&bdAddr);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::DisconnectAudio,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Voice Recognition */
void
BluetoothHandsfreeHALInterface::StartVoiceRecognition(
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->start_voice_recognition();
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::StartVoiceRecognition,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::StopVoiceRecognition(
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->stop_voice_recognition();
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::StopVoiceRecognition,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Volume */
void
BluetoothHandsfreeHALInterface::VolumeControl(
BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_volume_type_t type = BTHF_VOLUME_TYPE_SPK;
if (NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->volume_control(type, aVolume);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::VolumeControl,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Device status */
void
BluetoothHandsfreeHALInterface::DeviceStatusNotification(
BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType, int aSignal,
int aBattChg, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_network_state_t ntkState = BTHF_NETWORK_STATE_NOT_AVAILABLE;
bthf_service_type_t svcType = BTHF_SERVICE_TYPE_HOME;
if (NS_SUCCEEDED(Convert(aNtkState, ntkState)) &&
NS_SUCCEEDED(Convert(aSvcType, svcType))) {
status = mInterface->device_status_notification(ntkState, svcType,
aSignal, aBattChg);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::DeviceStatusNotification,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Responses */
void
BluetoothHandsfreeHALInterface::CopsResponse(
const char* aCops, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->cops_response(aCops);
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::CopsResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::CindResponse(
int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
int aSignal, int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE;
if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState))) {
status = mInterface->cind_response(aSvc, aNumActive, aNumHeld,
callSetupState, aSignal,
aRoam, aBattChg);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::CindResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::FormattedAtResponse(
const char* aRsp, BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status = mInterface->formatted_at_response(aRsp);
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::FormattedAtResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::AtResponse(
BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_at_response_t responseCode = BTHF_AT_RESPONSE_ERROR;
if (NS_SUCCEEDED(Convert(aResponseCode, responseCode))) {
status = mInterface->at_response(responseCode, aErrorCode);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::AtResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
void
BluetoothHandsfreeHALInterface::ClccResponse(
int aIndex,
BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_call_direction_t dir = BTHF_CALL_DIRECTION_OUTGOING;
bthf_call_state_t state = BTHF_CALL_STATE_ACTIVE;
bthf_call_mode_t mode = BTHF_CALL_TYPE_VOICE;
bthf_call_mpty_type_t mpty = BTHF_CALL_MPTY_TYPE_SINGLE;
bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN;
if (NS_SUCCEEDED(Convert(aDir, dir)) &&
NS_SUCCEEDED(Convert(aState, state)) &&
NS_SUCCEEDED(Convert(aMode, mode)) &&
NS_SUCCEEDED(Convert(aMpty, mpty)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->clcc_response(aIndex, dir, state, mode, mpty,
NS_ConvertUTF16toUTF8(aNumber).get(),
type);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::ClccResponse,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Phone State */
void
BluetoothHandsfreeHALInterface::PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes)
{
bt_status_t status;
bthf_call_state_t callSetupState = BTHF_CALL_STATE_ACTIVE;
bthf_call_addrtype_t type = BTHF_CALL_ADDRTYPE_UNKNOWN;
if (NS_SUCCEEDED(Convert(aCallSetupState, callSetupState)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->phone_state_change(
aNumActive, aNumHeld, callSetupState,
NS_ConvertUTF16toUTF8(aNumber).get(), type);
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothHandsfreeHALResult(
aRes, &BluetoothHandsfreeResultHandler::PhoneStateChange,
ConvertDefault(status, STATUS_FAIL));
}
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,95 @@
/* -*- 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_dom_bluetooth_bluedroid_bluetoothhandsfreehalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothhandsfreehalinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_hf.h>
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothHandsfreeHALInterface MOZ_FINAL
: public BluetoothHandsfreeInterface
{
public:
friend class BluetoothHALInterface;
void Init(BluetoothHandsfreeNotificationHandler* aNotificationHandler,
BluetoothHandsfreeResultHandler* aRes);
void Cleanup(BluetoothHandsfreeResultHandler* aRes);
/* Connect / Disconnect */
void Connect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void Disconnect(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void ConnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
void DisconnectAudio(const nsAString& aBdAddr,
BluetoothHandsfreeResultHandler* aRes);
/* Voice Recognition */
void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
/* Volume */
void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
BluetoothHandsfreeResultHandler* aRes);
/* Device status */
void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
BluetoothHandsfreeServiceType aSvcType,
int aSignal, int aBattChg,
BluetoothHandsfreeResultHandler* aRes);
/* Responses */
void CopsResponse(const char* aCops,
BluetoothHandsfreeResultHandler* aRes);
void CindResponse(int aSvc, int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState, int aSignal,
int aRoam, int aBattChg,
BluetoothHandsfreeResultHandler* aRes);
void FormattedAtResponse(const char* aRsp,
BluetoothHandsfreeResultHandler* aRes);
void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
BluetoothHandsfreeResultHandler* aRes);
void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
BluetoothHandsfreeCallState aState,
BluetoothHandsfreeCallMode aMode,
BluetoothHandsfreeCallMptyType aMpty,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes);
/* Phone State */
void PhoneStateChange(int aNumActive, int aNumHeld,
BluetoothHandsfreeCallState aCallSetupState,
const nsAString& aNumber,
BluetoothHandsfreeCallAddressType aType,
BluetoothHandsfreeResultHandler* aRes);
protected:
BluetoothHandsfreeHALInterface(const bthf_interface_t* aInterface);
~BluetoothHandsfreeHALInterface();
private:
const bthf_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,480 @@
/* -*- 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 "BluetoothSocketHALInterface.h"
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include "BluetoothHALHelpers.h"
#include "nsXULAppAPI.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
int, int>
BluetoothSocketHALIntResultRunnable;
typedef
BluetoothHALInterfaceRunnable3<BluetoothSocketResultHandler, void,
int, const nsString, int,
int, const nsAString_internal&, int>
BluetoothSocketHALIntStringIntResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothSocketHALErrorRunnable;
static nsresult
DispatchBluetoothSocketHALResult(
BluetoothSocketResultHandler* aRes,
void (BluetoothSocketResultHandler::*aMethod)(int), int aArg,
BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothSocketHALIntResultRunnable(aRes, aMethod, aArg);
} else {
runnable = new BluetoothSocketHALErrorRunnable(aRes,
&BluetoothSocketResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
static nsresult
DispatchBluetoothSocketHALResult(
BluetoothSocketResultHandler* aRes,
void (BluetoothSocketResultHandler::*aMethod)(int, const nsAString&, int),
int aArg1, const nsAString& aArg2, int aArg3, BluetoothStatus aStatus)
{
MOZ_ASSERT(aRes);
nsRunnable* runnable;
if (aStatus == STATUS_SUCCESS) {
runnable = new BluetoothSocketHALIntStringIntResultRunnable(
aRes, aMethod, aArg1, aArg2, aArg3);
} else {
runnable = new BluetoothSocketHALErrorRunnable(aRes,
&BluetoothSocketResultHandler::OnError, aStatus);
}
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_FAILED(rv)) {
BT_WARNING("NS_DispatchToMainThread failed: %X", rv);
}
return rv;
}
void
BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
{
int fd;
bt_status_t status;
btsock_type_t type = BTSOCK_RFCOMM; // silences compiler warning
if (NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->listen(type,
NS_ConvertUTF16toUTF8(aServiceName).get(),
aServiceUuid, aChannel, &fd,
(BTSOCK_FLAG_ENCRYPT * aEncrypt) |
(BTSOCK_FLAG_AUTH * aAuth));
} else {
status = BT_STATUS_PARM_INVALID;
}
if (aRes) {
DispatchBluetoothSocketHALResult(
aRes, &BluetoothSocketResultHandler::Listen, fd,
ConvertDefault(status, STATUS_FAIL));
}
}
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
*
* Bluedroid sends two socket info messages (20 bytes) at
* the beginning of a connection to both peers.
*
* - 1st message: [channel:4]
* - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
*
* On the server side, the second message will contain a
* socket file descriptor for the connection. The client
* uses the original file descriptor.
*/
class SocketMessageWatcher : public MessageLoopForIO::Watcher
{
public:
static const unsigned char MSG1_SIZE = 4;
static const unsigned char MSG2_SIZE = 16;
static const unsigned char OFF_CHANNEL1 = 0;
static const unsigned char OFF_SIZE = 4;
static const unsigned char OFF_BDADDRESS = 6;
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
SocketMessageWatcher(int aFd)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
{ }
virtual ~SocketMessageWatcher()
{ }
virtual void Proceed(BluetoothStatus aStatus) = 0;
void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE
{
BluetoothStatus status;
switch (mLen) {
case 0:
status = RecvMsg1();
break;
case MSG1_SIZE:
status = RecvMsg2();
break;
default:
/* message-size error */
status = STATUS_FAIL;
break;
}
if (IsComplete() || status != STATUS_SUCCESS) {
mWatcher.StopWatchingFileDescriptor();
Proceed(status);
}
}
void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE
{ }
void Watch()
{
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
MessageLoopForIO::WATCH_READ,
&mWatcher,
this);
}
bool IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
}
int GetFd() const
{
return mFd;
}
int32_t GetChannel1() const
{
return ReadInt32(OFF_CHANNEL1);
}
int32_t GetSize() const
{
return ReadInt16(OFF_SIZE);
}
nsString GetBdAddress() const
{
nsString bdAddress;
ReadBdAddress(OFF_BDADDRESS, bdAddress);
return bdAddress;
}
int32_t GetChannel2() const
{
return ReadInt32(OFF_CHANNEL2);
}
int32_t GetConnectionStatus() const
{
return ReadInt32(OFF_STATUS);
}
int GetClientFd() const
{
return mClientFd;
}
private:
BluetoothStatus RecvMsg1()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf;
iv.iov_len = MSG1_SIZE;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res < 0) {
return STATUS_FAIL;
}
mLen += res;
return STATUS_SUCCESS;
}
BluetoothStatus RecvMsg2()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf + MSG1_SIZE;
iv.iov_len = MSG2_SIZE;
struct msghdr msg;
struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
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(mFd, &msg, MSG_NOSIGNAL));
if (res < 0) {
return STATUS_FAIL;
}
mLen += res;
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
return STATUS_FAIL;
}
struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
// Extract client fd from message header
for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
// if multiple file descriptors have been sent, we close
// all but the final one.
if (mClientFd != -1) {
TEMP_FAILURE_RETRY(close(mClientFd));
}
// retrieve sent client fd
mClientFd = *(static_cast<int*>(CMSG_DATA(cmsgptr)));
}
}
return STATUS_SUCCESS;
}
int16_t ReadInt16(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int16_t>(mBuf[aOffset]);
}
int32_t ReadInt32(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
(static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
(static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int32_t>(mBuf[aOffset]);
}
void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const
{
const bt_bdaddr_t* bdAddress =
reinterpret_cast<const bt_bdaddr_t*>(mBuf+aOffset);
if (NS_FAILED(Convert(*bdAddress, aBdAddress))) {
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
}
}
MessageLoopForIO::FileDescriptorWatcher mWatcher;
int mFd;
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher)
: mWatcher(aWatcher)
{
MOZ_ASSERT(mWatcher);
}
void Run() MOZ_OVERRIDE
{
mWatcher->Watch();
}
private:
SocketMessageWatcher* mWatcher;
};
/* |DeleteTask| deletes a class instance on the I/O thread
*/
template <typename T>
class DeleteTask MOZ_FINAL : public Task
{
public:
DeleteTask(T* aPtr)
: mPtr(aPtr)
{ }
void Run() MOZ_OVERRIDE
{
mPtr = nullptr;
}
private:
nsAutoPtr<T> mPtr;
};
/* |ConnectWatcher| specializes SocketMessageWatcher for
* connect operations by reading the socket messages from
* Bluedroid and forwarding the connected socket to the
* resource handler.
*/
class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
{ }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
{
int fd;
bt_status_t status;
bt_bdaddr_t bdAddr;
btsock_type_t type = BTSOCK_RFCOMM; // silences compiler warning
if (NS_SUCCEEDED(Convert(aBdAddr, bdAddr)) &&
NS_SUCCEEDED(Convert(aType, type))) {
status = mInterface->connect(&bdAddr, type, aUuid, aChannel, &fd,
(BTSOCK_FLAG_ENCRYPT * aEncrypt) |
(BTSOCK_FLAG_AUTH * aAuth));
} else {
status = BT_STATUS_PARM_INVALID;
}
if (status == BT_STATUS_SUCCESS) {
/* receive Bluedroid's socket-setup messages */
Task* t = new SocketMessageWatcherTask(new ConnectWatcher(fd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
} else if (aRes) {
DispatchBluetoothSocketHALResult(
aRes, &BluetoothSocketResultHandler::Connect, -1, EmptyString(), 0,
ConvertDefault(status, STATUS_FAIL));
}
}
/* Specializes SocketMessageWatcher for Accept operations by
* reading the socket messages from Bluedroid and forwarding
* the received client socket to the resource handler. The
* first message is received immediately. When there's a new
* connection, Bluedroid sends the 2nd message with the socket
* info and socket file descriptor.
*/
class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
{
/* not supplying a result handler leaks received file descriptor */
MOZ_ASSERT(mRes);
}
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
BluetoothSocketHALInterface::Accept(int aFd,
BluetoothSocketResultHandler* aRes)
{
/* receive Bluedroid's socket-setup messages and client fd */
Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
}
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
const btsock_interface_t* aInterface)
: mInterface(aInterface)
{
MOZ_ASSERT(mInterface);
}
BluetoothSocketHALInterface::~BluetoothSocketHALInterface()
{ }
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,49 @@
/* -*- 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_dom_bluetooth_bluedroid_bluetoothsockethalinterface_h__
#define mozilla_dom_bluetooth_bluedroid_bluetoothsockethalinterface_h__
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothHALInterface;
class BluetoothSocketHALInterface MOZ_FINAL
: public BluetoothSocketInterface
{
public:
friend class BluetoothHALInterface;
void Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes);
void Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt, bool aAuth,
BluetoothSocketResultHandler* aRes);
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
protected:
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
~BluetoothSocketHALInterface();
private:
const btsock_interface_t* mInterface;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -9,6 +9,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothAdapter.cpp',
'BluetoothDevice.cpp',
'BluetoothHidManager.cpp',
'BluetoothInterface.cpp',
'BluetoothManager.cpp',
'BluetoothProfileController.cpp',
'BluetoothPropertyContainer.cpp',
@ -44,11 +45,16 @@ if CONFIG['MOZ_B2G_BT']:
DEFINES['MOZ_B2G_BT_BLUEZ'] = True
elif CONFIG['MOZ_B2G_BT_BLUEDROID']:
SOURCES += [
'bluedroid/BluetoothA2dpHALInterface.cpp',
'bluedroid/BluetoothA2dpManager.cpp',
'bluedroid/BluetoothInterface.cpp',
'bluedroid/BluetoothAvrcpHALInterface.cpp',
'bluedroid/BluetoothHALHelpers.cpp',
'bluedroid/BluetoothHALInterface.cpp',
'bluedroid/BluetoothHandsfreeHALInterface.cpp',
'bluedroid/BluetoothOppManager.cpp',
'bluedroid/BluetoothServiceBluedroid.cpp',
'bluedroid/BluetoothSocket.cpp',
'bluedroid/BluetoothSocketHALInterface.cpp',
'bluedroid/BluetoothUtils.cpp',
]
LOCAL_INCLUDES += [

View File

@ -21,7 +21,6 @@ XPIDL_SOURCES += [
'nsIDOMNSEditableElement.idl',
'nsIDOMProcessingInstruction.idl',
'nsIDOMText.idl',
'nsIDOMUserDataHandler.idl',
'nsIDOMXMLDocument.idl',
]

View File

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[builtinclass, uuid(a974a4d3-2ff1-445b-8b8e-0aada5d4eedc)]
[builtinclass, uuid(93bf61ba-9ffa-42b7-9594-2de803c9627c)]
interface nsIDOMAttr : nsIDOMNode
{
readonly attribute DOMString name;

View File

@ -15,7 +15,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[uuid(0f401429-30b3-46de-b1bf-d7d5fa7563f9)]
[uuid(864c4e6a-3933-4f8a-8dd8-3883be60ea10)]
interface nsIDOMCDATASection : nsIDOMText
{
};

View File

@ -13,7 +13,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[uuid(84f72a38-1873-46f8-937c-1df22d7e7cae)]
[uuid(7b1b8719-6669-4614-bf96-93ddf7966f64)]
interface nsIDOMCharacterData : nsIDOMNode
{
attribute DOMString data;

View File

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[uuid(e702a5d2-3aa8-4788-b048-2d3b3e6d16f2)]
[uuid(8edde4d9-dc26-492c-8477-2be0f95088ad)]
interface nsIDOMComment : nsIDOMCharacterData
{
};

View File

@ -32,7 +32,7 @@ interface nsIDOMLocation;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(d24d1118-a527-4d5a-9c4e-fb07dfc2fc27)]
[uuid(950ca868-e09f-4a7d-9b87-e4ec9aedb3e5)]
interface nsIDOMDocument : nsIDOMNode
{
readonly attribute nsIDOMDocumentType doctype;

View File

@ -14,7 +14,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[builtinclass, uuid(75a237af-133e-40f0-8196-2a172867c41a)]
[builtinclass, uuid(5c601878-5b77-4f88-9425-3fe8d2dc8813)]
interface nsIDOMDocumentFragment : nsIDOMNode
{
/**

View File

@ -15,7 +15,7 @@
* http://www.w3.org/TR/DOM-Level-2-Core/
*/
[uuid(aa7d28b2-7122-422d-8fcf-634771fb9ac1)]
[uuid(55fe2f3f-35e8-4cb0-b39d-bea1bd0061c7)]
interface nsIDOMDocumentType : nsIDOMNode
{
readonly attribute DOMString name;

View File

@ -15,7 +15,7 @@ interface nsIDOMMozNamedAttrMap;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
*/
[uuid(d7de6065-1776-4f52-a776-4bbeabacbdaf)]
[uuid(ea94c5e2-5d5d-4afe-b3ab-431903797f31)]
interface nsIDOMElement : nsIDOMNode
{
readonly attribute DOMString tagName;

View File

@ -6,7 +6,6 @@
#include "domstubs.idl"
interface nsIVariant;
interface nsIDOMUserDataHandler;
/**
* The nsIDOMNode interface is the primary datatype for the entire
@ -17,7 +16,7 @@ interface nsIDOMUserDataHandler;
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(56545150-a001-484e-9ed4-cb319eebd7b3)]
[uuid(3eef1ab9-2f87-4eda-9bb9-469c37294f72)]
interface nsIDOMNode : nsISupports
{
const unsigned short ELEMENT_NODE = 1;
@ -102,9 +101,8 @@ interface nsIDOMNode : nsISupports
// Introduced in DOM Level 3:
boolean isEqualNode(in nsIDOMNode arg);
// Introduced in DOM Level 3:
nsIVariant setUserData(in DOMString key,
in nsIVariant data,
in nsIDOMUserDataHandler handler);
nsIVariant setUserData(in DOMString key,
in nsIVariant data);
// Introduced in DOM Level 3:
nsIVariant getUserData(in DOMString key);

View File

@ -15,7 +15,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(91f2e856-5596-44d6-b396-0a02d8ec28c6)]
[uuid(ca632936-4c6b-48b4-9920-fbe1e3710802)]
interface nsIDOMProcessingInstruction : nsIDOMCharacterData
{
readonly attribute DOMString target;

View File

@ -13,7 +13,7 @@
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[uuid(d14d13b4-21d5-49e2-8d59-76a24156db54)]
[uuid(b16d449b-60f1-444a-a7e5-dc50a5d0ffad)]
interface nsIDOMText : nsIDOMCharacterData
{
nsIDOMText splitText(in unsigned long offset)

View File

@ -1,26 +0,0 @@
/* 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 "domstubs.idl"
#include "nsIVariant.idl"
// Introduced in DOM Level 3:
[scriptable, function, uuid(91afebdd-a201-4db0-b728-9d59580f0cfd)]
interface nsIDOMUserDataHandler : nsISupports
{
// OperationType
const unsigned short NODE_CLONED = 1;
const unsigned short NODE_IMPORTED = 2;
const unsigned short NODE_DELETED = 3;
const unsigned short NODE_RENAMED = 4;
const unsigned short NODE_ADOPTED = 5;
void handle(in unsigned short operation,
in DOMString key,
in nsIVariant data,
in nsIDOMNode src,
in nsIDOMNode dst);
};

View File

@ -5,7 +5,7 @@
#include "nsIDOMDocument.idl"
[uuid(ebf9f390-7cd2-4456-bc53-4869019370ea)]
[uuid(dc767223-838f-4ca2-9f4c-ae685862d1df)]
interface nsIDOMXMLDocument : nsIDOMDocument
{
// DOM Level 3 Load & Save, DocumentLS

View File

@ -13,7 +13,7 @@
*/
interface nsISelection;
[uuid(b73be9dd-bcc8-44df-8b01-3389e277427f)]
[uuid(b7fcb58a-9ad5-44b5-8c6f-b7181c249413)]
interface nsIDOMHTMLDocument : nsIDOMDocument
{
attribute DOMString domain;

View File

@ -19,7 +19,7 @@ interface nsIDOMHTMLMenuElement;
* with changes from the work-in-progress WHATWG HTML specification:
* http://www.whatwg.org/specs/web-apps/current-work/
*/
[uuid(db3352cf-04f3-4e7e-baa0-cd2f81b46328)]
[uuid(2728c077-9ecc-4a75-ac95-16fbfcb007df)]
interface nsIDOMHTMLElement : nsIDOMElement
{
// metadata attributes

View File

@ -9,7 +9,7 @@ interface nsIDOMCSSStyleDeclaration;
interface nsIDOMCSSValue;
[uuid(0a6c6f77-8256-402c-9b2d-01d177ad3877)]
[uuid(7a11697a-668b-4a6e-a44a-909abffee230)]
interface nsIDOMSVGElement : nsIDOMElement
{
// raises DOMException on setting

View File

@ -10,7 +10,7 @@ interface nsIDOMXULCommandDispatcher;
interface nsIObserver;
interface nsIBoxObject;
[uuid(efdb94fb-642f-4a79-ae20-9a5f7cb7f736)]
[uuid(546c658e-805f-4293-9738-6e6a00d75839)]
interface nsIDOMXULDocument : nsIDOMDocument
{
attribute nsIDOMNode popupNode;

View File

@ -12,7 +12,7 @@ interface nsIControllers;
interface nsIBoxObject;
[uuid(604d10c0-6ad0-4419-ad2f-a090d20bd7dc)]
[uuid(1bd9303d-0854-4ed3-9fda-added29a570e)]
interface nsIDOMXULElement : nsIDOMElement
{
// Layout properties

View File

@ -34,6 +34,7 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
using nscolor from "nsColor.h";
using class mozilla::WidgetCompositionEvent from "ipc/nsGUIEventIPC.h";
using struct mozilla::widget::IMENotification from "nsIWidget.h";
using struct nsIMEUpdatePreference from "nsIWidget.h";
using struct nsIntPoint from "nsPoint.h";
using struct nsIntRect from "nsRect.h";
@ -188,6 +189,14 @@ parent:
*/
NotifyIMETextHint(nsString text);
/**
* Notifies IME of mouse button event on a character in focused editor.
*
* Returns true if the mouse button event is consumd by IME.
*/
sync NotifyIMEMouseButtonEvent(IMENotification notification)
returns (bool consumedByIME);
/**
* Instructs chrome to end any pending composition
*

View File

@ -1310,6 +1310,22 @@ TabParent::RecvNotifyIMETextHint(const nsString& aText)
return true;
}
bool
TabParent::RecvNotifyIMEMouseButtonEvent(
const IMENotification& aIMENotification,
bool* aConsumedByIME)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
*aConsumedByIME = false;
return true;
}
nsresult rv = widget->NotifyIME(aIMENotification);
*aConsumedByIME = rv == NS_SUCCESS_EVENT_CONSUMED;
return true;
}
bool
TabParent::RecvRequestFocus(const bool& aCanRaise)
{

View File

@ -40,6 +40,10 @@ namespace layout {
class RenderFrameParent;
}
namespace widget {
struct IMENotification;
}
namespace dom {
class ClonedMessageData;
@ -167,6 +171,8 @@ public:
const uint32_t& aFocus,
const bool& aCausedByComposition) MOZ_OVERRIDE;
virtual bool RecvNotifyIMETextHint(const nsString& aText) MOZ_OVERRIDE;
virtual bool RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
bool* aConsumedByIME) MOZ_OVERRIDE;
virtual bool RecvEndIMEComposition(const bool& aCancel,
nsString* aComposition) MOZ_OVERRIDE;
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,

View File

@ -1187,8 +1187,6 @@ var interfaceNamesInGlobalScope =
"URL",
// IMPORTANT: Do not change this list without review from a DOM peer!
"URLSearchParams",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "UserDataHandler", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
"UserProximityEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -12,7 +12,6 @@
interface Principal;
interface URI;
interface UserDataHandler;
interface Node : EventTarget {
const unsigned short ELEMENT_NODE = 1;
@ -105,7 +104,7 @@ interface Node : EventTarget {
[Pure]
boolean hasAttributes();
[Throws, Func="IsChromeOrXBL"]
any setUserData(DOMString key, any data, UserDataHandler? handler);
any setUserData(DOMString key, any data);
[Throws, Func="IsChromeOrXBL"]
any getUserData(DOMString key);
[ChromeOnly]

View File

@ -40,7 +40,6 @@
#include "nsIAuthPrompt.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentPolicyUtils.h"
#include "nsIDOMUserDataHandler.h"
#include "nsNodeUtils.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"

View File

@ -76,7 +76,10 @@ public:
HRESULT hr = mDT->mDevice->CreateTexture2D(&desc, nullptr, byRef(tmpTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create temporary texture to hold surface data.";
gfxWarning() << "Failure to create temporary texture. Size: " << size << " Code: " << hr;
// Crash debug builds but try to recover in release builds.
MOZ_ASSERT(false);
return;
}
mDT->mDevice->CopyResource(tmpTexture, mDT->mTexture);
@ -90,7 +93,10 @@ public:
&props, byRef(mOldSurfBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create shared bitmap for old surface.";
gfxWarning() << "Failed to create shared bitmap for old surface. Code: " << hr;
// Crash debug builds but try to recover in release builds.
MOZ_ASSERT(false);
return;
}
IntRect clipBounds;

View File

@ -116,32 +116,7 @@ Compositor::ClipRectInLayersCoordinates(Layer* aLayer, RenderTargetIntRect aClip
RenderTargetRect result;
aClip = aClip + renderTargetOffset;
RenderTargetIntSize destSize = RenderTargetIntSize(GetWidgetSize().width,
GetWidgetSize().height);
switch (mScreenRotation) {
case ROTATION_0:
result = RenderTargetRect(aClip.x, aClip.y, aClip.width, aClip.height);
break;
case ROTATION_90:
result = RenderTargetRect(aClip.y,
destSize.width - aClip.x - aClip.width,
aClip.height, aClip.width);
break;
case ROTATION_270:
result = RenderTargetRect(destSize.height - aClip.y - aClip.height,
aClip.x,
aClip.height, aClip.width);
break;
case ROTATION_180:
result = RenderTargetRect(destSize.width - aClip.x - aClip.width,
destSize.height - aClip.y - aClip.height,
aClip.width, aClip.height);
break;
// ScreenRotation has a sentinel value, need to catch it in the switch
// statement otherwise the build fails (-WError)
default: {}
}
result = RenderTargetRect(aClip.x, aClip.y, aClip.width, aClip.height);
return result;
}

View File

@ -342,7 +342,6 @@ public:
*/
virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
const gfx::Rect* aClipRectIn,
const gfx::Matrix& aTransform,
const gfx::Rect& aRenderBounds,
gfx::Rect* aClipRectOut = nullptr,
gfx::Rect* aRenderBoundsOut = nullptr) = 0;
@ -373,11 +372,8 @@ public:
* target, usually the screen. Calling this method prepares the compositor to
* render using a different viewport (that is, size and transform), usually
* associated with a new render target.
* aWorldTransform is the transform from user space to the new viewport's
* coordinate space.
*/
virtual void PrepareViewport(const gfx::IntSize& aSize,
const gfx::Matrix& aWorldTransform) = 0;
virtual void PrepareViewport(const gfx::IntSize& aSize) = 0;
/**
* Whether textures created by this compositor can receive partial updates.

View File

@ -631,8 +631,7 @@ Layer::MayResample()
}
RenderTargetIntRect
Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect,
const gfx::Matrix* aWorldTransform)
Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect)
{
ContainerLayer* container = GetParent();
NS_ASSERTION(container, "This can't be called on the root!");
@ -681,15 +680,6 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect,
if (container) {
scissor.MoveBy(-container->GetIntermediateSurfaceRect().TopLeft());
} else if (aWorldTransform) {
gfx::Rect r(scissor.x, scissor.y, scissor.width, scissor.height);
gfx::Rect trScissor = aWorldTransform->TransformBounds(r);
trScissor.Round();
nsIntRect tmp;
if (!gfxUtils::GfxRectToIntRect(ThebesRect(trScissor), &tmp)) {
return RenderTargetIntRect(currentClip.TopLeft(), RenderTargetIntSize(0, 0));
}
scissor = RenderTargetPixel::FromUntyped(tmp);
}
return currentClip.Intersect(scissor);
}

View File

@ -1392,12 +1392,8 @@ public:
* nearest ancestor that has an intermediate surface, or relative to the root
* viewport if no ancestor has an intermediate surface, corresponding to the
* clip rect for this layer intersected with aCurrentScissorRect.
* If no ancestor has an intermediate surface, the clip rect is transformed
* by aWorldTransform before being combined with aCurrentScissorRect, if
* aWorldTransform is non-null.
*/
RenderTargetIntRect CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect,
const gfx::Matrix* aWorldTransform);
RenderTargetIntRect CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect);
virtual const char* Name() const =0;
virtual LayerType GetType() const =0;

View File

@ -460,10 +460,13 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
int currTileX = floor_div(x - newBufferOrigin.x, scaledTileSize.width);
int currTileY = floor_div(y - newBufferOrigin.y, scaledTileSize.height);
int index = currTileX * mRetainedHeight + currTileY;
NS_ABORT_IF_FALSE(!newValidRegion.Intersects(tileRect) ||
!IsPlaceholder(newRetainedTiles.
SafeElementAt(index, AsDerived().GetPlaceholderTile())),
"If we don't draw a tile we shouldn't have a placeholder there.");
// If allocating a tile failed we can run into this assertion.
// Rendering is going to be glitchy but we don't want to crash.
NS_ASSERTION(!newValidRegion.Intersects(tileRect) ||
!IsPlaceholder(newRetainedTiles.
SafeElementAt(index, AsDerived().GetPlaceholderTile())),
"Unexpected placeholder tile");
#endif
y += height;
continue;
@ -494,7 +497,7 @@ TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
nsIntPoint tileOrigin(tileStartX, tileStartY);
newTile = AsDerived().ValidateTile(newTile, nsIntPoint(tileStartX, tileStartY),
tileDrawRegion);
NS_ABORT_IF_FALSE(!IsPlaceholder(newTile), "index out of range");
NS_ASSERTION(!IsPlaceholder(newTile), "Unexpected placeholder tile - failed to allocate?");
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Store Validate tile %i, %i -> %i\n", tileStartX, tileStartY, index);
#endif

View File

@ -385,7 +385,6 @@ BasicCompositor::ClearRect(const gfx::Rect& aRect)
void
BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
const gfx::Rect *aClipRectIn,
const gfx::Matrix& aTransform,
const gfx::Rect& aRenderBounds,
gfx::Rect *aClipRectOut /* = nullptr */,
gfx::Rect *aRenderBoundsOut /* = nullptr */)

View File

@ -89,7 +89,6 @@ public:
virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
const gfx::Rect *aClipRectIn,
const gfx::Matrix& aTransform,
const gfx::Rect& aRenderBounds,
gfx::Rect *aClipRectOut = nullptr,
gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
@ -110,8 +109,7 @@ public:
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) { }
virtual void PrepareViewport(const gfx::IntSize& aSize,
const gfx::Matrix& aWorldTransform) MOZ_OVERRIDE { }
virtual void PrepareViewport(const gfx::IntSize& aSize) MOZ_OVERRIDE { }
virtual const char* Name() const { return "Basic"; }

View File

@ -133,9 +133,6 @@ ClientLayerManager::SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
ScreenRotation aRotation)
{
mTargetRotation = aRotation;
if (mWidget) {
mTargetBounds = mWidget->GetNaturalBounds();
}
}
void
@ -201,10 +198,9 @@ ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
hal::GetCurrentScreenConfiguration(&currentConfig);
orientation = currentConfig.orientation();
}
nsIntRect clientBounds;
mWidget->GetClientBounds(clientBounds);
clientBounds.x = clientBounds.y = 0;
mForwarder->BeginTransaction(mTargetBounds, mTargetRotation, clientBounds, orientation);
nsIntRect targetBounds = mWidget->GetNaturalBounds();
targetBounds.x = targetBounds.y = 0;
mForwarder->BeginTransaction(targetBounds, mTargetRotation, orientation);
// If we're drawing on behalf of a context with async pan/zoom
// enabled, then the entire buffer of thebes layers might be

View File

@ -285,9 +285,6 @@ private:
void* aCallbackData,
EndTransactionFlags);
// The bounds of |mTarget| in device pixels.
nsIntRect mTargetBounds;
LayerRefArray mKeepAlive;
nsIWidget* mWidget;

View File

@ -751,6 +751,12 @@ TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
if (!mBackBuffer ||
mBackLock->GetReadCount() > 1) {
if (mBackLock) {
// Before we Replacing the lock by another one we need to unlock it!
mBackLock->ReadUnlock();
}
if (mBackBuffer) {
// Our current back-buffer is still locked by the compositor. This can occur
// when the client is producing faster than the compositor can consume. In
@ -761,14 +767,18 @@ TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
}
}
mBackBuffer.Set(this, pool->GetTextureClient());
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
mBackBufferOnWhite = pool->GetTextureClient();
if (!mBackBuffer) {
return nullptr;
}
if (mBackLock) {
// Before we Replacing the lock by another one we need to unlock it!
mBackLock->ReadUnlock();
if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
mBackBufferOnWhite = pool->GetTextureClient();
if (!mBackBufferOnWhite) {
mBackBuffer.Set(this, nullptr);
return nullptr;
}
}
// Create a lock for our newly created back-buffer.
if (mManager->AsShadowForwarder()->IsSameProcess()) {
// If our compositor is in the same process, we can save some cycles by not
@ -1122,19 +1132,29 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
extraPainted.And(extraPainted, mNewValidRegion);
mPaintedRegion.Or(mPaintedRegion, extraPainted);
if (!backBuffer) {
NS_WARNING("Failed to allocate a tile TextureClient");
aTile.DiscardBackBuffer();
aTile.DiscardFrontBuffer();
return TileClient();
}
// the back buffer may have been already locked in ValidateBackBufferFromFront
if (!backBuffer->IsLocked()) {
if (!backBuffer->Lock(OpenMode::OPEN_READ_WRITE)) {
NS_WARNING("Failed to lock tile TextureClient for updating.");
NS_WARNING("Failed to lock a tile TextureClient");
aTile.DiscardBackBuffer();
aTile.DiscardFrontBuffer();
return aTile;
return TileClient();
}
}
if (backBufferOnWhite && !backBufferOnWhite->IsLocked()) {
if (!backBufferOnWhite->Lock(OpenMode::OPEN_READ_WRITE)) {
NS_WARNING("Failed to lock tile TextureClient for updating.");
aTile.DiscardBackBuffer();
aTile.DiscardFrontBuffer();
return aTile;
return TileClient();
}
}

View File

@ -74,7 +74,7 @@ WalkTheTree(Layer* aLayer,
dom::ScreenOrientation chromeOrientation = aTargetConfig.orientation();
dom::ScreenOrientation contentOrientation = state->mTargetConfig.orientation();
if (!IsSameDimension(chromeOrientation, contentOrientation) &&
ContentMightReflowOnOrientationChange(aTargetConfig.clientBounds())) {
ContentMightReflowOnOrientationChange(aTargetConfig.naturalBounds())) {
aReady = false;
}
}
@ -122,9 +122,9 @@ void
AsyncCompositionManager::ComputeRotation()
{
if (!mTargetConfig.naturalBounds().IsEmpty()) {
mLayerManager->SetWorldTransform(
mWorldTransform =
ComputeTransformForRotation(mTargetConfig.naturalBounds(),
mTargetConfig.rotation()));
mTargetConfig.rotation());
}
}
@ -958,6 +958,7 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
return false;
}
// NB: we must sample animations *before* sampling pan/zoom
// transforms.
bool wantNextFrame = SampleAnimations(root, aCurrentFrame);
@ -995,6 +996,13 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
}
}
LayerComposite* rootComposite = root->AsLayerComposite();
gfx::Matrix4x4 trans = rootComposite->GetShadowTransform();
trans *= gfx::Matrix4x4::From2D(mWorldTransform);
rootComposite->SetShadowTransform(trans);
return wantNextFrame;
}

View File

@ -204,6 +204,8 @@ private:
bool mLayersUpdated;
bool mReadyForCompose;
gfx::Matrix mWorldTransform;
};
class MOZ_STACK_CLASS AutoResolveRefLayers {

View File

@ -184,7 +184,7 @@ ContainerPrepare(ContainerT* aContainer,
}
RenderTargetIntRect clipRect = layerToRender->GetLayer()->
CalculateScissorRect(aClipRect, &aManager->GetWorldTransform());
CalculateScissorRect(aClipRect);
if (clipRect.IsEmpty()) {
continue;
}

View File

@ -601,14 +601,14 @@ LayerManagerComposite::Render()
composer2D = mCompositor->GetWidget()->GetComposer2D();
}
if (!mTarget && composer2D && composer2D->TryRender(mRoot, mWorldMatrix, mGeometryChanged)) {
if (!mTarget && composer2D && composer2D->TryRender(mRoot, mGeometryChanged)) {
if (mFPS) {
double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());
if (gfxPrefs::LayersDrawFPS()) {
printf_stderr("HWComposer: FPS is %g\n", fps);
}
}
mCompositor->EndFrameForExternalComposition(mWorldMatrix);
mCompositor->EndFrameForExternalComposition(Matrix());
// Reset the invalid region as compositing is done
mInvalidRegion.SetEmpty();
mLastFrameMissedHWC = false;
@ -643,12 +643,11 @@ LayerManagerComposite::Render()
if (mRoot->GetClipRect()) {
clipRect = *mRoot->GetClipRect();
WorldTransformRect(clipRect);
Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
mCompositor->BeginFrame(invalid, &rect, mWorldMatrix, bounds, nullptr, &actualBounds);
mCompositor->BeginFrame(invalid, &rect, bounds, nullptr, &actualBounds);
} else {
gfx::Rect rect;
mCompositor->BeginFrame(invalid, nullptr, mWorldMatrix, bounds, &rect, &actualBounds);
mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds);
clipRect = nsIntRect(rect.x, rect.y, rect.width, rect.height);
}
@ -710,31 +709,6 @@ LayerManagerComposite::Render()
RecordFrame();
}
void
LayerManagerComposite::SetWorldTransform(const gfx::Matrix& aMatrix)
{
NS_ASSERTION(aMatrix.PreservesAxisAlignedRectangles(),
"SetWorldTransform only accepts matrices that satisfy PreservesAxisAlignedRectangles");
NS_ASSERTION(!aMatrix.HasNonIntegerScale(),
"SetWorldTransform only accepts matrices with integer scale");
mWorldMatrix = aMatrix;
}
gfx::Matrix&
LayerManagerComposite::GetWorldTransform(void)
{
return mWorldMatrix;
}
void
LayerManagerComposite::WorldTransformRect(nsIntRect& aRect)
{
gfx::Rect grect(aRect.x, aRect.y, aRect.width, aRect.height);
grect = mWorldMatrix.TransformBounds(grect);
aRect.SetRect(grect.X(), grect.Y(), grect.Width(), grect.Height());
}
static void
SubtractTransformedRegion(nsIntRegion& aRegion,
const nsIntRegion& aRegionToSubtract,

View File

@ -165,19 +165,6 @@ public:
virtual const char* Name() const MOZ_OVERRIDE { return ""; }
enum WorldTransforPolicy {
ApplyWorldTransform,
DontApplyWorldTransform
};
/**
* Setup World transform matrix.
* Transform will be ignored if it is not PreservesAxisAlignedRectangles
* or has non integer scale
*/
void SetWorldTransform(const gfx::Matrix& aMatrix);
gfx::Matrix& GetWorldTransform(void);
/**
* RAII helper class to add a mask effect with the compositable from aMaskLayer
* to the EffectChain aEffect and notify the compositable when we are done.
@ -292,7 +279,6 @@ private:
*/
void RenderDebugOverlay(const gfx::Rect& aBounds);
void WorldTransformRect(nsIntRect& aRect);
RefPtr<CompositingRenderTarget> PushGroupForLayerEffects();
void PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
@ -313,7 +299,6 @@ private:
RefPtr<gfx::DrawTarget> mTarget;
nsIntRect mTargetBounds;
gfx::Matrix mWorldMatrix;
nsIntRegion mInvalidRegion;
UniquePtr<FPSState> mFPS;

View File

@ -158,7 +158,7 @@ ContainerLayerD3D10::RenderLayer()
}
nsIntRect scissorRect =
RenderTargetPixel::ToUntyped(layerToRender->GetLayer()->CalculateScissorRect(RenderTargetPixel::FromUntyped(oldScissor), nullptr));
RenderTargetPixel::ToUntyped(layerToRender->GetLayer()->CalculateScissorRect(RenderTargetPixel::FromUntyped(oldScissor)));
if (scissorRect.IsEmpty()) {
continue;
}

View File

@ -483,7 +483,7 @@ CompositorD3D11::SetRenderTarget(CompositingRenderTarget* aRenderTarget)
ID3D11RenderTargetView* view = newRT->mRTView;
mCurrentRT = newRT;
mContext->OMSetRenderTargets(1, &view, nullptr);
PrepareViewport(newRT->GetSize(), gfx::Matrix());
PrepareViewport(newRT->GetSize());
}
void
@ -738,7 +738,6 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
void
CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
const Rect* aClipRectIn,
const gfx::Matrix& aTransform,
const Rect& aRenderBounds,
Rect* aClipRectOut,
Rect* aRenderBoundsOut)
@ -816,8 +815,7 @@ CompositorD3D11::EndFrame()
}
void
CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
const gfx::Matrix& aWorldTransform)
CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize)
{
D3D11_VIEWPORT viewport;
viewport.MaxDepth = 1.0f;
@ -833,8 +831,6 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize,
viewMatrix.PreScale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
viewMatrix.PreScale(1.0f, -1.0f);
viewMatrix = aWorldTransform * viewMatrix;
Matrix4x4 projection = Matrix4x4::From2D(viewMatrix);
projection._33 = 0.0f;

View File

@ -100,7 +100,6 @@ public:
*/
virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
const gfx::Rect *aClipRectIn,
const gfx::Matrix& aTransform,
const gfx::Rect& aRenderBounds,
gfx::Rect *aClipRectOut = nullptr,
gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
@ -125,8 +124,7 @@ public:
* Setup the viewport and projection matrix for rendering
* to a window of the given dimensions.
*/
virtual void PrepareViewport(const gfx::IntSize& aSize,
const gfx::Matrix& aWorldTransform) MOZ_OVERRIDE;
virtual void PrepareViewport(const gfx::IntSize& aSize) MOZ_OVERRIDE;
virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE { return true; }

View File

@ -194,7 +194,7 @@ CompositorD3D9::SetRenderTarget(CompositingRenderTarget *aRenderTarget)
RefPtr<CompositingRenderTargetD3D9> oldRT = mCurrentRT;
mCurrentRT = static_cast<CompositingRenderTargetD3D9*>(aRenderTarget);
mCurrentRT->BindRenderTarget(device());
PrepareViewport(mCurrentRT->GetSize(), Matrix());
PrepareViewport(mCurrentRT->GetSize());
}
static DeviceManagerD3D9::ShaderMode
@ -599,7 +599,6 @@ CompositorD3D9::Ready()
void
CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion,
const Rect *aClipRectIn,
const gfx::Matrix& aTransform,
const Rect& aRenderBounds,
Rect *aClipRectOut,
Rect *aRenderBoundsOut)
@ -662,8 +661,7 @@ CompositorD3D9::EndFrame()
}
void
CompositorD3D9::PrepareViewport(const gfx::IntSize& aSize,
const Matrix &aWorldTransform)
CompositorD3D9::PrepareViewport(const gfx::IntSize& aSize)
{
Matrix4x4 viewMatrix;
/*
@ -675,8 +673,6 @@ CompositorD3D9::PrepareViewport(const gfx::IntSize& aSize,
viewMatrix._41 = -1.0f;
viewMatrix._42 = 1.0f;
viewMatrix = Matrix4x4::From2D(aWorldTransform) * viewMatrix;
HRESULT hr = device()->SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4);
if (FAILED(hr)) {

View File

@ -61,7 +61,6 @@ public:
virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
const gfx::Rect *aClipRectIn,
const gfx::Matrix& aTransform,
const gfx::Rect& aRenderBounds,
gfx::Rect *aClipRectOut = nullptr,
gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
@ -72,8 +71,7 @@ public:
virtual void AbortFrame() MOZ_OVERRIDE {}
virtual void PrepareViewport(const gfx::IntSize& aSize,
const gfx::Matrix& aWorldTransform) MOZ_OVERRIDE;
virtual void PrepareViewport(const gfx::IntSize& aSize) MOZ_OVERRIDE;
virtual bool SupportsPartialTextureUpdate() MOZ_OVERRIDE{ return true; }

View File

@ -161,7 +161,7 @@ ContainerLayerD3D9::RenderLayer()
}
nsIntRect scissorRect =
RenderTargetPixel::ToUntyped(layerToRender->GetLayer()->CalculateScissorRect(RenderTargetPixel::FromUntyped(oldScissor), nullptr));
RenderTargetPixel::ToUntyped(layerToRender->GetLayer()->CalculateScissorRect(RenderTargetPixel::FromUntyped(oldScissor)));
if (scissorRect.IsEmpty()) {
continue;
}

View File

@ -801,7 +801,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
// Instruct the LayerManager to update its render bounds now. Since all the orientation
// change, dimension change would be done at the stage, update the size here is free of
// race condition.
mLayerManager->UpdateRenderBounds(aTargetConfig.clientBounds());
mLayerManager->UpdateRenderBounds(aTargetConfig.naturalBounds());
mLayerManager->SetRegionToClear(aTargetConfig.clearRegion());
mCompositionManager->Updated(aIsFirstPaint, aTargetConfig);

View File

@ -49,7 +49,6 @@ namespace layers {
struct TargetConfig {
nsIntRect naturalBounds;
ScreenRotation rotation;
nsIntRect clientBounds;
ScreenOrientation orientation;
nsIntRegion clearRegion;
};

View File

@ -64,7 +64,7 @@ public:
{}
void Begin(const nsIntRect& aTargetBounds, ScreenRotation aRotation,
const nsIntRect& aClientBounds, dom::ScreenOrientation aOrientation)
dom::ScreenOrientation aOrientation)
{
mOpen = true;
mTargetBounds = aTargetBounds;
@ -76,7 +76,6 @@ public:
mRotationChanged = true;
}
mTargetRotation = aRotation;
mClientBounds = aClientBounds;
mTargetOrientation = aOrientation;
}
void MarkSyncTransaction()
@ -141,7 +140,6 @@ public:
ShadowableLayerSet mMutants;
nsIntRect mTargetBounds;
ScreenRotation mTargetRotation;
nsIntRect mClientBounds;
dom::ScreenOrientation mTargetOrientation;
bool mSwapRequired;
@ -186,12 +184,11 @@ ShadowLayerForwarder::~ShadowLayerForwarder()
void
ShadowLayerForwarder::BeginTransaction(const nsIntRect& aTargetBounds,
ScreenRotation aRotation,
const nsIntRect& aClientBounds,
dom::ScreenOrientation aOrientation)
{
NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
NS_ABORT_IF_FALSE(mTxn->Finished(), "uncommitted txn?");
mTxn->Begin(aTargetBounds, aRotation, aClientBounds, aOrientation);
mTxn->Begin(aTargetBounds, aRotation, aOrientation);
}
static PLayerChild*
@ -635,7 +632,6 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
TargetConfig targetConfig(mTxn->mTargetBounds,
mTxn->mTargetRotation,
mTxn->mClientBounds,
mTxn->mTargetOrientation,
aRegionToClear);

View File

@ -176,7 +176,6 @@ public:
*/
void BeginTransaction(const nsIntRect& aTargetBounds,
ScreenRotation aRotation,
const nsIntRect& aClientBounds,
mozilla::dom::ScreenOrientation aOrientation);
/**

View File

@ -49,17 +49,10 @@ public:
* composition and the render was successful. Return false to fall
* back on the GPU.
*
* |aWorldTransform| must be applied to |aRoot|'s subtree when
* rendering to the framebuffer. This is a global transform on the
* entire scene, defined in GL space. If the Composer2D
* implementation is unable to honor the transform, it should return
* false.
*
* Currently, when TryRender() returns true, the entire framebuffer
* must have been rendered.
*/
virtual bool TryRender(Layer* aRoot, const gfx::Matrix& aWorldTransform,
bool aGeometryChanged) = 0;
virtual bool TryRender(Layer* aRoot, bool aGeometryChanged) = 0;
};
} // namespace layers

View File

@ -56,7 +56,7 @@ CompositingRenderTargetOGL::BindRenderTarget()
}
}
mCompositor->PrepareViewport(mInitParams.mSize, mTransform);
mCompositor->PrepareViewport(mInitParams.mSize);
}
}
@ -92,7 +92,7 @@ CompositingRenderTargetOGL::InitializeImpl()
NS_ERROR(msg.get());
}
mCompositor->PrepareViewport(mInitParams.mSize, mTransform);
mCompositor->PrepareViewport(mInitParams.mSize);
mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height);
if (mInitParams.mInit == INIT_MODE_CLEAR) {
mGL->fClearColor(0.0, 0.0, 0.0, 0.0);

View File

@ -67,7 +67,6 @@ public:
GLuint aTexure, GLuint aFBO)
: CompositingRenderTarget(aOrigin)
, mInitParams()
, mTransform()
, mCompositor(aCompositor)
, mGL(aCompositor->gl())
, mTextureHandle(aTexure)
@ -82,12 +81,10 @@ public:
*/
static TemporaryRef<CompositingRenderTargetOGL>
RenderTargetForWindow(CompositorOGL* aCompositor,
const gfx::IntSize& aSize,
const gfx::Matrix& aTransform)
const gfx::IntSize& aSize)
{
RefPtr<CompositingRenderTargetOGL> result
= new CompositingRenderTargetOGL(aCompositor, gfx::IntPoint(0, 0), 0, 0);
result->mTransform = aTransform;
result->mInitParams = InitParams(aSize, 0, INIT_MODE_NONE);
result->mInitParams.mStatus = InitParams::INITIALIZED;
return result.forget();
@ -146,10 +143,6 @@ public:
return gfx::SurfaceFormat::UNKNOWN;
}
const gfx::Matrix& GetTransform() {
return mTransform;
}
#ifdef MOZ_DUMP_PAINTING
virtual TemporaryRef<gfx::DataSourceSurface> Dump(Compositor* aCompositor);
#endif
@ -162,7 +155,6 @@ private:
void InitializeImpl();
InitParams mInitParams;
gfx::Matrix mTransform;
CompositorOGL* mCompositor;
GLContext* mGL;
GLuint mTextureHandle;

View File

@ -567,8 +567,7 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
}
void
CompositorOGL::PrepareViewport(const gfx::IntSize& aSize,
const Matrix& aWorldTransform)
CompositorOGL::PrepareViewport(const gfx::IntSize& aSize)
{
// Set the viewport correctly.
mGLContext->fViewport(0, 0, aSize.width, aSize.height);
@ -579,9 +578,7 @@ CompositorOGL::PrepareViewport(const gfx::IntSize& aSize,
// drawing directly into the window's back buffer, so this keeps things
// looking correct.
// XXX: We keep track of whether the window size changed, so we could skip
// this update if it hadn't changed since the last call. We will need to
// track changes to aTransformPolicy and aWorldTransform for this to work
// though.
// this update if it hadn't changed since the last call.
// Matrix to transform (0, 0, aWidth, aHeight) to viewport space (-1.0, 1.0,
// 2, 2) and flip the contents.
@ -600,8 +597,6 @@ CompositorOGL::PrepareViewport(const gfx::IntSize& aSize,
viewMatrix.PreTranslate(mRenderOffset.x, mRenderOffset.y);
}
viewMatrix = aWorldTransform * viewMatrix;
Matrix4x4 matrix3d = Matrix4x4::From2D(viewMatrix);
matrix3d._33 = 0.0f;
@ -705,7 +700,6 @@ CompositorOGL::ClearRect(const gfx::Rect& aRect)
void
CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
const Rect *aClipRectIn,
const gfx::Matrix& aTransform,
const Rect& aRenderBounds,
Rect *aClipRectOut,
Rect *aRenderBoundsOut)
@ -723,7 +717,6 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
rect = gfx::Rect(aRenderBounds.x, aRenderBounds.y, aRenderBounds.width, aRenderBounds.height);
}
rect = aTransform.TransformBounds(rect);
if (aRenderBoundsOut) {
*aRenderBoundsOut = rect;
}
@ -758,8 +751,7 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion,
mCurrentRenderTarget =
CompositingRenderTargetOGL::RenderTargetForWindow(this,
IntSize(width, height),
aTransform);
IntSize(width, height));
mCurrentRenderTarget->BindRenderTarget();
#ifdef DEBUG
mWindowRenderTarget = mCurrentRenderTarget;
@ -1325,7 +1317,7 @@ CompositorOGL::EndFrame()
mWidget->GetBounds(rect);
}
RefPtr<DrawTarget> target = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(rect.width, rect.height), SurfaceFormat::B8G8R8A8);
CopyToTarget(target, nsIntPoint(), mCurrentRenderTarget->GetTransform());
CopyToTarget(target, nsIntPoint(), Matrix());
WriteSnapshotToDumpFile(this, target);
}
@ -1334,7 +1326,7 @@ CompositorOGL::EndFrame()
mFrameInProgress = false;
if (mTarget) {
CopyToTarget(mTarget, mTargetBounds.TopLeft(), mCurrentRenderTarget->GetTransform());
CopyToTarget(mTarget, mTargetBounds.TopLeft(), Matrix());
mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
mCurrentRenderTarget = nullptr;
return;

Some files were not shown because too many files have changed in this diff Show More