身近な話題でありながら中身のよくわからないことを調べてみるのは興味ぶかいもので、そこから得た知識が意外なところで役に立つことも少なくありません。かねてより 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.rc ■ PackageManagerService のスタートアップ - 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 件のコメント:
コメントを投稿