2012年7月23日月曜日

Android パッケージインストール処理のしくみを追う

身近な話題でありながら中身のよくわからないことを調べてみるのは興味ぶかいもので、そこから得た知識が意外なところで役に立つことも少なくありません。かねてより Android 環境へアプリケーションをインストールする際に内部でどのような処理が行われるのかに関心を持っていたのですが、知りたい情報がなかなか見当たらないため手元で調査を行いました。その内容を公開します。

まとめ

※クリックすると大きな図が開きます 

※PackageInstaller を起動した状態での関連プロセスの例

$ ps  USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME  root      1     0     268    180   c009b74c 0000875c S /init  root      36    1     812    244   c02181f4 afd0b45c S /system/bin/installd  root      33    1     60900  16628 c009b74c afd0b844 S zygote  system    62    33    126452 28368 ffffffff afd0b6fc S system_server  app_30    372   33    74876  18852 ffffffff afd0c51c S com.android.packageinstaller                                :  
※Package Manager Service と installd プロセスの連携用 UNIX ドメインソケット
$ ls -l /dev/socket/installd  srw------- system   system            2012-07-04 11:43 installd  
  • Android OS 上でパッケージインストールにもっとも深い関わりを持つシステムサービスは、system_server プロセス内で稼動する Package Manager Service と、単独のネイティブプロセスとして動作する installd デーモンである。両者はいずれもシステムブート時に動作を開始する。
  • Package Manager Service は起動時に /system/data/packages.xml ファイルより現システム上のパッケージに関する情報を読み込んで実状と照合し、何らかの不整合があれば再インストール処理を含む自動復旧を試みた上で同ファイルへ最新の状態を反映する。
  • Package Manager Service は起動時に /system/etc/permissions/platform.xml を参照し既定の Android パーミッションに関する情報をロードし、同ディレクトリ下の他の *.xml より当該端末がカバーする機能の情報をロードする。
  • installd デーモンは UNIX ドメインソケット /dev/socket/installd 経由で Package Manager Service から処理要求を受信し、パッケージのインストール・アンインストールまわりの一連の手順のうち root 権限を要する処理を主に担当する。

  • PackageInstaller は通常のパッケージを対話的にインストールするための Android 既定のアプリケーションである。ユーザからインストール指示を受けると PackageInstaller は InstallAppProgress アクティビティを呼び出し、InstallAppProgress は Package Manager Service の installPackage() API 経由で当該パッケージのインストールをシステムへ依頼する。
  • Package Manager Service はパッケージインストール要求を受けると当該パッケージの情報を取得し以下を実施する 
    - インストール処理用のキューへパッケージ情報を追加〜順番待ち
    - 当該パッケージの適切なインストールロケーションを判定
    - 新規インストール/更新インストールの判別
    - 所定のディレクトリへの apk ファイルのコピー
    - 当該アプリの UID の決定
    - installd デーモンへ処理を要求
         - アプリケーションディレクトリの作成とパーミッション設定
         - dex コードのキャッシュディレクトリへの切り出し
    - 最新の状態を /system/data/packages.xml および packages.list へ反映
    - インストール完了の旨をパッケージ名を添えてシステムへブロードキャスト
     (新規の場合:Intent.ACTION_PACKAGE_ADDED
       更新の場合:Intent.ACTION_PACKAGE_REPLACED)

  • 上記の PackageInstaller 経由でのインストール経路とは別に、Package Manager Service は内部クラス「AppDirObserver」による非対話式のインストール経路を用意している。 AppDirObserver は android.os.FileObserver の派生クラスであり、所定のディレクトリ直下に .apk の拡張子を持つファイルが配置/削除されると自動的にシステムへのインストール/アンインストールを行う機能を持つ。(※別経路でインストールが行われた場合に重複処理発生を抑制するための機構を備える) Package Manager Service は起動時に /system/app, /data/app, /data/app-private, /system/framwrorks, /vendor/app の各ディレクトリを対象に AppDirObserver クラスのインスタンスを生成する。なお、これらのディレクトリへの書き込みには特権が必要であるため一般のアプリケーションプロセスから直接 AppDirObserver の提供する機構を利用することはできない。

