[Firefox OS][B2G][FxOS] gecko層への機能拡張について


Firefox OSとは、スマートフォンとタブレットで動作するオープンソースOSです。
簡単に説明致しますと、以下のような構成となっております。

レイヤー名 主な機能 主な使用言語
Gaia アプリ, UI HTML, JavaScript
Gecko ランタイム JavaScript, C++
Gonk OS, HAL C++

アプリ層の開発に関しては検索をかければ幾つかヒットします。
そこでこの記事では、ランタイム層に関して新たに機能を実装し、
確認を行う手順について記載します。

大まかな手順
以下の手順に関して、順を追って説明してゆきます。
・環境準備
・Gecko層へソースファイル実装
・Gaia層へソースファイル実装
・動作確認

環境準備
アプリのみを作成する場合は必要ありませんが、
ライブラリや実行環境に手を加える場合、
ソースファイルを取得し、変更を加える必要があります。
環境構築及び取得方法は以下のサイトに詳しく記載されているので参照してください。
https://developer.mozilla.org/ja/docs/Mozilla/Boot_to_Gecko/Building_and_installing_Firefox_OS

Gecko層へソースファイル実装
デバイス等に依存しない、webでの動作のみのアプリを作る場合であれば、
Gecko層への実装は必要ありません。
また、元々FirefoxOS上で準備されているWebAPIを使用してアプリを作る場合についても、Gecko層への実装は必要ありません。
Gecko層に対して新たな機能を実装し、アプリ層から呼び出したい場合に、
以下の手順を踏む必要があります。
以下では例として、足し算をして結果を返すプログラムを作成します。

1.必要ファイル
以下のファイルを新規作成/修正する必要があります。
[新規作成ファイル]
・/gecko/dom/myCalc
・/gecko/dom/myCalc/Makefile.in
・/gecko/dom/myCalc/MyCalcManager.js
・/gecko/dom/myCalc/MyCalcManager.manifest
・/gecko/dom/myCalc/nsIDOMMyCalcManager.idl

[修正ファイル]
・/gecko/dom/Makefile.in
・/gecko/dom/dom-config.mk
・/gecko/b2g/installer/package-manifest.in

/gecko/dom/myCalc/Makefile.in

DEPTH       = @DEPTH@
topsrcdir   = @top_srcdir@
srcdir      = @srcdir@
VPATH       = @srcdir@

include $(DEPTH)/config/autoconf.mk

MODULE              = dom
XPIDL_MODULE        = dom_mycalc
LIBRARY_NAME        = dommycalc_s
LIBXUL_LIBRARY      = 1
FORCE_STATIC_LIB    = 1
GRE_MODULE          = 1
FAIL_ON_WARNINGS := 1

include $(topsrcdir)/dom/dom-config.mk

EXPORTS_NAMESPACES = mozilla/dom/mycalc

EXTRA_COMPONENTS =       \
  MyCalcManager.js       \
  MyCalcManager.manifest \
  $(NULL)

EXTRA_JS_MODULES = \
  $(NULL)

XPIDLSRCS =               \
  nsIDOMMyCalcManager.idl \
  $(NULL)

EXPORTS_mozilla/dom/mycalc = \
  $(NULL)

CPPSRCS =             \
  $(NULL)

include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk

XPIDL_FLAGS += \
  -I$(topsrcdir)/dom/interfaces/base \
  $(NULL)

/gecko/dom/myCalc/MyCalcManager.js

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

"use strict";

/* static functions */
const DEBUG = true;

function debug(aStr) {
  if (DEBUG)
    dump("MyCalcManager: " + aStr + "\n");
}

const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;

Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");

const MYCALCMANAGER_CONTRACTID = "@mozilla.org/MyCalcManager;1";
const MYCALCMANAGER_CID        = Components.ID("{682f9ea0-8a24-11e2-9f07-000c2921e8d6}");
const nsIDOMMozMyCalcManager   = Ci.nsIDOMMozMyCalcManager;
const nsIClassInfo             = Ci.nsIClassInfo;

function MyCalcManager()
{
  debug("Constructor");
}

MyCalcManager.prototype = {

  __proto__: DOMRequestIpcHelper.prototype,

  classID : MYCALCMANAGER_CID,

  QueryInterface : XPCOMUtils.generateQI([nsIDOMMozMyCalcManager, Ci.nsIDOMGlobalPropertyInitializer]),

  classInfo : XPCOMUtils.generateCI({ classID: MYCALCMANAGER_CID,
                                      contractID: MYCALCMANAGER_CONTRACTID,
                                      classDescription: "MyCalcManager",
                                      interfaces: [nsIDOMMozMyCalcManager],
                                      flags: nsIClassInfo.DOM_OBJECT }),

  add: function add(a, b) {
    debug("add()");
    debug(a);
    debug(b);
    return a + b;
  },

  receiveMessage: function receiveMessage(aMessage) {
    debug("receiveMessage(): " + aMessage.name);

    let json = aMessage.json;
    let request = this.getRequest(json.requestId);

    if (!request) {
      debug("No request stored! " + json.requestId);
      return;
    }

    switch (aMessage.name) {
      case "MyCalcManager:Add:Return:OK":
        Services.DOMRequest.fireSuccess(request, json.id);
        break;
      default:
        debug("Wrong message: " + aMessage.name);
        break;
    }
    this.removeRequest(json.requestId);
   },

  // nsIDOMGlobalPropertyInitializer implementation
  init: function init(aWindow) {
    debug("init()");

    // Set navigator.mozAlarms to null.
//    if (!Services.prefs.getBoolPref("dom.mozmycalc.enabled"))
//      return null;

    this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);

    // Add the valid messages to be listened.
    this.initHelper(aWindow, ["MyCalcManager:Add:Return:OK"]);

    // Get the manifest URL if this is an installed app
    let appsService = Cc["@mozilla.org/AppsService;1"]
                        .getService(Ci.nsIAppsService);
 //   this._pageURL = principal.URI.spec;
 //   this._manifestURL = appsService.getManifestURLByLocalId(principal.appId);
    this._window = aWindow;
  },

  // Called from DOMRequestIpcHelper.
  uninit: function uninit() {
    debug("uninit()");
  },
}

