旧N7、N10、GNでもBLEが使えるか?

昨日のブログでは、新N7でBLEが使えるかを簡単に確認しました。
その中でも触れましたが、以下のソフトウエアがGoogle Playで提供されています。

Bluetooth Low Energy Enabler
https://play.google.com/store/apps/details?id=com.manuelnaranjo.btle.installer2

実際にこのソフトを使ってGNでもBLEが動作したそうです。
@sakiraさんありがとうございます。

要Rootとは言え、Google Playに提供されているアプリケーションで有効に出来るってことは、どっかの設定を変えるくらいで対応できてしまうってことですかね?

SDKのサンプルBluetoothLeGattでBLEに対応しているかを以下のようにチェックしています。
PackageManagerのhasSystemFeatureでパラメータにPackageManager.FEATURE_BLUETOOTH_LEを渡してチェックしていますね。

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}

ソースをちょっと見てみましょう。こんなときにOESFのAndroidソースコード検索サービスが役立ちます。
https://sites.google.com/site/devcollaboration/codesearch



まず、PackageManager.FEATURE_BLUETOOTH_LEは、PackageManager.javaの877行目で以下のように定義されています。
public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";


現在は、SDKにFramework周りのソースコードが付属しているので、ステップ実行してどこでチェックしているのか追っかけてみます。
サンプル:BluetoothLeGattのチェックしているところにブレークポイントを張ります。
今回はチェックしているところを確認するだけなので、エミュレータで実行します。

ブレークポイントで止まったら、デバッグ画面のプロジェクトで右クリックして「ソース・ルックアップの編集」を選択します。
画像


ソース・ルックアップ・パスの編集画面がポップアップするので、「追加」を押します。
画像


ソースの追加画面が表示されるので「ファイル・システム・ディレクトリー」を選択してOKを押します。
画像


ファイル・システム・フォルダーの追加画面がポップアップするので、SDK配下のソースファイルのフォルダを指定します。
画像


指定が終わったら、OKを押します。
画像


ソース・ルックアップ・パスの編集画面でOKを押します。
画像


デバッグ画面に戻るので、スレッドを選択して、ステップインの機能を使って中に入っていきます。

1、getPackageManager()
ContextWrapper.javaの94行目で止まります。
mBaseはContextImpl型です
さらにステップインします
画像


2、getPackageManager()
ContextImpl.javaの567行目で止まります。
mPackageManagerがNULLかチェックして、NULLでなければmPackageManagerを返しています。
mPackageManagerは、ApplicationPackageManager型です。
画像


戻って、戻って
getPackageManager()のリターンはAppllicationPackageManager型のインスタンス
その配下のhasSystemFeature()を呼び出します。

3、hasSystemFeature()
ApplicationPackageManager.javaの310行目で止まります。
画像


mPMはIPackageManager$Stub$Proxy
画像


この先はソースが見つかりませんと表示されるので、ソースコード検索サービスで追っかけます。

IPackageManager$Stub$ProxyはBinderによる呼び出しです。
Marakanaの良い資料があったので、以下に示します。
画像


IPackageManager$Stub$ProxyからBinder(/dev/binder)を経由してPackageManagerServiceを呼び出します。
図の青い四角で囲ったところです。

PackageManagerService.javaを検索すると2111行目
http://tools.oesf.biz/android-4.3.0_r2.1/xref/frameworks/base/services/java/com/android/server/pm/PackageManagerService.java

return mAvailableFeatures.containsKey(name);

mAvailableFeaturesは以下のように定義されています。ただのHashMapのようですね。
final HashMap mAvailableFeatures = new HashMap();

なのでname、この場合はPackageManager.FEATURE_BLUETOOTH_LEをキーとして指定してHashMap上に存在するかをチェックしていることになります。
データはFeatureInfo型でParcelableを継承しています。

やってることは単純(HashMapをキーでチェック)ですが、ではそのデータはどこから来るのでしょう?
さきほどのmAvailableFeaturesの定義のところに以下のコメントがありまs。
// These are the features this devices supports that were read from the
// etc/permissions.xml file.

etc/permissions.xmlから読み込んでいるようですね。
Android etc/permissions.xml featureで検索すると情報がヒットしました。
何気なく使っているFramework 第1回 PackageManager
http://d.hatena.ne.jp/baroqueworksdev/20110701/1309542202

Android パッケージインストール処理のしくみを追う
http://dsas.blog.klab.org/archives/52069323.html

どっちも良い資料ですね。
/etc/実際は/system/etcにシンボリックリンクされています。
よって、/system/etc/permissions/features.xmlと/system/etc/permissions/*.xml
を読み込んでいるようです。

読み込んでいるメソッドは、readPermissions() とreadPermissionsFromXml()ですね。
最終的にreadPermissionsFromXml()メソッドの1634行目で先ほどのmAvailableFeaturesにPutしています。
mAvailableFeatures.put(fname, fi);



ではそのXMLファイルを見てみましょう。
/system/etc/permissions配下のファイルとサイズの差分チェックです。
旧N7と新N7からファイルを抜いてきて比較しました。

新しいほうは22個のファイル
古いほうは21個のファイル

画像


差分は
●追加
android.hardware.audio.low_latency.xml:オーディオ(サラウンド)
android.hardware.bluetooth_le.xml:BLE対応
android.hardware.camera.flash-autofocus.xml:インカメラだと思います。
handheld_core_hardware.xml:後述

●削除
NFC関係が2つ削除
com.android.nfc_extras.xml
com.nxp.mifare.xml
tablet_core_hardware.xml:後述

tablet_core_hardware.xmlの中身を見てみると、追加になったhandheld_core_hardware.xmlと若干の差分はあるものの大同小異です。名称変更と内容変更と言ってよいでしょう。
画像


android.hardware.bluetooth_le.xmlが追加になっています。
中身はコメント部を除外すれば以下の三行になります。



この文字列どこかで見ましたね?
そう、public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
です。
よって、このandroid.hardware.bluetooth_le.xmlによってFeature(機能)を追加しています。



結論
もしハードウエア的にBLEに対応しているのであれば、/sytem/etc/permissions/android.hardware.bluetooth_le.xml
を追加してPackageManagerServiceに読み込ませれば動きそうな気がします。

system.imgに組み込むなら「何気なく使っているFramework 第1回 PackageManager」に記述されているように
device_base.mkに組み込むことで自動的にコピーされるようになると思います。

あくまでソースを追っかけた結果なので実機確認はしていませんので、ご参考までに



ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント

この記事へのトラックバック