thanks to the author

http://blog.csdn.net/tifa_ai/article/details/77184015

webidl是gecko层写的接口,供gaia调用。

写一个这样的接口,需要写接口文件,实现类,控制调用方式

1.写接口文件,接口文件以webidl为后缀,必须放到dom/webidl目录下面,而且需要在dom/webidl/moz.build中加入文件名,以使编译器能够看见它的存在。

注意,接口名字需要与实现类的头文件名字、cpp文件名字一致。

Gecko/dom/webidl/MozAaaTest.webidl

interface MozAaaTest

{

void setTestData();

};

在dom/webidl/moz.build中添加文件名时,需要注意,该文件中WEBIDL_FILES下的文件名是按字母顺序排序的,如果不按字母顺序添加文件名,会报错。

编写moz.build的例子如下

WEBIDL_FILES =[

...

'MozAaaTest.webidl',

...

]

2写实现类,

在gecko/dom下新建文件夹aaatest,接着把所有需要的模块文件都放到这个文件夹里面,最简单的框架就是

l  MozAaaTest.h

l  MozAaaTest.cpp

l  moz.build

下面分别看看这三个文件的写法

2.1头文件MozAaaTest.h

#ifndef mozilla_dom_aaatest_MozAaaTest_h

#define mozilla_dom_aaatest_MozAaaTest_h

#include "nsWrapperCache.h"

#include "nsPIDOMWindow.h"

namespace mozilla{

namespace dom{

namespace aaatest{

class MozAaaTest final

:public nsISupports

,public nsWrapperCache

{

public:

NS_DECL_CYCLE_COLLECTING_ISUPPORTS

NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MozAaaTest)

MozAaaTest(nsPIDOMWindow* aWindow); //构造函数

virtual~MozAaaTest();//析构函数

nsPIDOMWindow* GetParentObject()const{return mWindow;}

virtual JSObject* WrapObject(JSContext* aCx) override;

/* Impliment the WebIDL interface begin*/

NS_IMETHODIMP SetTestData();

/* Imppliment the WebIDL interface end*/

private:

protected:

nsCOMPtr<nsPIDOMWindow> mWindow;

};

}// namespace aaatest

}// namespace dom

}// namespace mozilla

#endif

解析:

(1)预编译防止重复引用

#ifndef mozilla_dom_aaatest_MozAaaTest_h

#define mozilla_dom_aaatest_MozAaaTest_h

...

#endif

(2)命名空间必须在mozilla ::dom下面

namespace mozilla{

namespace dom{

namespace aaatest{

...

}// namespace aaatest

}// namespace dom

}// namespace mozilla

(3)继承关系

函数继承nsISupports和nsWrapperCache。注意,如果要继承这两个接口,就需要把nsISupports放到nsWrapperCache前面

nsISupports
nsISupports是所有的XPCOM都需要继承的接口,nsISupports提供三个方法。第一个方法QueryInterface可以实时的根据接口uuid获得接口指针,从而利用指针调用接口方法;而AddRef与Release增加了实例的计数功能

nsWrapperCache
如果你的接口不继承别的接口,就需要继承nsWrapperCache,nsWrapperCache把你的类挂载到cycle collector,这样cycle collector就会对你的wrapper cache进行跟踪处理。
(4)GetParentObject

如果你的接口不继承其他类,就需要执行GetParentObject,这样每一个webidl object就会关联到返回的特定窗口。

nsPIDOMWindow* GetParentObject()const{return mWindow;}

(5)WrapObject。头文件这里只是定义了一下,具体实现在cpp文件

virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;

(6)接口函数

这里的函数名是从webidl文件里面得来的,需要注意的是函数名首字母变为大写

NS_IMETHODIMP SetTestData();

2.2 CPP文件的写法

cpp文件的编写参照webidl接口文件和H文件,实现其中申明的函数。需要注意的是 MozAaaTestBinding.h是生成的文件,必须要包含,不然报错。

#include "MozAaaTest.h"

#include "mozilla/dom/MozAaaTestBinding.h"

using  namespace mozilla;

using namespace mozilla::dom;

