何気なく使っているFramework 第1回 PackageManager

アプリケーション開発で何気なく使っているFrameworks層のAPI
ちょっとだけ掘り下げて、Frameworksを確認してみる。

確認OSバージョン

Android OS 2.3 GingerBread

PackageManagerの役割り

現在デバイスにインストールされているアプリケーションのパッケージに関連する、さまざまな情報を取得するためのクラス。

PackageManagerServiceの役割り

  • system/app/ (=プリインストールapk)を読み込む
  • data/data/ (=ダウンロードしたapk)を読み込む
  • SDカードと端末間のパッケージ移動
  • パッケージ情報の管理
  • 端末がサポートしている機能(Features)情報の管理

役割りが多い分、インナークラスも多いですね。
できれば、もっと機能ごとにファイル分割して欲しいなぁっと思ってみたり。

Activityからの使用

  • CotextImplクラスに、PackageManagerクラスを継承したApplicationPackageManagerクラスがある
  • ApplicationPackageManagerクラスは、インターフェイス:IPackageManagerを持っている
  • IPackageManagerからPackageManagerService(=IPackageManager#Stubの継承クラス)につながっている
  • PackageManagerServiceは各パッケージの情報を保持している




端末のサポート機能(Features)情報の管理

Featuresをどこから読み込んでいるのか確認しました。
PackageManagerServiceクラスのメソッドに注目です。

    void readPermissions() {
        // Read permissions from .../etc/permission directory.
        File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");

               (省略) 

        // Iterate over the files in the directory and scan .xml files
        for (File f : libraryDir.listFiles()) {
            // We'll read platform.xml last
            if (f.getPath().endsWith("etc/permissions/platform.xml")) {
                continue;
            }

               (省略) 

            readPermissionsFromXml(f);
        }

        // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
        final File permFile = new File(Environment.getRootDirectory(),
                "etc/permissions/platform.xml");
        readPermissionsFromXml(permFile);
    }

    private void readPermissionsFromXml(File permFile) {
               (省略) 
                } else if ("feature".equals(name)) {
                    String fname = parser.getAttributeValue(null, "name");
                    if (fname == null) {
                        Slog.w(TAG, "<feature> without name at "
                                + parser.getPositionDescription());
                    } else {
                        //Log.i(TAG, "Got feature " + fname);
                        FeatureInfo fi = new FeatureInfo();
                        fi.name = fname;
                        mAvailableFeatures.put(fname, fi);
                    }
                    XmlUtils.skipCurrentTag(parser);
                    continue;

                } else {
               (省略) 
    }

ソースを見ると以下のことが分かります。

  • "system/etc/permissions"のファイル一覧の「.xml」を読み込む
  • "system/etc/permissions/platform.xml"を読み込む
  • privateメンバーのmAvailableFeaturesにputし、情報を保持




systemフォルダからxmlファイルを読み込み、情報をmAvailableFeaturesに保持しています。

もう一歩、踏み込んでみましょう。
このxmlはどうやってsystem.imgに組み込まれているか確認します

Android_2.3.5_r1のNexus Sのビルド環境をみると、以下のmakefileに記載されています。
ファイル:\device\samsung\crespo\device_base.mk

# These are the hardware-specific features
PRODUCT_COPY_FILES += \
	frameworks/base/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml \
	frameworks/base/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
	frameworks/base/data/etc/android.hardware.camera.front.xml:system/etc/permissions/android.hardware.camera.front.xml \
	frameworks/base/data/etc/android.hardware.location.gps.xml:system/etc/permissions/android.hardware.location.gps.xml \
	frameworks/base/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
	frameworks/base/data/etc/android.hardware.sensor.proximity.xml:system/etc/permissions/android.hardware.sensor.proximity.xml \
	frameworks/base/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml \
	frameworks/base/data/etc/android.hardware.sensor.gyroscope.xml:system/etc/permissions/android.hardware.sensor.gyroscope.xml \
	frameworks/base/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:system/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \
	frameworks/base/data/etc/android.hardware.nfc.xml:system/etc/permissions/android.hardware.nfc.xml \
	frameworks/base/data/etc/android.software.sip.voip.xml:system/etc/permissions/android.software.sip.voip.xml \
	frameworks/base/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml \
	packages/wallpapers/LivePicker/android.software.live_wallpaper.xml:system/etc/permissions/android.software.live_wallpaper.xml


このファイルから、
「frameworks/base/data/etc/XXXX.xml を system/etc/permissions/XXX.xmlにコピー」という事がわかります。

独自でなにかデバイス機能を追加するときは、上記と同じように追記すればOKですね。