firefoxos :add a webidl,and use
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相关推荐
- firefoxos :add ipdl
thanks to the author http://blog.csdn.net/tifa_ai/article/details/77246448 ipdl就是用一种安全的方式实现进程或线程间通信, ...
- cordova 学习笔记
0.sdk安装 http://spring.io/guides/gs/android/ 1.安装(node.js 需要安装https://nodejs.org/) on OS X and Linux: ...
- Java Calendar.add()方法的使用,参数含义。指定时间差。
cal.add()方法中的参数含义: 第一个参数如果是1则代表的是对年份操作,2是对月份操作,3是对星期操作,5是对日期操作,11是对小时操作,12是对分钟操作,13是对秒操作,14是对毫秒操作. 第 ...
- Docker 入门系列(7)- Dockerfile 使用(FROM、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、WORKDIR)
Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 来快速创建自定义的镜像. 1. 基本结构 Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行. ...
- git add . 之后 想执行回滚操作(git add 到本地仓库的代码回滚到没有add 之前的操作)
git add 到本地仓库的代码回滚到没有add 之前的操作 ,如果git 非常熟悉临时忘记了命令 回滚单个文件的命令:git restore --staged xx文件名 回滚所有add 的文件直 ...
- Multiple substitutions specified in non-positional format; did you mean to add the formatted=”false”
make 编译android代码的出现这样的错误 这个问题可能是跟android 的版本有关系就是xml 中的String.xml文件的文字使用%s 无法识别引起的, 不过有些版本可以识别 下面的就有 ...
- Kotlin 使用list.add 时候报错的处理方法
在Kotlin 中 使用list.add 方法的时候出现报错例如下面的现象 这个时候处理的方法就是把List 更换为MutableList 这样就不会报错了 下面是处理之后的.
- Can't add more than 2 views to a ViewSwitcher
最近使用到 TextSwitcher 来实现文字上下轮播的效果,出现了 Can't add more than 2 views to a ViewSwitcher 看了下源码 /*** {@inhe ...
- List 数据add进去的是一个bean 的时候删除数据的方法
这个时候要删除数据,也是用到add 进 list 里面的bean 然后使用for 循环对应里面的数据的方法 例如: selectList.remove(findSeatInfoBean(xx, xx) ...
最新文章
- wpf异形按钮,定制异型按钮在WPF
- 定点量化误差python仿真.零极点(1)
- 网站优化中能有效提升网站打开速度的技巧有哪些?
- tl wn322g linux驱动下载,TL-WN322G+ 2.0_WN422G+ 2.0驱动程序
- 如果redis哨兵宕机了怎么办_Spring集成Redis做缓存,Redis宕机时Spring处理的问题
- Rethinking算法实习生
- 测试发送消息和接受消息
- 【HTML】输入密码访问
- CentOS 7 安装及设置
- citrixreceiver云桌面系统_CStack xView桌面云平台与方德操作系统完成兼容性认证
- ubuntu20.04系统 ros noetic下安裝orbslam2
- matlab 解析 mnist 数据集
- 一大波Java来袭(四)String类、StringBuilder类、StringBuffer类对照
- linux里用cmake安装的软件要怎么卸载?
- 硬核AI开发者大会来袭:飞桨发布开源框架2.0 RC版、生物计算平台PaddleHelix「螺旋桨」...
- Android10.0应用图标隐藏方案(7.0-10.0)
- IP签名档HTML版本源码 显示精准定位
- kafka添加安全验证配置
- 视频教程-项目1——无线自助点餐平台-Java
- Virtualbox源码分析16 APIC虚拟化1 APIC概念和初始化