using namespace mozilla::dom::aaatest;

// cycle collector与isupports的宏定义

NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozAaaTest)

NS_INTERFACE_MAP_ENTRY(nsISupports)

NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY

NS_INTERFACE_MAP_END

NS_IMPL_CYCLE_COLLECTING_ADDREF(MozAaaTest)

NS_IMPL_CYCLE_COLLECTING_RELEASE(MozAaaTest)

NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MozAaaTest, mWindow)

// 构造函数与析构函数的实现

MozAaaTest::MozAaaTest(nsPIDOMWindow* aWindow)

: mWindow(aWindow)

{

printf("aiyan enter MozAaaTest\n");

}

MozAaaTest::~MozAaaTest()

{

printf("aiyan enter ~MozAaaTest\n");

}

// WrapObject的实现

JSObject*

MozAaaTest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)

{

return MozAaaTestBinding::Wrap(aCx,this, JS::Handle<JSObject*> aGivenProto);

}

// webidl中定义的接口的实现

NS_IMETHODIMP MozAaaTest::SetTestData(){

printf("aiyan enter SetTestData:isSuccessed\n");

return NS_OK;

}

2.3 moz.build的编写

同样的,每个中括号中的文件名都必须按字母顺序排列,另外,FINAL_LIBRARY ='xul'这个库文件必须加上,不然会报错。

EXPORTS.mozilla.dom.aaatest+=[

'MozAaaTest.h',

]

SOURCES +=[

'MozAaaTest.cpp',

]

LOCAL_INCLUDES +=[

'/dom/aaatest',

]

// #

FINAL_LIBRARY ='xul'

补充说明

(1)文件夹aaatest的添加需要在dom/moz.build中添加路径

DIRS +=['aaatest',]

(2)配置文件dom/bindings/Bindings.conf,为接口的执行添加入口

'MozAaaTest':{

'nativeType':'mozilla::dom::aaatest::MozAaaTest',

},

括号中不添加信息,表示是默认值;

如果你的C++不是mozilla::dom::MyInterface的格式存在,那么需要在nativeType中添加正确的路径,如mozilla::dom::aaatest::MozAaaTest;

如果你的头文件路径不与nativeType中信息一一对应,即如不是mozilla/dom/aaatest/MozAaaTest.h,那么你需要在headerFile中添加正确的头文件路径。

3 模块添加完了,要怎么调用了,最简单的方式就是通过navigator来调用。因为navigator在gaia层的调用关系架构已经搭好。

同样,修改navigator需要修改的文件包括:

l gecko/dom/webidl/Navigator.webidl

l gecko/dom/base/Navigator.h

l gecko/dom/base/Navigator.cpp

修改的原理是在Navigator.webidl中添加一个属性,然后在cpp中去实现这个属性,给我们的模块实例化。

3.1Navigator.webidl

给Navigator添加了一个只读的属性。这里有个权限的检查,后面会介绍我们需要加权限,才能在gaia去用添加的接口。

partial interface Navigator{

[Throws,CheckAnyPermissions="aaatest"]

readonly attribute MozAaaTest mozAaaTest;

};

3.2头文件Navigator.h

在头文件中申明了属性的实现函数GetMozAaaTest,另外申明了一个成员变量mAaaTest用来保存MozAaaTest的实例

// 需要使用到MozAaaTest类

namespace aaatest{

class MozAaaTest;

}

class Navigator MOZ_FINAL:public nsIDOMNavigator

,public nsIMozNavigatorNetwork

,public nsWrapperCache

{

public:

...

// 属性的实现

aaatest::MozAaaTest* GetMozAaaTest(ErrorResult& aRv);

private:

...

// 存储MozAaaTest的实例

nsRefPtr<aaatest::MozAaaTest> mAaaTest;

}

3.2CPP文件的添加

从属性的实现函数可以看出来,gaia初始化Navigator.mozAaaTest,就会调用GetMozAaaTest函数,返回MozAaaTest的实例mAaaTest,如果实例没有被初始化,就调用MozAaaTest的构造函数进行初始化。