this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MyCalcManager])

/gecko/dom/myCalc/MyCalcManager.manifest

component {682f9ea0-8a24-11e2-9f07-000c2921e8d6} MyCalcManager.js
contract @mozilla.org/MyCalcManager;1 {682f9ea0-8a24-11e2-9f07-000c2921e8d6}
category JavaScript-navigator-property mozMyCalc @mozilla.org/MyCalcManager;1

/gecko/dom/myCalc/nsIDOMMyCalcManager.idl

#include "domstubs.idl"

interface nsIDOMDOMRequest;

[scriptable, uuid(682f9ea0-8a24-11e2-9f07-000c2921e8d6)]
interface nsIDOMMozmyCalc : nsISupports
{
  nsIDOMDOMRequest add(in jsval a, in jsval b);
};

/gecko/dom/Makefile.in

PARALLEL_DIRS += \
  apps \
  base \
・
・
  alarm \
  mycalc \		←追加
  devicestorage \

/gecko/dom/dom-config.mk

DOM_SRCDIRS = \
  dom/base \
  dom/battery \
・
・
  dom/alarm \
  dom/mycalc \		←追加
  dom/src/events \

/gecko/b2g/installer/package-manifest.in

@BINPATH@/components/dom_contacts.xpt
@BINPATH@/components/dom_alarm.xpt
@BINPATH@/components/dom_mycalc.xpt			←追加
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt
・
・
・
@BINPATH@/components/AlarmsManager.js
@BINPATH@/components/AlarmsManager.manifest
@BINPATH@/components/MyCalcManager.js
@BINPATH@/components/MyCalcManager.manifest		←追加
@BINPATH@/components/FeedProcessor.manifest		←追加
@BINPATH@/components/FeedProcessor.js

上記で使用したuuid(682f9ea0-8a24-11e2-9f07-000c2921e8d6)については、
固有の英数字を割り振る必要があります。
ターミナルで以下のコマンドを実行し、固有の英数字を取得し、使用してください。

uuidgen

2.ビルド確認
環境を展開したフォルダ(任意/b2g/)に移動し、
ターミナルから以下のコマンドを実行します。

./build.sh

ビルド完了まで待ち、エラーメッセージが出力されていなければ、
コンパイルできたことになります。
次に、動作確認のため、実装したGecko層機能を呼び出すアプリを作成します。

Gaia層へソースファイル実装
1.必要ファイル
以下のファイルを新規作成/ダウンロードする必要があります。

[新規作成ファイル]
・/gaia/apps/testcalc_api/index.html
・/gaia/apps/testcalc_api/manifest.webapps
・/gaia/apps/testcalc_api/js/test.js

[ダウンロードファイル]
・/gaia/apps/testcalc_api/js/lib/zepto.min.js

下記アドレスからzept.min.jsをダウンロードし、上記パスに格納して下さい。
http://zeptojs.com/

/gaia/apps/testcalc_api/index.html

<HTML>
<HEAD><meta charset="UTF-8"><TITLE>test add</TITLE></HEAD>
<script type="text/javascript" src="/js/lib/zepto.min.js"></script>
<SCRIPT type="application/javascript" src="js/testcalc.js">
</SCRIPT>
</HTML>

/gaia/apps/testcalc_api/manifest.webapps

{
  "name": "Test firefox api",
  "description": "test program",
  "launch_path": "/index.html",
  "developer": {
    "name": "FirefoxOS_tester",
    "url": "http://"
  },
  "icons": {
    "128": "/style/icons/test.png"
  }
}

/gaia/apps/testcalc_api/js/test.js

a = Math.round(Math.random()*10);
b = Math.round(Math.random()*10);
document.write(a);
document.write("
");
document.write(b);
document.write("
");
console.log("myCalcAdd start");
var myCalc = navigator.mozMyCalc;
var c = myCalc.add(a, b);
document.write(c);
document.write("
[end]");

2.ビルド確認
環境を展開したフォルダ(任意/b2g/)に移動し、
ターミナルから以下のコマンドを実行します。

./build.sh

ビルド完了まで待ち、エラーメッセージが出力されていなければ、
コンパイルできたことになります。
最後に動作確認を行い、想定した結果が出力されれば成功です。

動作確認
上記gecko, gaiaへの実装が完了したことを確認後、
環境を展開したフォルダ(任意/b2g/)に移動し、
以下のコマンドを実行します。

./run-emulator.sh

以下のような表示が出ていれば、正常に動作できています。
※但し、1行目、2行目の数字に関してはランダムです。3行目の数字について、1行目と2行目が足された値になっていればOKです。

4
9
13
[end]

 

[Firefox OS][B2G][FxOS] gecko層への機能拡張について” への2件のコメント

  1. ピンバック: [FxOS] firefox OSのモジュール図 | GCG研究所

  2. ピンバック: [Firefox OS][FxOS][Gecko] webidlでのAPIの追加 | GCG研究所

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <img localsrc="" alt="">