[Firefox OS][WebAPI] Idle API読んでみた


 藪下@2課のガジェオタです。

 世間がFirefox 29とZTE Open CとFirefox OS v1.3で賑わっているなかどこふく風でAPIの実装を読んでみたお話です。

 前回addIdleObserverが見えないと書いたのですが、geckoのソースコードを覗いてみたら実装されてるっぽいです。

http://wiki.mozilla.org/WebAPI/IdleAPI

 ここにも書いてある通りaddIdleObserverはNavigatorの下にあるのでNavigatorを見てみます。
 まずはwebidlですね。

http://reading.fxos.org/source/xref/B2G/gecko/dom/webidl/Navigator.webidl#167

  /**
   * Navigator requests to add an idle observer to the existing window.
   */
  [Throws, Func="Navigator::HasIdleSupport"]
  void addIdleObserver(MozIdleObserver aIdleObserver);

  /**
   * Navigator requests to remove an idle observer from the existing window.
   */
  [Throws, Func="Navigator::HasIdleSupport"]
  void removeIdleObserver(MozIdleObserver aIdleObserver);

 [Func]属性がついてますね。Navigator::HasIdleSupportがtrueでないと見えないということを示しています。

 webidlについては以下のページに書かれています。全訳されてませんが[Func]属性の部分は訳しておきました。

 HasIdleSupportを見てみます。

http://reading.fxos.org/source/xref/B2G/gecko/dom/base/Navigator.cpp#2049

/* static */
bool
Navigator::HasIdleSupport(JSContext*  /* unused */, JSObject* aGlobal)
{
  if (!nsContentUtils::IsIdleObserverAPIEnabled()) {
    return false;
  }

  nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
  return CheckPermission(win, "idle");
}

 nsContentUtils::IsIdleObserverAPIEnabled()とCheckPermission(win, “idle”)に依存してるのでそれぞれ見ていきます。

http://reading.fxos.org/source/xref/B2G/gecko/content/base/public/nsContentUtils.h#1837

  /**
   * Returns true if the idle observers API is enabled.
   */
  static bool IsIdleObserverAPIEnabled() { return sIsIdleObserverAPIEnabled; }

 sIsIdleObserverAPIEnabledが設定されているところを探します。

http://reading.fxos.org/source/xref/B2G/gecko/content/base/src/nsContentUtils.cpp#434

  sIsIdleObserverAPIEnabled = Preferences::GetBool("dom.idle-observers-api.enabled", true);

 ということで “dom.idle-observers-api.enabled” がtrueかどうかがnsContentUtils::IsIdleObserverAPIEnabled()の結果です。

 次にCheckPermission(win, “idle”)を追います。

http://reading.fxos.org/source/xref/B2G/gecko/dom/base/Navigator.cpp#1789

/* static */
bool
Navigator::CheckPermission(nsPIDOMWindow* aWindow, const char* aType)
{
  if (!aWindow) {
    return false;
  }

  nsCOMPtr<nsIPermissionManager> permMgr =
    services::GetPermissionManager();
  NS_ENSURE_TRUE(permMgr, false);

  uint32_t permission = nsIPermissionManager::DENY_ACTION;
  permMgr->TestPermissionFromWindow(aWindow, aType, &permission);
  return permission == nsIPermissionManager::ALLOW_ACTION;
}

 ということでパーミッションがALLOW_ACTIONかDENY_ACTIONかで見ているようなので設定しているところを探します。

http://reading.fxos.org/source/xref/B2G/gecko/dom/apps/src/PermissionsTable.jsm#209

                           "idle": {
                             app: DENY_ACTION,
                             privileged: DENY_ACTION,
                             certified: ALLOW_ACTION
                           },

 あれ、これなんか見たことあると思ったらMDNとmxrに書いてありました。

https://developer.mozilla.org/ja/docs/Web/Apps/App_permissions

関連情報
Firefox コード内では 許可設定一覧表 にすべての許可設定が定義されています。

https://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm#36

 というわけでcertifiedのアプリにidleパーミッションをつけないといけないみたいです。
# MDNにもwikimoにも必要って書いてないし! ないし!

 サンプルコードを更新しました。

https://github.com/aoitan/gcg_labo/tree/master/api_reading/20140323_using_Idle_API

 マニフェストにpermissions属性を加えてます。もちろん許可するのはidleです。
 あとCSPに怒られたのでスクリプトをidle_test.jsに抜き出しました。

  "permissions": {
    "idle": {}
  },

 ビルドして動かしてみましょう。

Screenshot_from_2014-05-12 01_22_39

 とまあ動いたのですが、HasIdleSupportを見る限りパーミッションが設定されてないとやっぱりAPIが見えないはずなので、デスクトップとかfor Android的にはおかしいです。
# wikimoにはデスクトップとAndroidはデフォルト有効と書いてます。
https://wiki.mozilla.org/WebAPI
 これビルド対象合わせでパーミッションチェックしないといけない気がするのでちょっとパッチ書いてみようかと思います。

 今回Idle APIを追いかけましたが、実は書いた以上にソースコードを追いかけました。
 パーミッションマネージャを割と掘り下げたので機会があれば記事にします。お楽しみに。

コメントを残す

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

次の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="">