#include "mozilla/dom/aaatest/MozAaaTest.h"

using namespace aaatest;

NS_IMPL_CYCLE_COLLECTION_UNLINK(mAaaTest)

// 属性的实现函数

aaatest::MozAaaTest*

Navigator::GetMozAaaTest(ErrorResult& aRv)

{

LOG("aiyan GetMozAaaTest");

if(!CheckPermission("aaatest")){

LOG("aiyan GetMozAaaTest CheckPermission return false");

aRv.Throw(NS_ERROR_UNEXPECTED);

returnnullptr;

}

if(!mAaaTest){

mAaaTest =new aaatest::MozAaaTest(mWindow);

}

else{

LOG("mAaaTest exist just return");

}

return mAaaTest;

}

// 资源释放

void

Navigator::Invalidate()

{

...

if(mAaaTest){

mAaaTest =nullptr;

}

}

4gaia的调用,桥搭好了,现在看看怎么掉

要调用webidl首先需要有一个权限,这个就是我们在前面用到的“aaatest”权限,接着需要在app的manifest.webapp中加入权限,最后才能使用webidl接口。
注意,想要gaia能调用新加入的webidl,需要删除out目录,整编全部代码,不然gaia会找不到接口。
定义权限,在gecko/dom/apps/PermissionsTable.jsm中加入代码

this.PermissionsTable= {

"aaatest":{

app: DENY_ACTION,

privileged: DENY_ACTION,

certified: ALLOW_ACTION

},

}

给app加入权限
在gaia/apps/system/manifest.webapp中加入代码

"permissions":{

...

"aaatest":{},

...

},

使用例子

HardwareButtonsBaseState.prototype.process=function(type){

switch(type){

case'enter-button-press':

dump("aiyan "+type);

var _aaaTest=navigator.mozAaaTest;

_aaaTest.setTestData();

...

}

}

注意这里必须先调用mozAaaTest的构造函数,再利用mozAaaTest的实例_aaaTest去调用webidl中定义的函数,这里的函数名必须与webidl中的保持一致,而不是在cpp中的函数名。

1.1

添加webidl 的过程
一添加webidl 文件
Gecko/dom/webidl/MozAaaTest.webidl
Gecko/dom/webidl/moz.build
二添加实现模块
gecko/dom/aaatest/
l  MozAaaTest.h
l  MozAaaTest.cpp
l  moz.build
配置文件gecko/dom/bindings/Bindings.conf,为接口的执行添加入口
dom/bindings/Bindings.conf
三添加调通路
l gecko/dom/webidl/Navigator.webidl
l gecko/dom/base/Navigator.h
l gecko/dom/base/Navigator.cpp
四gaia 调用
gecko/dom/apps/PermissionsTable.jsm
gaia/apps/system/manifest.webapp

如果要从gaia调用已经有的webidl需要满足以下

(1)需要对应APP的在manifest.webapp里面添加权限

如:

"permissions":{

"voicemail":{}

}

改完manifest.webapp最重要的是要全编整个gaia层,单编模块不会起作用:make reset-gaia

(2)如果这样还不能起作用,检查一下调用的app是个什么样的app

在对应的manifest.webapp下,可以看到关键字

“type”:"ceitified"

在gecko/dom/apps/PermissionsTable.jsm里面

可以搜“voicemail”

“voicemail”:{

app:DENY_ACTION

trusted:DENY_ACTION

privileged:DENY_ACTION

certified:ALLOW_ACTION

}

可以看看你的app是否有voicemail这个权限

(3)最后如果还不行,需要看看你调用的方式是否正确,或者接口是否存在。

https://blog.csdn.net/zyt2138/article/details/44955897

向FFOS添加webidl

webidl简介

Web IDL(Interface Definition Language,接口定义语言)该规范定义了一个OMG IDL 3.0的语法子集,用来规范定义的接口。Web IDL 是一个具有多种功能的IDL 变量,便于规范Web平台中的常用脚本对象的操作。

webidl xpidl ipdl 区别

webidl:接口定义文件后缀为.webidl,用于定义webapi,比如gecko/dom/webidl/FMRadio.webidl

