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 collectorisupports的宏定义

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,用于定义进程间通信接口,帮助geckowebidl接口的实现,比如gecko/dom/fmradio/ipc/PFMRadio.ipdl

Gecko内部使用最多的还是基于XPConnect上的DOM Bindings,使用ScriptableHelper来帮助把XPCOM组件暴露在JavaScript上,但这种方式有一些内存管理和速度上的缺点,并且XPIDLXPCOM界面定义语言)与WebIDLWeb界面定义语言)在语义上有一定的不同,会使各种加速方法和处理语义问题的 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

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值