コード読み

パッケージインストール処理を構成する一連のソースコードはかなりのボリュームがありますが、コードリーディングの一助として注釈を添えた抜粋を以下に掲載します。コードはいずれも 2012-07-06 現在の内容です。 なお、オンラインソースへのリンクには便宜上 http://android.git.linaro.org/ を使用しています。 

クラス・メソッドの参照関係(一部)  ※リンク末尾の「(*)」はオンラインソースへのリンクであることをを示す  ※リンク末尾の「-」は引数の異なるオーバーロードメソッドであることをを示す     ■ system_server プロセスおよび installd プロセスの起動(システムブート時)      - /init.rcPackageManagerService のスタートアップ      - PackageManagerService.PackageManagerService()          - Settings              - PackageSetting (*)          - Installer          - PackageManagerService.readPermissions()              - PackageManagerService.readPermissionsFromXml()          - Settings.readLPw()          - PackageManagerService.AppDirObserver          - PackageManagerService.scanDirLI()              - PackageParser.Package              - PackageManagerService.scanPackageLI()                  - PackageParser.Package                  - PackageParser.parsePackage()                      - PackageParser.parsePackage() -                  - PackageManagerService.collectCertificatesLI()                      - PackageParser.collectCertificates()                          - PackageParser.loadCertificates()                  - PackageManagerService.scanPackageLI() -                      - Settings.getPackageLPw()                          - Settings.getPackageLPw() -                      - Installer.remove()                          - installd.c                              - commands.c                              - utils.c (*)                      - Installer.install()                          - installd.c                              - commands.c                              - utils.c (*)          - Settings.writeLPr()              - Settings.writePermissionLPr()              - Settings.writePackageLPr()                  - PackageSignatures.writeXml()              - Settings.writeDisabledSysPackageLPr()              - PreferredActivity.writeToXml()                  - PreferredComponent.writeToXml()                  - IntentFilter.writeToXml()installd デーモンのスタートアップ      - installd.c          - commands.c          - utils.c (*)PackageInstaller から InstallAppProgress へインストール要求の引き渡し      - PackageInstallerActivity.onCreate()          - PackageUtil.getPackageInfo()              - PackageParser.parsePackage()                  - PackageParser.Package                  - PackageParser.parsePackage() -          - ApplicationInfo  (*)      - PackageInstallerActivity.onClick()InstallAppProgress からシステムへインストール要求〜インストール実処理      - InstallAppProgress.onCreate()      - InstallAppProgress.initView()        - InstallAppProgress.PackageInstallObserver        - PackageManager.installPackage()          - PackageManagerService.installPackage()            - PackageManagerService.installPackageWithVerification              - PackageManagerService.PackageHandler [INIT_COPY]                - PackageManagerService.HandlerParams                - PackageManagerService.connectToService()              - PackageManagerService.PackageHandler [MCS_BOUND]                - PackageManagerService.HandlerParams.startCopy()                  - PackageManagerService.PackageHandler [MCS_GIVE_UP]                  - PackageManagerService.PackageHandler [MCS_RECONNECT]                    - PackageManagerService.disconnectService()                    - PackageManagerService.connectToService()                  - PackageManagerService.InstallParams.handleStartCopy()                    - PackageManagerService.InstallParams.installLocationPolicy()                    - PackageManagerService.InstallParams.createInstallArgs()                      - PackageManagerService.FileInstallArgs.FileInstallArgs()                    - PackageManagerService.FileInstallArgs.copyApk()                      - PackageManagerService.FileInstallArgs.createCopyFile()                      - PackageManagerService.FileInstallArgs.setPermissions()                      - IMediaContainerService.copyResource()                        - DefaultContainerService.IMediaContainerService.Stub.copyResource()                          - DefaultContainerService.copyFile()                            - DefaultContainerService.copyToFile()                              - DefaultContainerService.copyToFile() -                            - DefaultContainerService.copyToFile() -                  - PackageManagerService.InstallParams.handleReturnCode()                    - PackageManagerService.processPendingInstall()                      - PackageManagerService.FileInstallArgs.doPreInstall()                        - PackageManagerService.FileInstallArgs.cleanUp()                      - PackageManagerService.installPackageLI()                        - PackageParser.parsePackage()                          - PackageParser.Package                          - PackageParser.parsePackage() -                        - PackageManagerService.FileInstallArgs.doRename()                          - PackageManagerService.FileInstallArgs.cleanUp()                          - PackageManagerService.FileInstallArgs.getResourcePathFromCodePath()                          - PackageManagerService.FileInstallArgs.setPermissions()                        - PackageManagerService.installNewPackageLI()                          - PackageManagerService.scanPackageLI()                            - PackageSetting (*)                            - Settings.getPackageLPw()                              - Settings.getPackageLPw() -                            - Installer.remove()                              - installd.c                                - commands.c                                - utils.c (*)                            - Installer.install()                              - installd.c                                - commands.c                                - utils.c (*)                          - PackageManagerService.updateSettingsLI()                            - Settings.writeLPr()                              - Settings.writePermissionLPr()                              - Settings.writePackageLPr()                                - PackageSignatures.writeXml()                              - Settings.writeDisabledSysPackageLPr()                              - PreferredActivity.writeToXml()                                - PreferredComponent.writeToXml()                                - IntentFilter.writeToXml()                            - PackageManagerService.moveDexFilesLI()                              - Installer.movedex()                                - installd.c                                  - commands.c                                  - utils.c (*)                            - PackageManagerService.setPermissionsLI()                            - Settings.writeLPr()                                     : (前出)                      - PackageManagerService.FileInstallArgs.doPostInstall()                        - PackageManagerService.FileInstallArgs.cleanUp()                      - PackageManagerService.PackageHandler [POST_INSTALL]                        - PackageManagerService.sendPackageBroadcast()                        - InstallAppProgress.PackageInstallObserver.packageInstalled()                          - InstallAppProgress.handleMessage [INSTALL_COMPLETE]                - PackageManagerService.PackageHandler [MCS_UNBIND]                  - PackageManagerService.disconnectService()AppDirObserver によるインストール・アンインストールの自動処理      - PackageManagerService.AppDirObserver.onEvent()          - PackageManagerService.scanPackageLI()              - PackageParser.Package              - PackageParser.parsePackage()                  - PackageParser.parsePackage() -              - PackageSetting (*)              - PackageManagerService.collectCertificatesLI()                  - PackageParser.collectCertificates()                      - PackageParser.loadCertificates()              - PackageManagerService.scanPackageLI() -                  - Settings.getPackageLPw()                      - Settings.getPackageLPw() -                  - Installer.remove()                      - installd.c                          - commands.c                          - utils.c (*)                  - Installer.install()                      - installd.c                          - commands.c                          - utils.c (*)          - Settings.writeLPr()              - Settings.writePermissionLPr()              - Settings.writePackageLPr()                  - PackageSignatures.writeXml()              - Settings.writeDisabledSysPackageLPr()              - PreferredActivity.writeToXml()                  - PreferredComponent.writeToXml()                  - IntentFilter.writeToXml()          - PackageManagerService.sendPackageBroadcast()  