xpidl:接口定义文件后缀为.idl,用于定义xpcom组件接口,比如gecko/dom/wifi/nsIWifi.idl

ipdl:接口定义文件后缀为.ipdl,用于定义进程间通信接口,帮助gecko中webidl接口的实现,比如gecko/dom/fmradio/ipc/PFMRadio.ipdl

Gecko内部使用最多的还是基于XPConnect上的DOM Bindings,使用ScriptableHelper来帮助把XPCOM组件暴露在JavaScript上,但这种方式有一些内存管理和速度上的缺点,并且XPIDL(XPCOM界面定义语言)与WebIDL(Web界面定义语言)在语义上有一定的不同,会使各种加速方法和处理语义问题的 Wrapper需要手工地针对不同API进行修改。

因为XPIDL的一些问题,Firefox OS里还提供一种DOM bindings的方法。由于这个问题是在法国巴黎首次讨论的,所以最早被称为“Paris Bindings”。因为这些DOM API实际上不使用XPCOM的许多功能,所以它的速度比原有的XPConnect会快许多。通过WebIDL DOM bindings可以省略掉一些虚函数的开销,还可以节省掉XPCOM处理线程安全的花费,透过新的JIT技术,从JavaScript可以调用DOM API,甚至直接调用C++的实现。未来描述DOM API的语言可能统一为WebIDL。

http://www.programmer.com.cn/15789/

如何向ffos 添加JS 实现的webidl

1.      编写webidl文件

在gecko/dom/webidl 目录下面编写webidl文件

/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */

/* 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/.

*/

[JSImplementation="@mozilla.org/mytest;1",

NavigatorProperty="mytest"

]

interface MyTest {

DOMString sayHello();

};

‘@mozilla.org/mytest;1 ‘                   contractname,之后和js实现绑定。

NavigatorProperty             设置为navigator的属性

2.      编写manifest文件

在gecko/dom/mytest/ 中创建 MyTest.manifest 文件。

在MyTest.manifest文件中,将webidl接口与javascript实现绑定。

MyTest.manifest 文件如下:

component {50CD146F-75EE-4C5E-88FA-FB3871362156} MyTest.js

contract @mozilla.org/mytest;1 {50CD146F-75EE-4C5E-88FA-FB3871362156}

定义 一个component,然后将其与 @mozilla.org/mytest;1绑定

3.      编写js 文件,MyTest.js

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

function MyTest(){

dump("zyt mytest constractor");

}

MyTest.prototype = {

classDescription: "zyt test xpcom",

classID: Components.ID("{50CD146F-75EE-4C5E-88FA-FB3871362156}"),

contractID: "@mozilla.org/mytest;1",

QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),

sayHello : function(){

dump("this is zyt test to say hello");

return"this is my first webidl test";

},

};

this.NSGetFactory= XPCOMUtils.generateNSGetFactory([MyTest]);

4.      创建dom/mytest/moz.build 文件

# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-

# vim: set filetype=python:

# 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/.

EXTRA_COMPONENTS += [

'MyTest.js',

'MyTest.manifest',

]

注:该文件必须按字母序排列。否则编译出错。

5.      修改dom/moz.build文件

diff --git a/dom/moz.build b/dom/moz.build

--- a/dom/moz.build

+++ b/dom/moz.build

@@ -81,6 +81,7 @@ PARALLEL_DIRS += [

'webidl',

'xbl',

'xslt',

+    'mytest',

]

if CONFIG['OS_ARCH'] == 'WINNT':

6.      添加到Firefox OS

修改 gecko/b2g/installer/package-manifest.in:

;my test

@BINPATH@/components/MyTest.js

@BINPATH@/components/MyTest.manifest

firefoxos :add a webidl,and use相关推荐

  1. firefoxos :add ipdl

    thanks to the author http://blog.csdn.net/tifa_ai/article/details/77246448 ipdl就是用一种安全的方式实现进程或线程间通信, ...

  2. cordova 学习笔记

    0.sdk安装 http://spring.io/guides/gs/android/ 1.安装(node.js 需要安装https://nodejs.org/) on OS X and Linux: ...

  3. Java Calendar.add()方法的使用,参数含义。指定时间差。

    cal.add()方法中的参数含义: 第一个参数如果是1则代表的是对年份操作,2是对月份操作,3是对星期操作,5是对日期操作,11是对小时操作,12是对分钟操作,13是对秒操作,14是对毫秒操作. 第 ...

  4. Docker 入门系列(7)- Dockerfile 使用(FROM、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、WORKDIR)

    Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 来快速创建自定义的镜像. 1. 基本结构 Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行. ...

  5. git add . 之后 想执行回滚操作(git add 到本地仓库的代码回滚到没有add 之前的操作)

    git add 到本地仓库的代码回滚到没有add 之前的操作 ,如果git 非常熟悉临时忘记了命令 回滚单个文件的命令:git restore --staged  xx文件名 回滚所有add 的文件直 ...

  6. Multiple substitutions specified in non-positional format; did you mean to add the formatted=”false”

    make 编译android代码的出现这样的错误 这个问题可能是跟android 的版本有关系就是xml 中的String.xml文件的文字使用%s 无法识别引起的, 不过有些版本可以识别 下面的就有 ...

  7. Kotlin 使用list.add 时候报错的处理方法

    在Kotlin 中 使用list.add 方法的时候出现报错例如下面的现象 这个时候处理的方法就是把List 更换为MutableList 这样就不会报错了 下面是处理之后的.

  8. Can't add more than 2 views to a ViewSwitcher

    最近使用到  TextSwitcher 来实现文字上下轮播的效果,出现了 Can't add more than 2 views to a ViewSwitcher 看了下源码 /*** {@inhe ...

  9. List 数据add进去的是一个bean 的时候删除数据的方法

    这个时候要删除数据,也是用到add 进 list 里面的bean 然后使用for 循环对应里面的数据的方法 例如: selectList.remove(findSeatInfoBean(xx, xx) ...

最新文章

  1. wpf异形按钮,定制异型按钮在WPF
  2. 定点量化误差python仿真.零极点(1)
  3. 网站优化中能有效提升网站打开速度的技巧有哪些?
  4. tl wn322g linux驱动下载,TL-WN322G+ 2.0_WN422G+ 2.0驱动程序
  5. 如果redis哨兵宕机了怎么办_Spring集成Redis做缓存,Redis宕机时Spring处理的问题
  6. Rethinking算法实习生
  7. 测试发送消息和接受消息
  8. 【HTML】输入密码访问
  9. CentOS 7 安装及设置
  10. citrixreceiver云桌面系统_CStack xView桌面云平台与方德操作系统完成兼容性认证
  11. ubuntu20.04系统 ros noetic下安裝orbslam2
  12. matlab 解析 mnist 数据集
  13. 一大波Java来袭(四)String类、StringBuilder类、StringBuffer类对照
  14. linux里用cmake安装的软件要怎么卸载?
  15. 硬核AI开发者大会来袭:飞桨发布开源框架2.0 RC版、生物计算平台PaddleHelix「螺旋桨」...
  16. Android10.0应用图标隐藏方案(7.0-10.0)
  17. IP签名档HTML版本源码 显示精准定位
  18. kafka添加安全验证配置
  19. 视频教程-项目1——无线自助点餐平台-Java
  20. Virtualbox源码分析16 APIC虚拟化1 APIC概念和初始化

热门文章

  1. python 实现实时语音对讲
  2. python 抓取头条街拍图片
  3. js 万年历农历转阳历 方法_JS实现带阴历的日历功能详解
  4. 如何修改微信公众号内部网页的头部标签内容
  5. 识别文字的软件哪个好呢?不如试试这几款
  6. 从钉钉后台API获取企业通信录
  7. 云计算工程师面试题集锦,云计算面试题及答案
  8. 论文阅读笔记--Federated Continual Learning with Weighted Inter-client Transfer
  9. 网站防篡改小工具使用方法
  10. qt学习之旅--MinGW编译FFmpeg(32bit)