system_server プロセスおよび installd プロセスの起動
(システムブート時)

実行環境の /init.rc より

                   :  service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server      socket zygote stream 666      onrestart write /sys/android_power/request_state wake      onrestart write /sys/power/state on      onrestart restart media      onrestart restart netd                   :    service installd /system/bin/installd      socket installd stream 600 system system                   :  

PackageManagerService のスタートアップ

frameworks/base/services/java/com/android/server/pm/PackageManagerService.java より

  PackageManagerService スタートアップ      17 package com.android.server.pm;                         :     152 public class PackageManagerService extends IPackageManager.Stub {                         :             // 定義・変数   166     static final boolean MULTIPLE_APPLICATION_UIDS = true;   167     private static final int RADIO_UID = Process.PHONE_UID;   168     private static final int LOG_UID = Process.LOG_UID;   169     private static final int NFC_UID = Process.NFC_UID;   170     static final int FIRST_APPLICATION_UID =   171         Process.FIRST_APPLICATION_UID;   172     static final int MAX_APPLICATION_UIDS = 1000;   173    174     private static final boolean GET_CERTIFICATES = true;   175    176     private static final int REMOVE_EVENTS =   177         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;   178     private static final int ADD_EVENTS =   179         FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;   180    181     private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;   182     // Suffix used during package installation when copying/moving   183     // package apks to install directory.   184     private static final String INSTALL_PACKAGE_SUFFIX = "-";                         :     209     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";   210    211     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(   212             DEFAULT_CONTAINER_PACKAGE,   213             "com.android.defcontainer.DefaultContainerService");   214    215     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";   216    217     private static final String LIB_DIR_NAME = "lib";   218    219     static final String mTempContainerPrefix = "smdl2tmp";   220    221     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",   222             Process.THREAD_PRIORITY_BACKGROUND);   223     final PackageHandler mHandler;   224    225     final int mSdkVersion = Build.VERSION.SDK_INT;   226     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)   227             ? null : Build.VERSION.CODENAME;   228    229     final Context mContext;   230     final boolean mFactoryTest;   231     final boolean mOnlyCore;   232     final boolean mNoDexOpt;   233     final DisplayMetrics mMetrics;   234     final int mDefParseFlags;   235     final String[] mSeparateProcesses;   236    237     // This is where all application persistent data goes.   238     final File mAppDataDir;   239    240     // This is where all application persistent data goes for secondary users.   241     final File mUserAppDataDir;   242    243     // This is the object monitoring the framework dir.   244     final FileObserver mFrameworkInstallObserver;   245    246     // This is the object monitoring the system app dir.   247     final FileObserver mSystemInstallObserver;   248    249     // This is the object monitoring the system app dir.   250     final FileObserver mVendorInstallObserver;   251    252     // This is the object monitoring mAppInstallDir.   253     final FileObserver mAppInstallObserver;   254    255     // This is the object monitoring mDrmAppPrivateInstallDir.   256     final FileObserver mDrmAppInstallObserver;   257    258     // Used for priviledge escalation.  MUST NOT BE CALLED WITH mPackages   259     // LOCK HELD.  Can be called with mInstallLock held.   260     final Installer mInstaller;   261    262     final File mFrameworkDir;   263     final File mSystemAppDir;   264     final File mVendorAppDir;   265     final File mAppInstallDir;   266     final File mDalvikCacheDir;   267    268     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked   269     // apps.   270     final File mDrmAppPrivateInstallDir;   271    272     // ----------------------------------------------------------------   273    274     // Lock for state used when installing and doing other long running   275     // operations.  Methods that must be called with this lock held have   276     // the prefix "LI".   277     final Object mInstallLock = new Object();   278    279     // These are the directories in the 3rd party applications installed dir   280     // that we have currently loaded packages from.  Keys are the application's   281     // installed zip file (absolute codePath), and values are Package.   282     final HashMap<String, PackageParser.Package> mAppDirs =   283             new HashMap<String, PackageParser.Package>();   284    285     // Information for the parser to write more useful error messages.   286     File mScanningPath;   287     int mLastScanError;   288    289     final int[] mOutPermissions = new int[3];   290    291     // ----------------------------------------------------------------   292    293     // Keys are String (package name), values are Package.  This also serves   294     // as the lock for the global state.  Methods that must be called with   295     // this lock held have the prefix "LP".   296     final HashMap<String, PackageParser.Package> mPackages =   297             new HashMap<String, PackageParser.Package>();   298    299     final Settings mSettings;   300     boolean mRestoredSettings;   301    302     // Group-ids that are given to all packages as read from etc/permissions/*.xml.   303     int[] mGlobalGids;   304    305     // These are the built-in uid -> permission mappings that were read from the   306     // etc/permissions.xml file.   307     final SparseArray<HashSet<String>> mSystemPermissions =   308             new SparseArray<HashSet<String>>();   309    310     // These are the built-in shared libraries that were read from the   311     // etc/permissions.xml file.   312     final HashMap<String, String> mSharedLibraries = new HashMap<String, String>();   313    314     // Temporary for building the final shared libraries for an .apk.   315     String[] mTmpSharedLibraries = null;   316    317     // These are the features this devices supports that were read from the   318     // etc/permissions.xml file.   319     final HashMap<String, FeatureInfo> mAvailableFeatures =   320             new HashMap<String, FeatureInfo>();   321    322     // All available activities, for your resolving pleasure.   323     final ActivityIntentResolver mActivities =   324             new ActivityIntentResolver();   325    326     // All available receivers, for your resolving pleasure.   327     final ActivityIntentResolver mReceivers =   328             new ActivityIntentResolver();   329    330     // All available services, for your resolving pleasure.   331     final ServiceIntentResolver mServices = new ServiceIntentResolver();   332    333     // Keys are String (provider class name), values are Provider.   334     final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =   335             new HashMap<ComponentName, PackageParser.Provider>();   336    337     // Mapping from provider base names (first directory in content URI codePath)   338     // to the provider information.   339     final HashMap<String, PackageParser.Provider> mProviders =   340             new HashMap<String, PackageParser.Provider>();   341    342     // Mapping from instrumentation class names to info about them.   343     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =   344             new HashMap<ComponentName, PackageParser.Instrumentation>();   345    346     // Mapping from permission names to info about them.   347     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =   348             new HashMap<String, PackageParser.PermissionGroup>();   349    350     // Packages whose data we have transfered into another package, thus   351     // should no longer exist.   352     final HashSet<String> mTransferedPackages = new HashSet<String>();   353        354     // Broadcast actions that are only available to the system.   355     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();   356    357     /** List of packages waiting for verification. */   358     final SparseArray<PackageVerificationState> mPendingVerification   359             = new SparseArray<PackageVerificationState>();   360    361     final ArrayList<PackageParser.Package> mDeferredDexOpt =   362             new ArrayList<PackageParser.Package>();   363    364     /** Token for keys in mPendingVerification. */   365     private int mPendingVerificationToken = 0;   366    367     boolean mSystemReady;   368     boolean mSafeMode;   369     boolean mHasSystemUidErrors;   370    371     ApplicationInfo mAndroidApplication;   372     final ActivityInfo mResolveActivity = new ActivityInfo();   373     final ResolveInfo mResolveInfo = new ResolveInfo();   374     ComponentName mResolveComponentName;   375     PackageParser.Package mPlatformPackage;   376    377     // Set of pending broadcasts for aggregating enable/disable of components.   378     final HashMap<String, ArrayList<String>> mPendingBroadcasts   379             = new HashMap<String, ArrayList<String>>();   380     // Service Connection to remote media container service to copy   381     // package uri's from external media onto secure containers   382     // or internal storage.   383     private IMediaContainerService mContainerService = null;                         :     406     final UserManager mUserManager;   407            // DefaultContainerService との接続・切断時のハンドラ   408     final private DefaultContainerConnection mDefContainerConn =   409             new DefaultContainerConnection();   410     class DefaultContainerConnection implements ServiceConnection {   411         public void onServiceConnected(ComponentName name, IBinder service) {   412             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");   413             IMediaContainerService imcs =   414                 IMediaContainerService.Stub.asInterface(service);                   // 接続確立時に自動的にハンドラへ MCS_BOUND メッセージを送出する   415             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));   416         }   417    418         public void onServiceDisconnected(ComponentName name) {   419             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");   420         }   421     };   422    423     // Recordkeeping of restore-after-install operations that are currently in flight   424     // between the Package Manager and the Backup Manager   425     class PostInstallData {   426         public InstallArgs args;   427         public PackageInstalledInfo res;   428    429         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {   430             args = _a;   431             res = _r;   432         }   433     };   434     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();   435     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows   436    437     private final String mRequiredVerifierPackage;                        :             // コンストラクタここから   860     public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) {   861         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,   862                 SystemClock.uptimeMillis());   863    864         if (mSdkVersion <= 0) {   865             Slog.w(TAG, "**** ro.build.version.sdk not set!");   866         }   867    868         mContext = context;   869         mFactoryTest = factoryTest;   870         mOnlyCore = onlyCore;   871         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));   872         mMetrics = new DisplayMetrics();                 // パッケージまわりの情報を一括管理するクラス   873         mSettings = new Settings();                 // 決め打ちの4 つの SharedUserId を設定   874         mSettings.addSharedUserLPw("android.uid.system",   875                 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);   876         mSettings.addSharedUserLPw("android.uid.phone",   877                 MULTIPLE_APPLICATION_UIDS   878                         ? RADIO_UID : FIRST_APPLICATION_UID,   879                 ApplicationInfo.FLAG_SYSTEM);   880         mSettings.addSharedUserLPw("android.uid.log",   881                 MULTIPLE_APPLICATION_UIDS   882                         ? LOG_UID : FIRST_APPLICATION_UID,   883                 ApplicationInfo.FLAG_SYSTEM);   884         mSettings.addSharedUserLPw("android.uid.nfc",   885                 MULTIPLE_APPLICATION_UIDS   886                         ? NFC_UID : FIRST_APPLICATION_UID,   887                 ApplicationInfo.FLAG_SYSTEM);                         :                 // Installer クラスは installd ソケットへの書き込みを行う   906         mInstaller = new Installer();   907    908         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);   909         Display d = wm.getDefaultDisplay();   910         d.getMetrics(mMetrics);   911    912         synchronized (mInstallLock) {   913         // writer   914         synchronized (mPackages) {                   // メッセージハンドラを起動   915             mHandlerThread.start();   916             mHandler = new PackageHandler(mHandlerThread.getLooper());   917                    // "/data/data", "/data/user", "/data/app-private"   918             File dataDir = Environment.getDataDirectory();   919             mAppDataDir = new File(dataDir, "data");   920             mUserAppDataDir = new File(dataDir, "user");   921             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");   922    923             mUserManager = new UserManager(mInstaller, mUserAppDataDir);   924                    // /system/etc/permissions/platform.xml および *.xml の読み込み   925             readPermissions();   926                    // /system/data/packages.xml の読み込み   927             mRestoredSettings = mSettings.readLPw();   928             long startTime = SystemClock.uptimeMillis();   929    930             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,   931                     startTime);   932    933             // Set flag to monitor and not change apk file paths when   934             // scanning install directories.   935             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX;   936             if (mNoDexOpt) {   937                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");   938                 scanMode |= SCAN_NO_DEX;   939             }   940    941             final HashSet<String> libFiles = new HashSet<String>();   942                    // "/framework", "/data/dalvik-cache"   943             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");   944             mDalvikCacheDir = new File(dataDir, "dalvik-cache");                                :                     // /system/app 下を AppDirObserver で監視  1057             // Collect all system packages.  1058             mSystemAppDir = new File(Environment.getRootDirectory(), "app");  1059             mSystemInstallObserver = new AppDirObserver(  1060                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);  1061             mSystemInstallObserver.startWatching();  1062             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM  1063                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);  1064                                  // /vendor/app 下を AppDirObserver で監視  1065             // Collect all vendor packages.  1066             mVendorAppDir = new File("/vendor/app");  1067             mVendorInstallObserver = new AppDirObserver(  1068                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);  1069             mVendorInstallObserver.startWatching();  1070             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM  1071                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);  1072   1073             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");  1074             mInstaller.moveFiles();  1075                      // すでに存在しないシステムパッケージを削除  1076             // Prune any system packages that no longer exist.  1077             if (!mOnlyCore) {  1078                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();  1079                 while (psit.hasNext()) {  1080                     PackageSetting ps = psit.next();  1081                     if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0  1082                             && !mPackages.containsKey(ps.name)  1083                             && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {  1084                         psit.remove();  1085                         String msg = "System package " + ps.name  1086                                 + " no longer exists; wiping its data";  1087                         reportSettingsProblem(Log.WARN, msg);  1088                         mInstaller.remove(ps.name, 0);  1089                         mUserManager.removePackageForAllUsers(ps.name);  1090                     }  1091                 }  1092             }  1093                                  // "/data/app"  1094             mAppInstallDir = new File(dataDir, "app");                     // インストール未了のパッケージファイルを探索して削除  1095             //look for any incomplete package installations  1096             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();  1097             //clean up list  1098             for(int i = 0; i < deletePkgsList.size(); i++) {  1099                 //clean up here  1100                 cleanupInstallFailedPackage(deletePkgsList.get(i));  1101             }  1102             //delete tmp files  1103             deleteTempPackageFiles();  1104   1105             if (!mOnlyCore) {  1106                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,  1107                         SystemClock.uptimeMillis());                         // /data/app 下を AppDirObserver で監視  1108                 mAppInstallObserver = new AppDirObserver(  1109                     mAppInstallDir.getPath(), OBSERVER_EVENTS, false);  1110                 mAppInstallObserver.startWatching();  1111                 scanDirLI(mAppInstallDir, 0, scanMode, 0);  1112                              // /data/app-private 下を AppDirObserver で監視  1113                 mDrmAppInstallObserver = new AppDirObserver(  1114                     mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);  1115                 mDrmAppInstallObserver.startWatching();  1116                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,  1117                         scanMode, 0);  1118             } else {  1119                 mAppInstallObserver = null;  1120                 mDrmAppInstallObserver = null;  1121             }                            :    1140             mSettings.mInternalSdkPlatform = mSdkVersion;  1141               1142             updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);  1143                      // /system/data/packages.xml, packages.list を最新の状態に更新  1144             // can downgrade to reader  1145             mSettings.writeLPr();                     :    1156         } // synchronized (mPackages)  1157         } // synchronized (mInstallLock)  1158     }  

installd デーモンのスタートアップ

platform/frameworks/base/cmds/installd/installd.c より

installd デーモン      17 #include "installd.h"                    :         // 各コマンドに対応する関数のエントリポイント    29 static int do_install(char **arg, char reply[REPLY_MAX])    30 {    31     return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */    32 }    33     34 static int do_dexopt(char **arg, char reply[REPLY_MAX])    35 {    36         /* apk_path, uid, is_public */    37     return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]));    38 }    39     40 static int do_move_dex(char **arg, char reply[REPLY_MAX])    41 {    42     return move_dex(arg[0], arg[1]); /* src, dst */    43 }                          :      50 static int do_remove(char **arg, char reply[REPLY_MAX])    51 {    52     return uninstall(arg[0], atoi(arg[1])); /* pkgname, userid */    53 }                          :         // 「コマンド名→関数名」のテーブル   125 struct cmdinfo {   126     const char *name;   127     unsigned numargs;   128     int (*func)(char **arg, char reply[REPLY_MAX]);   129 };   130    131 struct cmdinfo cmds[] = {   132     { "ping",                 0, do_ping },   133     { "install",              3, do_install },   134     { "dexopt",               3, do_dexopt },   135     { "movedex",              2, do_move_dex },   136     { "rmdex",                1, do_rm_dex },   137     { "remove",               2, do_remove },   138     { "rename",               2, do_rename },   139     { "freecache",            1, do_free_cache },   140     { "rmcache",              1, do_rm_cache },   141     { "protect",              2, do_protect },   142     { "getsize",              4, do_get_size },   143     { "rmuserdata",           2, do_rm_user_data },   144     { "movefiles",            0, do_movefiles },   145     { "linklib",              2, do_linklib },   146     { "unlinklib",            1, do_unlinklib },   147     { "mkuserdata",           3, do_mk_user_data },   148     { "rmuser",               1, do_rm_user },   149 };                          :     347 int main(const int argc, const char *argv[]) {   348     char buf[BUFFER_MAX];   349     struct sockaddr addr;   350     socklen_t alen;   351     int lsocket, s, count;   352    353     if (initialize_globals() < 0) {   354         ALOGE("Could not initialize globals; exiting.\n");   355         exit(1);   356     }   357    358     if (initialize_directories() < 0) {   359         ALOGE("Could not create directories; exiting.\n");   360         exit(1);   361     }   362    363     lsocket = android_get_control_socket(SOCKET_PATH);   364     if (lsocket < 0) {   365         ALOGE("Failed to get socket from environment: %s\n", strerror(errno));   366         exit(1);   367     }   368     if (listen(lsocket, 5)) {   369         ALOGE("Listen on socket failed: %s\n", strerror(errno));   370         exit(1);   371     }   372     fcntl(lsocket, F_SETFD, FD_CLOEXEC);   373            // /dev/socket/installd からの読み込みとコマンド呼び出し   374     for (;;) {   375         alen = sizeof(addr);   376         s = accept(lsocket, &addr, &alen);   377         if (s < 0) {   378             ALOGE("Accept failed: %s\n", strerror(errno));   379             continue;   380         }   381         fcntl(s, F_SETFD, FD_CLOEXEC);   382    383         ALOGI("new connection\n");   384         for (;;) {   385             unsigned short count;   386             if (readx(s, &count, sizeof(count))) {   387                 ALOGE("failed to read size\n");   388                 break;   389             }   390             if ((count < 1) || (count >= BUFFER_MAX)) {   391                 ALOGE("invalid size %d\n", count);   392                 break;   393             }   394             if (readx(s, buf, count)) {   395                 ALOGE("failed to read command\n");   396                 break;   397             }   398             buf[count] = 0;   399             if (execute(s, buf)) break;   400         }   401         ALOGI("closing connection\n");   402         close(s);   403     }   404    405     return 0;   406 }  
platform/frameworks/base/cmds/installd/commands.c より
installd デーモン 各コマンド関数の実体      17 #include "installd.h"                         :      31 int install(const char *pkgname, uid_t uid, gid_t gid)    32 {    33     char pkgdir[PKG_PATH_MAX];    34     char libdir[PKG_PATH_MAX];    35     36     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {    37         ALOGE("invalid uid/gid: %d %d\n", uid, gid);    38         return -1;    39     }    40     41     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {    42         ALOGE("cannot create package path\n");    43         return -1;    44     }    45     46     if (create_pkg_path(libdir, pkgname, PKG_LIB_POSTFIX, 0)) {    47         ALOGE("cannot create package lib path\n");    48         return -1;    49     }    50     51     if (mkdir(pkgdir, 0751) < 0) {    52         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));    53         return -errno;    54     }    55     if (chmod(pkgdir, 0751) < 0) {    56         ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));    57         unlink(pkgdir);    58         return -errno;    59     }    60     if (chown(pkgdir, uid, gid) < 0) {    61         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));    62         unlink(pkgdir);    63         return -errno;    64     }    65     66 #ifdef HAVE_SELINUX    67     if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {    68         LOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));    69         unlink(pkgdir);    70         return -errno;    71     }    72 

0 件のコメント:

コメントを投稿