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 �ץ�������Dz�ư���� Package Manager Service �ȡ�ñ�ȤΥͥ��ƥ��֥ץ������Ȥ���ư��� installd �ǡ����Ǥ��롣ξ�ԤϤ�����⥷���ƥ�֡��Ȼ���ư��򳫻Ϥ��롣
- Package Manager Service �ϵ�ư���� /data/system/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 �����ɤΥ���å���ǥ��쥯�ȥ�ؤ��ڤ�Ф�
- �ǿ��ξ��֤� /data/system/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 // /data/system/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 // /data/system/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 #endif 73 74 if (mkdir(libdir, 0755) < 0) { 75 ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno)); 76 unlink(pkgdir); 77 return -errno; 78 } 79 if (chmod(libdir, 0755) < 0) { 80 ALOGE("cannot chmod dir '%s': %s\n", libdir, strerror(errno)); 81 unlink(libdir); 82 unlink(pkgdir); 83 return -errno; 84 } 85 if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) { 86 ALOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno)); 87 unlink(libdir); 88 unlink(pkgdir); 89 return -errno; 90 } 91 92 #ifdef HAVE_SELINUX 93 if (selinux_android_setfilecon(libdir, pkgname, AID_SYSTEM) < 0) { 94 LOGE("cannot setfilecon dir '%s': %s\n", libdir, strerror(errno)); 95 unlink(libdir); 96 unlink(pkgdir); 97 return -errno; 98 } 99 #endif 100 101 return 0; 102 } 103 104 int uninstall(const char *pkgname, uid_t persona) 105 { 106 char pkgdir[PKG_PATH_MAX]; 107 108 if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) 109 return -1; 110 111 /* delete contents AND directory, no exceptions */ 112 return delete_dir_contents(pkgdir, 1, NULL); 113 } : 267 int move_dex(const char *src, const char *dst) 268 { 269 char src_dex[PKG_PATH_MAX]; 270 char dst_dex[PKG_PATH_MAX]; 271 272 if (validate_apk_path(src)) return -1; 273 if (validate_apk_path(dst)) return -1; 274 275 if (create_cache_path(src_dex, src)) return -1; 276 if (create_cache_path(dst_dex, dst)) return -1; 277 278 ALOGV("move %s -> %s\n", src_dex, dst_dex); 279 if (rename(src_dex, dst_dex) < 0) { 280 ALOGE("Couldn't move %s: %s\n", src_dex, strerror(errno)); 281 return -1; 282 } else { 283 return 0; 284 } 285 } 471 static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name, 472 const char* dexopt_flags) 473 { // Android ɸ��� dexopt ���ޥ�ɤ����� 474 static const char* DEX_OPT_BIN = "/system/bin/dexopt"; 475 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig 476 char zip_num[MAX_INT_LEN]; 477 char odex_num[MAX_INT_LEN]; 478 479 sprintf(zip_num, "%d", zip_fd); 480 sprintf(odex_num, "%d", odex_fd); 481 482 execl(DEX_OPT_BIN, DEX_OPT_BIN, "--zip", zip_num, odex_num, input_file_name, 483 dexopt_flags, (char*) NULL); 484 ALOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno)); 485 } 486 487 static int wait_dexopt(pid_t pid, const char* apk_path) 488 { 489 int status; 490 pid_t got_pid; 491 492 /* 493 * Wait for the optimization process to finish. 494 */ 495 while (1) { 496 got_pid = waitpid(pid, &status, 0); 497 if (got_pid == -1 && errno == EINTR) { 498 printf("waitpid interrupted, retrying\n"); 499 } else { 500 break; 501 } 502 } 503 if (got_pid != pid) { 504 ALOGW("waitpid failed: wanted %d, got %d: %s\n", 505 (int) pid, (int) got_pid, strerror(errno)); 506 return 1; 507 } 508 509 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 510 ALOGV("DexInv: --- END '%s' (success) ---\n", apk_path); 511 return 0; 512 } else { 513 ALOGW("DexInv: --- END '%s' --- status=0x%04x, process failed\n", 514 apk_path, status); 515 return status; /* always nonzero */ 516 } 517 } 518 519 int dexopt(const char *apk_path, uid_t uid, int is_public) 520 { 521 struct utimbuf ut; 522 struct stat apk_stat, dex_stat; 523 char dex_path[PKG_PATH_MAX]; 524 char dexopt_flags[PROPERTY_VALUE_MAX]; 525 char *end; 526 int res, zip_fd=-1, odex_fd=-1; 527 528 /* Before anything else: is there a .odex file? If so, we have 529 * pre-optimized the apk and there is nothing to do here. 530 */ 531 if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) { 532 return -1; 533 } 534 535 /* platform-specific flags affecting optimization and verification */ 536 property_get("dalvik.vm.dexopt-flags", dexopt_flags, ""); 537 538 strcpy(dex_path, apk_path); 539 end = strrchr(dex_path, '.'); 540 if (end != NULL) { 541 strcpy(end, ".odex"); 542 if (stat(dex_path, &dex_stat) == 0) { 543 return 0; 544 } 545 } 546 547 if (create_cache_path(dex_path, apk_path)) { 548 return -1; 549 } 550 551 memset(&apk_stat, 0, sizeof(apk_stat)); 552 stat(apk_path, &apk_stat); 553 554 zip_fd = open(apk_path, O_RDONLY, 0); 555 if (zip_fd < 0) { 556 ALOGE("dexopt cannot open '%s' for input\n", apk_path); 557 return -1; 558 } 559 560 unlink(dex_path); 561 odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644); 562 if (odex_fd < 0) { 563 ALOGE("dexopt cannot open '%s' for output\n", dex_path); 564 goto fail; 565 } 566 if (fchown(odex_fd, AID_SYSTEM, uid) < 0) { 567 ALOGE("dexopt cannot chown '%s'\n", dex_path); 568 goto fail; 569 } 570 if (fchmod(odex_fd, 571 S_IRUSR|S_IWUSR|S_IRGRP | 572 (is_public ? S_IROTH : 0)) < 0) { 573 ALOGE("dexopt cannot chmod '%s'\n", dex_path); 574 goto fail; 575 } 576 577 ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path); 578 579 pid_t pid; 580 pid = fork(); 581 if (pid == 0) { 582 /* child -- drop privileges before continuing */ 583 if (setgid(uid) != 0) { 584 ALOGE("setgid(%d) failed during dexopt\n", uid); 585 exit(64); 586 } 587 if (setuid(uid) != 0) { 588 ALOGE("setuid(%d) during dexopt\n", uid); 589 exit(65); 590 } 591 if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) { 592 ALOGE("flock(%s) failed: %s\n", dex_path, strerror(errno)); 593 exit(66); 594 } 595 596 run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags); 597 exit(67); /* only get here on exec failure */ 598 } else { 599 res = wait_dexopt(pid, apk_path); 600 if (res != 0) { 601 ALOGE("dexopt failed on '%s' res = %d\n", dex_path, res); 602 goto fail; 603 } 604 } 605 606 ut.actime = apk_stat.st_atime; 607 ut.modtime = apk_stat.st_mtime; 608 utime(dex_path, &ut); 609 610 close(odex_fd); 611 close(zip_fd); 612 return 0; 613 614 fail: 615 if (odex_fd >= 0) { 616 close(odex_fd); 617 unlink(dex_path); 618 } 619 if (zip_fd >= 0) { 620 close(zip_fd); 621 } 622 return -1; 623 } 624 :
Settings ���饹 ���󥹥ȥ饯��
frameworks/base/services/java/com/android/server/pm/Settings.java ���
Settings ���饹 �ѥå������ޤ��ξ����������륯�饹 17 package com.android.server.pm; : 68 /** 69 * Holds information about dynamic settings. 70 */ 71 final class Settings { 72 private static final String TAG = "PackageSettings"; 73 74 private static final boolean DEBUG_STOPPED = false; 75 76 private final File mSettingsFilename; 77 private final File mBackupSettingsFilename; 78 private final File mPackageListFilename; 79 private final File mStoppedPackagesFilename; 80 private final File mBackupStoppedPackagesFilename; 81 final HashMap<String, PackageSetting> mPackages = 82 new HashMap<String, PackageSetting>(); 83 // List of replaced system applications 84 final HashMap<String, PackageSetting> mDisabledSysPackages = 85 new HashMap<String, PackageSetting>(); 86 87 // These are the last platform API version we were using for 88 // the apps installed on internal and external storage. It is 89 // used to grant newer permissions one time during a system upgrade. 90 int mInternalSdkPlatform; 91 int mExternalSdkPlatform; 92 93 /** Device identity for the purpose of package verification. */ 94 private VerifierDeviceIdentity mVerifierDeviceIdentity; 95 96 // The user's preferred activities associated with particular intent 97 // filters. 98 final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities = 99 new IntentResolver<PreferredActivity, PreferredActivity>() { 100 @Override 101 protected String packageForFilter(PreferredActivity filter) { 102 return filter.mPref.mComponent.getPackageName(); 103 } 104 @Override 105 protected void dumpFilter(PrintWriter out, String prefix, 106 PreferredActivity filter) { 107 filter.mPref.dump(out, prefix, filter); 108 } 109 }; 110 final HashMap<String, SharedUserSetting> mSharedUsers = 111 new HashMap<String, SharedUserSetting>(); 112 private final ArrayList<Object> mUserIds = new ArrayList<Object>(); 113 private final SparseArray<Object> mOtherUserIds = 114 new SparseArray<Object>(); 115 116 // For reading/writing settings file. 117 private final ArrayList<Signature> mPastSignatures = 118 new ArrayList<Signature>(); 119 120 // Mapping from permission names to info about them. 121 final HashMap<String, BasePermission> mPermissions = 122 new HashMap<String, BasePermission>(); 123 124 // Mapping from permission tree names to info about them. 125 final HashMap<String, BasePermission> mPermissionTrees = 126 new HashMap<String, BasePermission>(); 127 128 // Packages that have been uninstalled and still need their external 129 // storage data deleted. 130 final ArrayList<String> mPackagesToBeCleaned = new ArrayList<String>(); 131 132 // Packages that have been renamed since they were first installed. 133 // Keys are the new names of the packages, values are the original 134 // names. The packages appear everwhere else under their original 135 // names. 136 final HashMap<String, String> mRenamedPackages = new HashMap<String, String>(); 137 138 final StringBuilder mReadMessages = new StringBuilder(); 139 140 /** 141 * Used to track packages that have a shared user ID that hasn't been read 142 * in yet. 143 * <p> 144 * TODO: make this just a local variable that is passed in during package 145 * scanning to make it less confusing. 146 */ 147 private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>(); 148 // ���󥹥ȥ饯�� 149 Settings() { 150 File dataDir = Environment.getDataDirectory(); 151 File systemDir = new File(dataDir, "system"); 152 systemDir.mkdirs(); 153 FileUtils.setPermissions(systemDir.toString(), 154 FileUtils.S_IRWXU|FileUtils.S_IRWXG 155 |FileUtils.S_IROTH|FileUtils.S_IXOTH, 156 -1, -1); 157 mSettingsFilename = new File(systemDir, "packages.xml"); 158 mBackupSettingsFilename = new File(systemDir, "packages-backup.xml"); 159 mPackageListFilename = new File(systemDir, "packages.list"); 160 mStoppedPackagesFilename = new File(systemDir, "packages-stopped.xml"); 161 mBackupStoppedPackagesFilename = new File(systemDir, "packages-stopped-backup.xml"); 162 } :
PackageManagerService.readPermissions()
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
1236 void readPermissions() { 1237 // Read permissions from .../etc/permission directory. // "/system/etc/permissions" 1238 File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions"); 1239 if (!libraryDir.exists() || !libraryDir.isDirectory()) { 1240 Slog.w(TAG, "No directory " + libraryDir + ", skipping"); 1241 return; 1242 } 1243 if (!libraryDir.canRead()) { 1244 Slog.w(TAG, "Directory " + libraryDir + " cannot be read"); 1245 return; 1246 } 1247 1248 // Iterate over the files in the directory and scan .xml files 1249 for (File f : libraryDir.listFiles()) { // platform.xml �ϸ�� 1250 // We'll read platform.xml last 1251 if (f.getPath().endsWith("etc/permissions/platform.xml")) { 1252 continue; 1253 } 1254 1255 if (!f.getPath().endsWith(".xml")) { 1256 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring"); 1257 continue; 1258 } 1259 if (!f.canRead()) { 1260 Slog.w(TAG, "Permissions library file " + f + " cannot be read"); 1261 continue; 1262 } 1263 1264 readPermissionsFromXml(f); 1265 } 1266 // �Ǹ�� platform.xml ����� 1267 // Read permissions from .../etc/permissions/platform.xml last so it will take precedence 1268 final File permFile = new File(Environment.getRootDirectory(), 1269 "etc/permissions/platform.xml"); 1270 readPermissionsFromXml(permFile); 1271 } 1272 1273 private void readPermissionsFromXml(File permFile) { 1274 FileReader permReader = null; 1275 try { 1276 permReader = new FileReader(permFile); 1277 } catch (FileNotFoundException e) { 1278 Slog.w(TAG, "Couldn't find or open permissions file " + permFile); 1279 return; 1280 } 1281 1282 try { 1283 XmlPullParser parser = Xml.newPullParser(); 1284 parser.setInput(permReader); 1285 1286 XmlUtils.beginDocument(parser, "permissions"); 1287 1288 while (true) { 1289 XmlUtils.nextElement(parser); 1290 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { 1291 break; 1292 } 1293 1294 String name = parser.getName(); 1295 if ("group".equals(name)) { 1296 String gidStr = parser.getAttributeValue(null, "gid"); 1297 if (gidStr != null) { 1298 int gid = Integer.parseInt(gidStr); 1299 mGlobalGids = appendInt(mGlobalGids, gid); 1300 } else { 1301 Slog.w(TAG, "without gid at " 1302 + parser.getPositionDescription()); 1303 } 1304 1305 XmlUtils.skipCurrentTag(parser); 1306 continue; 1307 } else if ("permission".equals(name)) { :
Settings.readLPw() / Settings.writeLPr()
frameworks/base/services/java/com/android/server/pm/Settings.java ���
// /data/system/packages.xml ���ѥå������ޤ��ξ��������� 1196 boolean readLPw() { 1197 FileInputStream str = null; 1198 if (mBackupSettingsFilename.exists()) { 1199 try { 1200 str = new FileInputStream(mBackupSettingsFilename); 1201 mReadMessages.append("Reading from backup settings file\n"); 1202 PackageManagerService.reportSettingsProblem(Log.INFO, 1203 "Need to read from backup settings file"); 1204 if (mSettingsFilename.exists()) { 1205 // If both the backup and settings file exist, we 1206 // ignore the settings since it might have been 1207 // corrupted. 1208 Slog.w(PackageManagerService.TAG, "Cleaning up settings file " 1209 + mSettingsFilename); 1210 mSettingsFilename.delete(); 1211 } 1212 } catch (java.io.IOException e) { 1213 // We'll try for the normal settings file. 1214 } 1215 } 1216 1217 mPendingPackages.clear(); 1218 mPastSignatures.clear(); 1219 1220 try { 1221 if (str == null) { 1222 if (!mSettingsFilename.exists()) { 1223 mReadMessages.append("No settings file found\n"); 1224 PackageManagerService.reportSettingsProblem(Log.INFO, 1225 "No settings file; creating initial state"); 1226 return false; 1227 } 1228 str = new FileInputStream(mSettingsFilename); 1229 } 1230 XmlPullParser parser = Xml.newPullParser(); 1231 parser.setInput(str, null); 1232 1233 int type; 1234 while ((type = parser.next()) != XmlPullParser.START_TAG 1235 && type != XmlPullParser.END_DOCUMENT) { 1236 ; 1237 } 1238 1239 if (type != XmlPullParser.START_TAG) { 1240 mReadMessages.append("No start tag found in settings file\n"); 1241 PackageManagerService.reportSettingsProblem(Log.WARN, 1242 "No start tag found in package manager settings"); 1243 Log.wtf(PackageManagerService.TAG, 1244 "No start tag found in package manager settings"); 1245 return false; 1246 } 1247 1248 int outerDepth = parser.getDepth(); 1249 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 1250 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 1251 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 1252 continue; 1253 } 1254 1255 String tagName = parser.getName(); 1256 if (tagName.equals("package")) { 1257 readPackageLPw(parser); 1258 } else if (tagName.equals("permissions")) { 1259 readPermissionsLPw(mPermissions, parser); 1260 } else if (tagName.equals("permission-trees")) { 1261 readPermissionsLPw(mPermissionTrees, parser); 1262 } else if (tagName.equals("shared-user")) { 1263 readSharedUserLPw(parser); 1264 } else if (tagName.equals("preferred-packages")) { 1265 // no longer used. 1266 } else if (tagName.equals("preferred-activities")) { 1267 readPreferredActivitiesLPw(parser); 1268 } else if (tagName.equals("updated-package")) { 1269 readDisabledSysPackageLPw(parser); 1270 } else if (tagName.equals("cleaning-package")) { 1271 String name = parser.getAttributeValue(null, "name"); 1272 if (name != null) { 1273 mPackagesToBeCleaned.add(name); 1274 } 1275 } else if (tagName.equals("renamed-package")) { 1276 String nname = parser.getAttributeValue(null, "new"); 1277 String oname = parser.getAttributeValue(null, "old"); 1278 if (nname != null && oname != null) { 1279 mRenamedPackages.put(nname, oname); 1280 } 1281 } else if (tagName.equals("last-platform-version")) { 1282 mInternalSdkPlatform = mExternalSdkPlatform = 0; 1283 try { 1284 String internal = parser.getAttributeValue(null, "internal"); 1285 if (internal != null) { 1286 mInternalSdkPlatform = Integer.parseInt(internal); 1287 } 1288 String external = parser.getAttributeValue(null, "external"); 1289 if (external != null) { 1290 mExternalSdkPlatform = Integer.parseInt(external); 1291 } 1292 } catch (NumberFormatException e) { 1293 } 1294 } else if (tagName.equals("verifier")) { 1295 final String deviceIdentity = parser.getAttributeValue(null, "device"); 1296 try { 1297 mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity); 1298 } catch (IllegalArgumentException e) { 1299 Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: " 1300 + e.getMessage()); 1301 } 1302 } else { 1303 Slog.w(PackageManagerService.TAG, "Unknown element under: " 1304 + parser.getName()); 1305 XmlUtils.skipCurrentTag(parser); 1306 } 1307 } 1308 1309 str.close(); 1310 1311 } catch (XmlPullParserException e) { 1312 mReadMessages.append("Error reading: " + e.toString()); 1313 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 1314 Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); 1315 1316 } catch (java.io.IOException e) { 1317 mReadMessages.append("Error reading: " + e.toString()); 1318 PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); 1319 Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); 1320 1321 } 1322 1323 final int N = mPendingPackages.size(); 1324 for (int i = 0; i < N; i++) { 1325 final PendingPackage pp = mPendingPackages.get(i); 1326 Object idObj = getUserIdLPr(pp.sharedId); 1327 if (idObj != null && idObj instanceof SharedUserSetting) { 1328 PackageSetting p = getPackageLPw(pp.name, null, pp.realName, 1329 (SharedUserSetting) idObj, pp.codePath, pp.resourcePath, 1330 pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags, true, true); 1331 if (p == null) { 1332 PackageManagerService.reportSettingsProblem(Log.WARN, 1333 "Unable to create application package for " + pp.name); 1334 continue; 1335 } 1336 p.copyFrom(pp); 1337 } else if (idObj != null) { 1338 String msg = "Bad package setting: package " + pp.name + " has shared uid " 1339 + pp.sharedId + " that is not a shared uid\n"; 1340 mReadMessages.append(msg); 1341 PackageManagerService.reportSettingsProblem(Log.ERROR, msg); 1342 } else { 1343 String msg = "Bad package setting: package " + pp.name + " has shared uid " 1344 + pp.sharedId + " that is not defined\n"; 1345 mReadMessages.append(msg); 1346 PackageManagerService.reportSettingsProblem(Log.ERROR, msg); 1347 } 1348 } 1349 mPendingPackages.clear(); 1350 1351 /* 1352 * Make sure all the updated system packages have their shared users 1353 * associated with them. 1354 */ 1355 final IteratordisabledIt = mDisabledSysPackages.values().iterator(); 1356 while (disabledIt.hasNext()) { 1357 final PackageSetting disabledPs = disabledIt.next(); 1358 final Object id = getUserIdLPr(disabledPs.userId); 1359 if (id != null && id instanceof SharedUserSetting) { 1360 disabledPs.sharedUser = (SharedUserSetting) id; 1361 } 1362 } 1363 1364 readStoppedLPw(); 1365 1366 mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, " 1367 + mSharedUsers.size() + " shared uids\n"); 1368 1369 return true; 1370 } : // /data/system/packages.xml, packages.list �إѥå������ޤ��ξ������¸ 833 void writeLPr() { 834 //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024); 835 836 // Keep the old settings around until we know the new ones have 837 // been successfully written. 838 if (mSettingsFilename.exists()) { 839 // Presence of backup settings file indicates that we failed 840 // to persist settings earlier. So preserve the older 841 // backup for future reference since the current settings 842 // might have been corrupted. 843 if (!mBackupSettingsFilename.exists()) { 844 if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) { 845 Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, " 846 + " current changes will be lost at reboot"); 847 return; 848 } 849 } else { 850 mSettingsFilename.delete(); 851 Slog.w(PackageManagerService.TAG, "Preserving older settings backup"); 852 } 853 } 854 855 mPastSignatures.clear(); 856 857 try { 858 FileOutputStream fstr = new FileOutputStream(mSettingsFilename); 859 BufferedOutputStream str = new BufferedOutputStream(fstr); 860 861 //XmlSerializer serializer = XmlUtils.serializerInstance(); 862 XmlSerializer serializer = new FastXmlSerializer(); 863 serializer.setOutput(str, "utf-8"); 864 serializer.startDocument(null, true); 865 serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 866 867 serializer.startTag(null, "packages"); 868 869 serializer.startTag(null, "last-platform-version"); 870 serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform)); 871 serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform)); 872 serializer.endTag(null, "last-platform-version"); 873 874 if (mVerifierDeviceIdentity != null) { 875 serializer.startTag(null, "verifier"); 876 serializer.attribute(null, "device", mVerifierDeviceIdentity.toString()); 877 serializer.endTag(null, "verifier"); 878 } 879 880 serializer.startTag(null, "permission-trees"); 881 for (BasePermission bp : mPermissionTrees.values()) { 882 writePermissionLPr(serializer, bp); 883 } 884 serializer.endTag(null, "permission-trees"); 885 886 serializer.startTag(null, "permissions"); 887 for (BasePermission bp : mPermissions.values()) { 888 writePermissionLPr(serializer, bp); 889 } 890 serializer.endTag(null, "permissions"); 891 892 for (final PackageSetting pkg : mPackages.values()) { 893 writePackageLPr(serializer, pkg); 894 } 895 896 for (final PackageSetting pkg : mDisabledSysPackages.values()) { 897 writeDisabledSysPackageLPr(serializer, pkg); 898 } 899 900 serializer.startTag(null, "preferred-activities"); 901 for (final PreferredActivity pa : mPreferredActivities.filterSet()) { 902 serializer.startTag(null, "item"); 903 pa.writeToXml(serializer); 904 serializer.endTag(null, "item"); 905 } 906 serializer.endTag(null, "preferred-activities"); 907 908 for (final SharedUserSetting usr : mSharedUsers.values()) { 909 serializer.startTag(null, "shared-user"); 910 serializer.attribute(null, "name", usr.name); 911 serializer.attribute(null, "userId", 912 Integer.toString(usr.userId)); 913 usr.signatures.writeXml(serializer, "sigs", mPastSignatures); 914 serializer.startTag(null, "perms"); 915 for (String name : usr.grantedPermissions) { 916 serializer.startTag(null, "item"); 917 serializer.attribute(null, "name", name); 918 serializer.endTag(null, "item"); 919 } 920 serializer.endTag(null, "perms"); 921 serializer.endTag(null, "shared-user"); 922 } 923 924 if (mPackagesToBeCleaned.size() > 0) { 925 for (int i=0; i 0) { 933 for (HashMap.Entry e : mRenamedPackages.entrySet()) { 934 serializer.startTag(null, "renamed-package"); 935 serializer.attribute(null, "new", e.getKey()); 936 serializer.attribute(null, "old", e.getValue()); 937 serializer.endTag(null, "renamed-package"); 938 } 939 } 940 941 serializer.endTag(null, "packages"); 942 943 serializer.endDocument(); 944 945 str.flush(); 946 FileUtils.sync(fstr); 947 str.close(); 948 949 // New settings successfully written, old ones are no longer 950 // needed. 951 mBackupSettingsFilename.delete(); 952 FileUtils.setPermissions(mSettingsFilename.toString(), 953 FileUtils.S_IRUSR|FileUtils.S_IWUSR 954 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 955 |FileUtils.S_IROTH, 956 -1, -1); 957 958 // Write package list file now, use a JournaledFile. 959 // 960 File tempFile = new File(mPackageListFilename.toString() + ".tmp"); 961 JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile); 962 963 fstr = new FileOutputStream(journal.chooseForWrite()); 964 str = new BufferedOutputStream(fstr); 965 try { 966 StringBuilder sb = new StringBuilder(); 967 for (final PackageSetting pkg : mPackages.values()) { 968 ApplicationInfo ai = pkg.pkg.applicationInfo; 969 String dataPath = ai.dataDir; 970 boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 971 972 // Avoid any application that has a space in its path 973 // or that is handled by the system. 974 if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID) 975 continue; 976 977 // we store on each line the following information for now: 978 // 979 // pkgName - package name 980 // userId - application-specific user id 981 // debugFlag - 0 or 1 if the package is debuggable. 982 // dataPath - path to package's data path 983 // 984 // NOTE: We prefer not to expose all ApplicationInfo flags for now. 985 // 986 // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS 987 // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES: 988 // system/core/run-as/run-as.c 989 // 990 sb.setLength(0); 991 sb.append(ai.packageName); 992 sb.append(" "); 993 sb.append((int)ai.uid); 994 sb.append(isDebug ? " 1 " : " 0 "); 995 sb.append(dataPath); 996 sb.append("\n"); 997 str.write(sb.toString().getBytes()); 998 } 999 str.flush(); 1000 FileUtils.sync(fstr); 1001 str.close(); 1002 journal.commit(); 1003 } catch (Exception e) { 1004 IoUtils.closeQuietly(str); 1005 journal.rollback(); 1006 } 1007 1008 FileUtils.setPermissions(mPackageListFilename.toString(), 1009 FileUtils.S_IRUSR|FileUtils.S_IWUSR 1010 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 1011 |FileUtils.S_IROTH, 1012 -1, -1); 1013 1014 writeStoppedLPr(); 1015 1016 return; 1017 1018 } catch(XmlPullParserException e) { 1019 Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " 1020 + "current changes will be lost at reboot", e); 1021 } catch(java.io.IOException e) { 1022 Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " 1023 + "current changes will be lost at reboot", e); 1024 } 1025 // Clean up partially written files 1026 if (mSettingsFilename.exists()) { 1027 if (!mSettingsFilename.delete()) { 1028 Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + mSettingsFilename); 1029 } 1030 } 1031 //Debug.stopMethodTracing(); 1032 } 1033 1034 void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg) 1035 throws java.io.IOException { 1036 serializer.startTag(null, "updated-package"); 1037 serializer.attribute(null, "name", pkg.name); 1038 if (pkg.realName != null) { 1039 serializer.attribute(null, "realName", pkg.realName); 1040 } 1041 serializer.attribute(null, "codePath", pkg.codePathString); 1042 serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); 1043 serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); 1044 serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); 1045 serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); 1046 if (!pkg.resourcePathString.equals(pkg.codePathString)) { 1047 serializer.attribute(null, "resourcePath", pkg.resourcePathString); 1048 } 1049 if (pkg.nativeLibraryPathString != null) { 1050 serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString); 1051 } 1052 if (pkg.sharedUser == null) { 1053 serializer.attribute(null, "userId", Integer.toString(pkg.userId)); 1054 } else { 1055 serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId)); 1056 } 1057 serializer.startTag(null, "perms"); 1058 if (pkg.sharedUser == null) { 1059 // If this is a shared user, the permissions will 1060 // be written there. We still need to write an 1061 // empty permissions list so permissionsFixed will 1062 // be set. 1063 for (final String name : pkg.grantedPermissions) { 1064 BasePermission bp = mPermissions.get(name); 1065 if (bp != null) { 1066 // We only need to write signature or system permissions but 1067 // this wont 1068 // match the semantics of grantedPermissions. So write all 1069 // permissions. 1070 serializer.startTag(null, "item"); 1071 serializer.attribute(null, "name", name); 1072 serializer.endTag(null, "item"); 1073 } 1074 } 1075 } 1076 serializer.endTag(null, "perms"); 1077 serializer.endTag(null, "updated-package"); 1078 } 1079 1080 void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg) 1081 throws java.io.IOException { 1082 serializer.startTag(null, "package"); 1083 serializer.attribute(null, "name", pkg.name); 1084 if (pkg.realName != null) { 1085 serializer.attribute(null, "realName", pkg.realName); 1086 } 1087 serializer.attribute(null, "codePath", pkg.codePathString); 1088 if (!pkg.resourcePathString.equals(pkg.codePathString)) { 1089 serializer.attribute(null, "resourcePath", pkg.resourcePathString); 1090 } 1091 if (pkg.nativeLibraryPathString != null) { 1092 serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString); 1093 } 1094 serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags)); 1095 serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); 1096 serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); 1097 serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); 1098 serializer.attribute(null, "version", String.valueOf(pkg.versionCode)); 1099 if (pkg.sharedUser == null) { 1100 serializer.attribute(null, "userId", Integer.toString(pkg.userId)); 1101 } else { 1102 serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId)); 1103 } 1104 if (pkg.uidError) { 1105 serializer.attribute(null, "uidError", "true"); 1106 } 1107 if (pkg.enabled != COMPONENT_ENABLED_STATE_DEFAULT) { 1108 serializer.attribute(null, "enabled", Integer.toString(pkg.enabled)); 1109 } 1110 if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) { 1111 serializer.attribute(null, "installStatus", "false"); 1112 } 1113 if (pkg.installerPackageName != null) { 1114 serializer.attribute(null, "installer", pkg.installerPackageName); 1115 } 1116 pkg.signatures.writeXml(serializer, "sigs", mPastSignatures); 1117 if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1118 serializer.startTag(null, "perms"); 1119 if (pkg.sharedUser == null) { 1120 // If this is a shared user, the permissions will 1121 // be written there. We still need to write an 1122 // empty permissions list so permissionsFixed will 1123 // be set. 1124 for (final String name : pkg.grantedPermissions) { 1125 serializer.startTag(null, "item"); 1126 serializer.attribute(null, "name", name); 1127 serializer.endTag(null, "item"); 1128 } 1129 } 1130 serializer.endTag(null, "perms"); 1131 } 1132 if (pkg.disabledComponents.size() > 0) { 1133 serializer.startTag(null, "disabled-components"); 1134 for (final String name : pkg.disabledComponents) { 1135 serializer.startTag(null, "item"); 1136 serializer.attribute(null, "name", name); 1137 serializer.endTag(null, "item"); 1138 } 1139 serializer.endTag(null, "disabled-components"); 1140 } 1141 if (pkg.enabledComponents.size() > 0) { 1142 serializer.startTag(null, "enabled-components"); 1143 for (final String name : pkg.enabledComponents) { 1144 serializer.startTag(null, "item"); 1145 serializer.attribute(null, "name", name); 1146 serializer.endTag(null, "item"); 1147 } 1148 serializer.endTag(null, "enabled-components"); 1149 } 1150 1151 serializer.endTag(null, "package"); 1152 } 1153 1154 void writePermissionLPr(XmlSerializer serializer, BasePermission bp) 1155 throws XmlPullParserException, java.io.IOException { 1156 if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) { 1157 serializer.startTag(null, "item"); 1158 serializer.attribute(null, "name", bp.name); 1159 serializer.attribute(null, "package", bp.sourcePackage); 1160 if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) { 1161 serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel)); 1162 } 1163 if (PackageManagerService.DEBUG_SETTINGS) 1164 Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type=" 1165 + bp.type); 1166 if (bp.type == BasePermission.TYPE_DYNAMIC) { 1167 final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo; 1168 if (pi != null) { 1169 serializer.attribute(null, "type", "dynamic"); 1170 if (pi.icon != 0) { 1171 serializer.attribute(null, "icon", Integer.toString(pi.icon)); 1172 } 1173 if (pi.nonLocalizedLabel != null) { 1174 serializer.attribute(null, "label", pi.nonLocalizedLabel.toString()); 1175 } 1176 } 1177 } 1178 serializer.endTag(null, "item"); 1179 } 1180 }
PackageSignatures.writeXml()
frameworks/base/services/java/com/android/server/pm/PackageSignatures.java ���
�ѥå������ν�̾��������륯�饹 31 class PackageSignatures { 32 Signature[] mSignatures; 33 34 PackageSignatures(PackageSignatures orig) { 35 if (orig != null && orig.mSignatures != null) { 36 mSignatures = orig.mSignatures.clone(); 37 } 38 } 39 40 PackageSignatures(Signature[] sigs) { 41 assignSignatures(sigs); 42 } 43 44 PackageSignatures() { 45 } 46 47 void writeXml(XmlSerializer serializer, String tagName, 48 ArrayList<Signature> pastSignatures) throws IOException { 49 if (mSignatures == null) { 50 return; 51 } 52 serializer.startTag(null, tagName); 53 serializer.attribute(null, "count", 54 Integer.toString(mSignatures.length)); 55 for (int i=0; i<mSignatures.length; i++) { 56 serializer.startTag(null, "cert"); 57 final Signature sig = mSignatures[i]; 58 final int sigHash = sig.hashCode(); 59 final int numPast = pastSignatures.size(); 60 int j; 61 for (j=0; j<numPast; j++) { 62 Signature pastSig = pastSignatures.get(j); // Ʊ��� key ����Ϥ��ߤʤ� index �Τߤ�ñ¤½Ð¤ï¿½ 63 if (pastSig.hashCode() == sigHash && pastSig.equals(sig)) { 64 serializer.attribute(null, "index", Integer.toString(j)); 65 break; 66 } 67 } 68 if (j >= numPast) { // ���ʬ�Τ� index �� key ��ñ¤½Ð¤ï¿½ // �����ǸƤӸ��� Settings.mPastSignatures �� add ����� 69 pastSignatures.add(sig); 70 serializer.attribute(null, "index", Integer.toString(numPast)); 71 serializer.attribute(null, "key", sig.toCharsString()); 72 } 73 serializer.endTag(null, "cert"); 74 } 75 serializer.endTag(null, tagName); 76 } :
PreferredActivity.writeToXml()
frameworks/base/services/java/com/android/server/pm/PreferredActivity.java ���
PreferredActivity ���饹 17 package com.android.server.pm; : 32 class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks { 33 private static final String TAG = "PreferredActivity"; 34 35 private static final boolean DEBUG_FILTERS = false; 36 37 final PreferredComponent mPref; 38 39 PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { 40 super(filter); 41 mPref = new PreferredComponent(this, match, set, activity); 42 } 43 44 PreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException { 45 mPref = new PreferredComponent(this, parser); 46 } 47 48 public void writeToXml(XmlSerializer serializer) throws IOException { 49 mPref.writeToXml(serializer); 50 serializer.startTag(null, "filter"); 51 super.writeToXml(serializer); 52 serializer.endTag(null, "filter"); 53 } :
PreferredComponent.writeToXml()
frameworks/services/java/com/android/server/PreferredComponent.java ���
PreferredComponent ���饹 17 package com.android.server; : 35 public class PreferredComponent { 36 public final int mMatch; 37 public final ComponentName mComponent; 38 39 private final String[] mSetPackages; 40 private final String[] mSetClasses; 41 private final String[] mSetComponents; 42 private final String mShortComponent; 43 private String mParseError; 44 45 private final Callbacks mCallbacks; 46 47 public interface Callbacks { 48 public boolean onReadTag(String tagName, XmlPullParser parser) 49 throws XmlPullParserException, IOException; 50 } 51 52 public PreferredComponent(Callbacks callbacks, int match, ComponentName[] set, 53 ComponentName component) { 54 mCallbacks = callbacks; 55 mMatch = match&IntentFilter.MATCH_CATEGORY_MASK; 56 mComponent = component; 57 mShortComponent = component.flattenToShortString(); 58 mParseError = null; 59 if (set != null) { 60 final int N = set.length; 61 String[] myPackages = new String[N]; 62 String[] myClasses = new String[N]; 63 String[] myComponents = new String[N]; 64 for (int i=0; i<N; i++) { 65 ComponentName cn = set[i]; 66 if (cn == null) { 67 mSetPackages = null; 68 mSetClasses = null; 69 mSetComponents = null; 70 return; 71 } 72 myPackages[i] = cn.getPackageName().intern(); 73 myClasses[i] = cn.getClassName().intern(); 74 myComponents[i] = cn.flattenToShortString().intern(); 75 } 76 mSetPackages = myPackages; 77 mSetClasses = myClasses; 78 mSetComponents = myComponents; 79 } else { 80 mSetPackages = null; 81 mSetClasses = null; 82 mSetComponents = null; 83 } 84 } 85 86 public PreferredComponent(Callbacks callbacks, XmlPullParser parser) 87 throws XmlPullParserException, IOException { 88 mCallbacks = callbacks; 89 mShortComponent = parser.getAttributeValue(null, "name"); 90 mComponent = ComponentName.unflattenFromString(mShortComponent); 91 if (mComponent == null) { 92 mParseError = "Bad activity name " + mShortComponent; 93 } 94 String matchStr = parser.getAttributeValue(null, "match"); 95 mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0; 96 String setCountStr = parser.getAttributeValue(null, "set"); 97 int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0; 98 99 String[] myPackages = setCount > 0 ? new String[setCount] : null; 100 String[] myClasses = setCount > 0 ? new String[setCount] : null; 101 String[] myComponents = setCount > 0 ? new String[setCount] : null; 102 103 int setPos = 0; 104 105 int outerDepth = parser.getDepth(); 106 int type; 107 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 108 && (type != XmlPullParser.END_TAG 109 || parser.getDepth() > outerDepth)) { 110 if (type == XmlPullParser.END_TAG 111 || type == XmlPullParser.TEXT) { 112 continue; 113 } 114 115 String tagName = parser.getName(); 116 //Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth=" 117 // + parser.getDepth() + " tag=" + tagName); 118 if (tagName.equals("set")) { 119 String name = parser.getAttributeValue(null, "name"); 120 if (name == null) { 121 if (mParseError == null) { 122 mParseError = "No name in set tag in preferred activity " 123 + mShortComponent; 124 } 125 } else if (setPos >= setCount) { 126 if (mParseError == null) { 127 mParseError = "Too many set tags in preferred activity " 128 + mShortComponent; 129 } 130 } else { 131 ComponentName cn = ComponentName.unflattenFromString(name); 132 if (cn == null) { 133 if (mParseError == null) { 134 mParseError = "Bad set name " + name + " in preferred activity " 135 + mShortComponent; 136 } 137 } else { 138 myPackages[setPos] = cn.getPackageName(); 139 myClasses[setPos] = cn.getClassName(); 140 myComponents[setPos] = name; 141 setPos++; 142 } 143 } 144 XmlUtils.skipCurrentTag(parser); 145 } else if (!mCallbacks.onReadTag(tagName, parser)) { 146 Slog.w("PreferredComponent", "Unknown element: " + parser.getName()); 147 XmlUtils.skipCurrentTag(parser); 148 } 149 } 150 151 if (setPos != setCount) { 152 if (mParseError == null) { 153 mParseError = "Not enough set tags (expected " + setCount 154 + " but found " + setPos + ") in " + mShortComponent; 155 } 156 } 157 158 mSetPackages = myPackages; 159 mSetClasses = myClasses; 160 mSetComponents = myComponents; 161 } 162 163 public String getParseError() { 164 return mParseError; 165 } 166 167 public void writeToXml(XmlSerializer serializer) throws IOException { 168 final int NS = mSetClasses != null ? mSetClasses.length : 0; 169 serializer.attribute(null, "name", mShortComponent); 170 if (mMatch != 0) { 171 serializer.attribute(null, "match", Integer.toHexString(mMatch)); 172 } 173 serializer.attribute(null, "set", Integer.toString(NS)); 174 for (int s=0; s<NS; s++) { 175 serializer.startTag(null, "set"); 176 serializer.attribute(null, "name", mSetComponents[s]); 177 serializer.endTag(null, "set"); 178 } 179 } :
IntentFilter.writeToXml()
/frameworks/core/java/android/content/IntentFilter.java ���
IntentFilter ���饹 17 package android.content; : 129 public class IntentFilter implements Parcelable { 130 private static final String SGLOB_STR = "sglob"; 131 private static final String PREFIX_STR = "prefix"; 132 private static final String LITERAL_STR = "literal"; 133 private static final String PATH_STR = "path"; 134 private static final String PORT_STR = "port"; 135 private static final String HOST_STR = "host"; 136 private static final String AUTH_STR = "auth"; 137 private static final String SCHEME_STR = "scheme"; 138 private static final String TYPE_STR = "type"; 139 private static final String CAT_STR = "cat"; 140 private static final String NAME_STR = "name"; 141 private static final String ACTION_STR = "action"; : 1145 /** 1146 * Write the contents of the IntentFilter as an XML stream. 1147 */ 1148 public void writeToXml(XmlSerializer serializer) throws IOException { 1149 int N = countActions(); 1150 for (int i=0; i<N; i++) { 1151 serializer.startTag(null, ACTION_STR); 1152 serializer.attribute(null, NAME_STR, mActions.get(i)); 1153 serializer.endTag(null, ACTION_STR); 1154 } 1155 N = countCategories(); 1156 for (int i=0; i<N; i++) { 1157 serializer.startTag(null, CAT_STR); 1158 serializer.attribute(null, NAME_STR, mCategories.get(i)); 1159 serializer.endTag(null, CAT_STR); 1160 } 1161 N = countDataTypes(); 1162 for (int i=0; i<N; i++) { 1163 serializer.startTag(null, TYPE_STR); 1164 String type = mDataTypes.get(i); 1165 if (type.indexOf('/') < 0) type = type + "/*"; 1166 serializer.attribute(null, NAME_STR, type); 1167 serializer.endTag(null, TYPE_STR); 1168 } 1169 N = countDataSchemes(); 1170 for (int i=0; i<N; i++) { 1171 serializer.startTag(null, SCHEME_STR); 1172 serializer.attribute(null, NAME_STR, mDataSchemes.get(i)); 1173 serializer.endTag(null, SCHEME_STR); 1174 } 1175 N = countDataAuthorities(); 1176 for (int i=0; i<N; i++) { 1177 serializer.startTag(null, AUTH_STR); 1178 AuthorityEntry ae = mDataAuthorities.get(i); 1179 serializer.attribute(null, HOST_STR, ae.getHost()); 1180 if (ae.getPort() >= 0) { 1181 serializer.attribute(null, PORT_STR, Integer.toString(ae.getPort())); 1182 } 1183 serializer.endTag(null, AUTH_STR); 1184 } 1185 N = countDataPaths(); 1186 for (int i=0; i<N; i++) { 1187 serializer.startTag(null, PATH_STR); 1188 PatternMatcher pe = mDataPaths.get(i); 1189 switch (pe.getType()) { 1190 case PatternMatcher.PATTERN_LITERAL: 1191 serializer.attribute(null, LITERAL_STR, pe.getPath()); 1192 break; 1193 case PatternMatcher.PATTERN_PREFIX: 1194 serializer.attribute(null, PREFIX_STR, pe.getPath()); 1195 break; 1196 case PatternMatcher.PATTERN_SIMPLE_GLOB: 1197 serializer.attribute(null, SGLOB_STR, pe.getPath()); 1198 break; 1199 } 1200 serializer.endTag(null, PATH_STR); 1201 } 1202 } :
AppDirObserver �ˤ�륤�󥹥ȡ��롦���󥤥󥹥ȡ���μ�ư����
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
���ꤵ�줿�ǥ��쥯�ȥ�ľ����ƻ뤷 *.apk ��������ɲä����м�ư�������륯�饹 4803 private final class AppDirObserver extends FileObserver { 4804 public AppDirObserver(String path, int mask, boolean isrom) { 4805 super(path, mask); 4806 mRootDir = path; 4807 mIsRom = isrom; 4808 } 4809 4810 public void onEvent(int event, String path) { 4811 String removedPackage = null; 4812 int removedUid = -1; 4813 String addedPackage = null; 4814 int addedUid = -1; 4815 4816 // TODO post a message to the handler to obtain serial ordering 4817 synchronized (mInstallLock) { 4818 String fullPathStr = null; 4819 File fullPath = null; 4820 if (path != null) { 4821 fullPath = new File(mRootDir, path); 4822 fullPathStr = fullPath.getPath(); 4823 } 4824 4825 if (DEBUG_APP_DIR_OBSERVER) 4826 Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event)); 4827 // *.apk �ʳ����Ƥ� 4828 if (!isPackageFilename(path)) { 4829 if (DEBUG_APP_DIR_OBSERVER) 4830 Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr); 4831 return; 4832 } 4833 // ¾�η�ϩ�ǥ��󥹥ȡ��뤵�줿�ѥå������ϴDz� 4834 // Ignore packages that are being installed or 4835 // have just been installed. 4836 if (ignoreCodePath(fullPathStr)) { 4837 return; 4838 } 4839 PackageParser.Package p = null; 4840 // reader 4841 synchronized (mPackages) { 4842 p = mAppDirs.get(fullPathStr); 4843 } // �ѥå�����������ޤ��ϰ�ư���줿��� 4844 if ((event&REMOVE_EVENTS) != 0) { 4845 if (p != null) { 4846 removePackageLI(p, true); 4847 removedPackage = p.applicationInfo.packageName; 4848 removedUid = p.applicationInfo.uid; 4849 } 4850 } 4851 // �ѥå��������ɲä��줿��� 4852 if ((event&ADD_EVENTS) != 0) { 4853 if (p == null) { 4854 p = scanPackageLI(fullPath, 4855 (mIsRom ? PackageParser.PARSE_IS_SYSTEM 4856 | PackageParser.PARSE_IS_SYSTEM_DIR: 0) | 4857 PackageParser.PARSE_CHATTY | 4858 PackageParser.PARSE_MUST_BE_APK, 4859 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME, 4860 System.currentTimeMillis()); 4861 if (p != null) { 4862 /* 4863 * TODO this seems dangerous as the package may have 4864 * changed since we last acquired the mPackages 4865 * lock. 4866 */ 4867 // writer 4868 synchronized (mPackages) { 4869 updatePermissionsLPw(p.packageName, p, 4870 p.permissions.size() > 0, false, false); 4871 } 4872 addedPackage = p.applicationInfo.packageName; 4873 addedUid = p.applicationInfo.uid; 4874 } 4875 } 4876 } 4877 4878 // reader 4879 synchronized (mPackages) { // /data/system/packages.xml, packages.list ��ǿ��ξ��֤˹��� 4880 mSettings.writeLPr(); 4881 } 4882 } 4883 // ���󥤥󥹥ȡ��봰λ or ���󥹥ȡ��봰λ��֥����ɥ��㥹�� 4884 if (removedPackage != null) { 4885 Bundle extras = new Bundle(1); 4886 extras.putInt(Intent.EXTRA_UID, removedUid); 4887 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false); 4888 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 4889 extras, null, null); 4890 } 4891 if (addedPackage != null) { 4892 Bundle extras = new Bundle(1); 4893 extras.putInt(Intent.EXTRA_UID, addedUid); 4894 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, 4895 extras, null, null); 4896 } 4897 } 4898 4899 private final String mRootDir; 4900 private final boolean mIsRom; 4901 }
PackageManagerService.scanDirLI()
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
// ����ǥ��쥯�ȥ겼�� apk ����������̵���ʤ�Τ�����к�� 2753 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) { 2754 String[] files = dir.list(); 2755 if (files == null) { 2756 Log.d(TAG, "No files in app dir " + dir); 2757 return; 2758 } 2759 2760 if (DEBUG_PACKAGE_SCANNING) { 2761 Log.d(TAG, "Scanning app dir " + dir); 2762 } 2763 2764 int i; 2765 for (i=0; i<files.length; i++) { 2766 File file = new File(dir, files[i]); 2767 if (!isPackageFilename(files[i])) { 2768 // Ignore entries which are not apk's 2769 continue; 2770 } // apk ����ѥå������������� 2771 PackageParser.Package pkg = scanPackageLI(file, 2772 flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime); 2773 // Don't mess around with apps in system partition. 2774 if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 && 2775 mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) { 2776 // Delete the apk 2777 Slog.w(TAG, "Cleaning up failed install of " + file); 2778 file.delete(); 2779 } 2780 } 2781 }
PackageManagerService.scanPackageLI()
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
// ���� apk �Υѥå����������������䴰�ξ塢���ץꥱ�������ǥ��쥯�ȥ�Í̵�� // �����å���Ԥ�Ŭ�������ޤ��Ͽ������������ѥå���������������ơ��֥���ɲ� 2835 /* 2836 * Scan a package and return the newly parsed package. 2837 * Returns null in case of errors and the error code is stored in mLastScanError 2838 */ 2839 private PackageParser.Package scanPackageLI(File scanFile, 2840 int parseFlags, int scanMode, long currentTime) { 2841 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 2842 String scanPath = scanFile.getPath(); 2843 parseFlags |= mDefParseFlags; 2844 PackageParser pp = new PackageParser(scanPath); 2845 pp.setSeparateProcesses(mSeparateProcesses); 2846 pp.setOnlyCoreApps(mOnlyCore); // ���� apk �Υѥå���������������� 2847 final PackageParser.Package pkg = pp.parsePackage(scanFile, 2848 scanPath, mMetrics, parseFlags); 2849 if (pkg == null) { 2850 mLastScanError = pp.getParseError(); 2851 return null; 2852 } 2853 PackageSetting ps = null; 2854 PackageSetting updatedPkg; 2855 // reader 2856 synchronized (mPackages) { 2857 // Look to see if we already know about this package. 2858 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 2859 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 2860 // This package has been renamed to its original name. Let's 2861 // use that. 2862 ps = mSettings.peekPackageLPr(oldName); 2863 } 2864 // If there was no original package, see one for the real package name. 2865 if (ps == null) { 2866 ps = mSettings.peekPackageLPr(pkg.packageName); 2867 } 2868 // Check to see if this package could be hiding/updating a system 2869 // package. Must look for it either under the original or real 2870 // package name depending on our state. 2871 updatedPkg = mSettings.mDisabledSysPackages.get( 2872 ps != null ? ps.name : pkg.packageName); 2873 } : // �ѥå������ξ���������������ǧ 2915 // Verify certificates against what was last scanned 2916 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { 2917 Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName); 2918 return null; 2919 } 2920 // The apk is forward locked (not public) if its code and resources 2921 // are kept in different files. 2922 // TODO grab this value from PackageSettings 2923 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 2924 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 2925 } 2927 String codePath = null; 2926 2928 String resPath = null; 2929 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) { 2930 if (ps != null && ps.resourcePathString != null) { 2931 resPath = ps.resourcePathString; 2932 } else { 2933 // Should not happen at all. Just log an error. 2934 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 2935 } 2936 } else { 2937 resPath = pkg.mScanPath; 2938 } 2939 codePath = pkg.mScanPath; 2940 // Set application objects path explicitly. 2941 setApplicationInfoPaths(pkg, codePath, resPath); 2942 // Note that we invoke the following method only if we are about to unpack an application 2943 return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime); 2944 } : // �ѥå������ξ���������������ǧ 2808 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps, 2809 PackageParser.Package pkg, File srcFile, int parseFlags) { 2810 if (GET_CERTIFICATES) { 2811 if (ps != null 2812 && ps.codePath.equals(srcFile) 2813 && ps.timeStamp == srcFile.lastModified()) { 2814 if (ps.signatures.mSignatures != null 2815 && ps.signatures.mSignatures.length != 0) { 2816 // Optimization: reuse the existing cached certificates 2817 // if the package appears to be unchanged. 2818 pkg.mSignatures = ps.signatures.mSignatures; 2819 return true; 2820 } 2821 2822 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); 2823 } else { 2824 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 2825 } 2826 2827 if (!pp.collectCertificates(pkg, parseFlags)) { 2828 mLastScanError = pp.getParseError(); 2829 return false; 2830 } 2831 } 2832 return true; 2833 } : 3127 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, 3128 int parseFlags, int scanMode, long currentTime) { 3129 File scanFile = new File(pkg.mScanPath); : 3137 mScanningPath = scanFile; : 3190 // Initialize package source and resource directories 3191 File destCodeFile = new File(pkg.applicationInfo.sourceDir); 3192 File destResourceFile = new File(pkg.applicationInfo.publicSourceDir); 3193 3194 SharedUserSetting suid = null; 3195 PackageSetting pkgSetting = null; 3196 3197 if (!isSystemApp(pkg)) { 3198 // Only system apps can use these features. 3199 pkg.mOriginalPackages = null; 3200 pkg.mRealPackage = null; 3201 pkg.mAdoptPermissions = null; 3202 } 3203 3204 // writer 3205 synchronized (mPackages) { : // �ѥå������� SharedUserId ���ꤢ��ʤ餽�� UID ����� 3245 if (pkg.mSharedUserId != null) { 3246 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 3247 pkg.applicationInfo.flags, true); 3248 if (suid == null) { 3249 Slog.w(TAG, "Creating application package " + pkg.packageName 3250 + " for shared user failed"); 3251 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3252 return null; 3253 } 3254 if (DEBUG_PACKAGE_SCANNING) { 3255 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 3256 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 3257 + "): packages=" + suid.packages); 3258 } 3259 } 3260 3261 // Check if we are renaming from an original package name. : // Settings ���饹�δ������� mPackages �ơ��֥�����ǤǤ��� PackageSetting ����� // ���� or ¸�ߤ��ʤ���п������������ѥ�᡼�������� false �� mPackages �ơ��֥�ؤ� // ��ư�ɲä��޻ߤ���ե饰 3316 // Just create the setting, don't add it yet. For already existing packages 3317 // the PkgSetting exists already and doesn't have to be created. 3318 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 3319 destResourceFile, pkg.applicationInfo.nativeLibraryDir, 3320 pkg.applicationInfo.flags, true, false); 3321 if (pkgSetting == null) { 3322 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed"); 3323 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3324 return null; 3325 } : // �ѥå������� UID �ò¥»¥Ã¥ï¿½ 3355 pkg.applicationInfo.uid = pkgSetting.userId; 3356 pkg.mExtras = pkgSetting; : 3426 } 3427 3428 final String pkgName = pkg.packageName; 3429 3430 final long scanFileTime = scanFile.lastModified(); 3431 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 3432 pkg.applicationInfo.processName = fixProcessName( 3433 pkg.applicationInfo.packageName, 3434 pkg.applicationInfo.processName, 3435 pkg.applicationInfo.uid); 3436 3437 File dataPath; 3438 if (mPlatformPackage == pkg) { 3439 // The system package is special. 3440 dataPath = new File (Environment.getDataDirectory(), "system"); 3441 pkg.applicationInfo.dataDir = dataPath.getPath(); 3442 } else { 3443 // This is a normal package, need to make its data directory. 3444 dataPath = getDataPathForPackage(pkg.packageName, 0); 3445 3446 boolean uidError = false; 3447 // ���ץꥱ�������Υǡ����ǥ��쥯�ȥ꤬��¸�ʢ⥤�󥹥ȡ��뤺�ߡˤξ�� 3448 if (dataPath.exists()) { 3449 mOutPermissions[1] = 0; 3450 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions); 3451 // UID �����פ��ʤ���Х��󥤥󥹥ȡ���ξ�ƥ��󥹥ȡ�����ߤ� 3452 // If we have mismatched owners for the data path, we have a problem. 3453 if (mOutPermissions[1] != pkg.applicationInfo.uid) { 3454 boolean recovered = false; 3455 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 3456 // If this is a system app, we can at least delete its 3457 // current data so the application will still work. 3458 int ret = mInstaller.remove(pkgName, 0); 3459 if (ret >= 0) { 3460 // TODO: Kill the processes first 3461 // Remove the data directories for all users 3462 mUserManager.removePackageForAllUsers(pkgName); 3463 // Old data gone! 3464 String msg = "System package " + pkg.packageName 3465 + " has changed from uid: " 3466 + mOutPermissions[1] + " to " 3467 + pkg.applicationInfo.uid + "; old data erased"; 3468 reportSettingsProblem(Log.WARN, msg); 3469 recovered = true; 3470 3471 // And now re-install the app. 3472 ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, 3473 pkg.applicationInfo.uid); 3474 if (ret == -1) { 3475 // Ack should not happen! 3476 msg = "System package " + pkg.packageName 3477 + " could not have data directory re-created after delete."; 3478 reportSettingsProblem(Log.WARN, msg); 3479 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3480 return null; 3481 } 3482 // Create data directories for all users 3483 mUserManager.installPackageForAllUsers(pkgName, 3484 pkg.applicationInfo.uid); 3485 } 3486 if (!recovered) { 3487 mHasSystemUidErrors = true; 3488 } 3489 } 3490 if (!recovered) { 3491 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 3492 + pkg.applicationInfo.uid + "/fs_" 3493 + mOutPermissions[1]; 3494 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 3495 String msg = "Package " + pkg.packageName 3496 + " has mismatched uid: " 3497 + mOutPermissions[1] + " on disk, " 3498 + pkg.applicationInfo.uid + " in settings"; 3499 // writer 3500 synchronized (mPackages) { 3501 mSettings.mReadMessages.append(msg); 3502 mSettings.mReadMessages.append('\n'); 3503 uidError = true; 3504 if (!pkgSetting.uidError) { 3505 reportSettingsProblem(Log.ERROR, msg); 3506 } 3507 } 3508 } 3509 } 3510 pkg.applicationInfo.dataDir = dataPath.getPath(); // �ǡ����ǥ��쥯�ȥ꤬¸�ߤ��ʤ���� 3511 } else { 3512 if (DEBUG_PACKAGE_SCANNING) { 3513 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 3514 Log.v(TAG, "Want this data dir: " + dataPath); 3515 } // �ǡ����ǥ��쥯�ȥ����������� UID �ˤĤ��ƽ���Υѡ��ߥå�������Ϳ 3516 //invoke installer to do the actual installation 3517 int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, 3518 pkg.applicationInfo.uid); 3519 if (ret < 0) { 3520 // Error from installer 3521 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3522 return null; 3523 } 3524 // Create data directories for all users 3525 mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid); 3526 3527 if (dataPath.exists()) { 3528 pkg.applicationInfo.dataDir = dataPath.getPath(); 3529 } else { 3530 Slog.w(TAG, "Unable to create data directory: " + dataPath); 3531 pkg.applicationInfo.dataDir = null; 3532 } 3533 } : 3633 // Request the ActivityManager to kill the process(only for existing packages) 3634 // so that we do not end up in a confused state while the user is still using the older 3635 // version of the application while the new one gets installed. 3636 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 3637 killApplication(pkg.applicationInfo.packageName, 3638 pkg.applicationInfo.uid); 3639 } 3640 3641 // writer 3642 synchronized (mPackages) { 3643 // We don't expect installation to fail beyond this point, 3644 if ((scanMode&SCAN_MONITOR) != 0) { 3645 mAppDirs.put(pkg.mPath, pkg); 3646 } 3647 // Add the new setting to mSettings 3648 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 3649 // Add the new setting to mPackages 3650 mPackages.put(pkg.applicationInfo.packageName, pkg); : 3672 int N = pkg.providers.size(); 3673 StringBuilder r = null; 3674 int i; 3675 for (i=0; i<N; i++) { 3676 PackageParser.Provider p = pkg.providers.get(i); 3677 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 3678 p.info.processName, pkg.applicationInfo.uid); 3679 mProvidersByComponent.put(new ComponentName(p.info.packageName, 3680 p.info.name), p); : 3720 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3721 if (r == null) { 3722 r = new StringBuilder(256); 3723 } else { 3724 r.append(' '); 3725 } 3726 r.append(p.info.name); 3727 } 3728 } : 3732 3733 N = pkg.services.size(); 3734 r = null; 3735 for (i=0; i<N; i++) { 3736 PackageParser.Service s = pkg.services.get(i); 3737 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 3738 s.info.processName, pkg.applicationInfo.uid); 3739 mServices.addService(s); 3740 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3741 if (r == null) { 3742 r = new StringBuilder(256); 3743 } else { 3744 r.append(' '); 3745 } 3746 r.append(s.info.name); 3747 } 3748 } : 3752 3753 N = pkg.receivers.size(); 3754 r = null; 3755 for (i=0; i<N; i++) { 3756 PackageParser.Activity a = pkg.receivers.get(i); 3757 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 3758 a.info.processName, pkg.applicationInfo.uid); 3759 mReceivers.addActivity(a, "receiver"); 3760 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3761 if (r == null) { 3762 r = new StringBuilder(256); 3763 } else { 3764 r.append(' '); 3765 } 3766 r.append(a.info.name); 3767 } 3768 } : 3773 N = pkg.activities.size(); 3774 r = null; 3775 for (i=0; i<N; i++) { 3776 PackageParser.Activity a = pkg.activities.get(i); 3777 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 3778 a.info.processName, pkg.applicationInfo.uid); 3779 mActivities.addActivity(a, "activity"); 3780 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3781 if (r == null) { 3782 r = new StringBuilder(256); 3783 } else { 3784 r.append(' '); 3785 } 3786 r.append(a.info.name); 3787 } 3788 } : 3793 N = pkg.permissionGroups.size(); 3794 r = null; 3795 for (i=0; i<N; i++) { 3796 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 3797 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 3798 if (cur == null) { 3799 mPermissionGroups.put(pg.info.name, pg); 3800 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3801 if (r == null) { 3802 r = new StringBuilder(256); 3803 } else { 3804 r.append(' '); 3805 } 3806 r.append(pg.info.name); 3807 } 3808 } else { 3809 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 3810 + pg.info.packageName + " ignored: original from " 3811 + cur.info.packageName); 3812 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3813 if (r == null) { 3814 r = new StringBuilder(256); 3815 } else { 3816 r.append(' '); 3817 } 3818 r.append("DUP:"); 3819 r.append(pg.info.name); 3820 } 3821 } 3822 } : 3826 3827 N = pkg.permissions.size(); 3828 r = null; 3829 for (i=0; i<N; i++) { 3830 PackageParser.Permission p = pkg.permissions.get(i); 3831 HashMap<String, BasePermission> permissionMap = 3832 p.tree ? mSettings.mPermissionTrees 3833 : mSettings.mPermissions; 3834 p.group = mPermissionGroups.get(p.info.group); 3835 if (p.info.group == null || p.group != null) { 3836 BasePermission bp = permissionMap.get(p.info.name); 3837 if (bp == null) { 3838 bp = new BasePermission(p.info.name, p.info.packageName, 3839 BasePermission.TYPE_NORMAL); 3840 permissionMap.put(p.info.name, bp); 3841 } 3842 if (bp.perm == null) { 3843 if (bp.sourcePackage == null 3844 || bp.sourcePackage.equals(p.info.packageName)) { 3845 BasePermission tree = findPermissionTreeLP(p.info.name); 3846 if (tree == null 3847 || tree.sourcePackage.equals(p.info.packageName)) { 3848 bp.packageSetting = pkgSetting; 3849 bp.perm = p; 3850 bp.uid = pkg.applicationInfo.uid; 3851 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3852 if (r == null) { 3853 r = new StringBuilder(256); 3854 } else { 3855 r.append(' '); 3856 } 3857 r.append(p.info.name); 3858 } 3859 } else { 3860 Slog.w(TAG, "Permission " + p.info.name + " from package " 3861 + p.info.packageName + " ignored: base tree " 3862 + tree.name + " is from package " 3863 + tree.sourcePackage); 3864 } 3865 } else { 3866 Slog.w(TAG, "Permission " + p.info.name + " from package " 3867 + p.info.packageName + " ignored: original from " 3868 + bp.sourcePackage); 3869 } 3870 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3871 if (r == null) { 3872 r = new StringBuilder(256); 3873 } else { 3874 r.append(' '); 3875 } 3876 r.append("DUP:"); 3877 r.append(p.info.name); 3878 } 3879 if (bp.perm == p) { 3880 bp.protectionLevel = p.info.protectionLevel; 3881 } 3882 } else { 3883 Slog.w(TAG, "Permission " + p.info.name + " from package " 3884 + p.info.packageName + " ignored: no group " 3885 + p.group); 3886 } 3887 } 3888 if (r != null) { 3889 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 3890 } 3891 3892 N = pkg.instrumentation.size(); 3893 r = null; 3894 for (i=0; i<N; i++) { 3895 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 3896 a.info.packageName = pkg.applicationInfo.packageName; 3897 a.info.sourceDir = pkg.applicationInfo.sourceDir; 3898 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 3899 a.info.dataDir = pkg.applicationInfo.dataDir; 3900 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 3901 mInstrumentation.put(a.getComponentName(), a); 3902 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3903 if (r == null) { 3904 r = new StringBuilder(256); 3905 } else { 3906 r.append(' '); 3907 } 3908 r.append(a.info.name); 3909 } 3910 } 3911 if (r != null) { 3912 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 3913 } 3914 3915 if (pkg.protectedBroadcasts != null) { 3916 N = pkg.protectedBroadcasts.size(); 3917 for (i=0; i<N; i++) { 3918 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 3919 } 3920 } 3921 3922 pkgSetting.setTimeStamp(scanFileTime); 3923 } 3924 3925 return pkg; 3926 } 3927
Settings.getPackageLPw()
frameworks/base/services/java/com/android/server/pm/Settings.java ���
164 PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, 165 String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, 166 String nativeLibraryPathString, int pkgFlags, boolean create, boolean add) { 167 final String name = pkg.packageName; 168 PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath, 169 resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, create, add); 170 return p; 171 } : 324 private PackageSetting getPackageLPw(String name, PackageSetting origPackage, 325 String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, 326 String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) { 327 PackageSetting p = mPackages.get(name); // mPackages �ơ��֥��˳�������ѥå�����̾�Υ���ȥ꤬¸�� 328 if (p != null) { 329 if (!p.codePath.equals(codePath)) { 330 // Check to see if its a disabled system app 331 if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 332 // This is an updated system app with versions in both system 333 // and data partition. Just let the most recent version 334 // take precedence. 335 Slog.w(PackageManagerService.TAG, "Trying to update system app code path from " + 336 p.codePathString + " to " + codePath.toString()); 337 } else { 338 // Just a change in the code path is not an issue, but 339 // let's log a message about it. 340 Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from " + p.codePath 341 + " to " + codePath + "; Retaining data and using new"); 342 /* 343 * Since we've changed paths, we need to prefer the new 344 * native library path over the one stored in the 345 * package settings since we might have moved from 346 * internal to external storage or vice versa. 347 */ 348 p.nativeLibraryPathString = nativeLibraryPathString; 349 } 350 } 351 if (p.sharedUser != sharedUser) { 352 PackageManagerService.reportSettingsProblem(Log.WARN, 353 "Package " + name + " shared user changed from " 354 + (p.sharedUser != null ? p.sharedUser.name : "<nothing>") 355 + " to " 356 + (sharedUser != null ? sharedUser.name : "<nothing>") 357 + "; replacing with new"); 358 p = null; 359 } else { 360 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) { 361 // If what we are scanning is a system package, then 362 // make it so, regardless of whether it was previously 363 // installed only in the data partition. 364 p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM; 365 } 366 } 367 } // �ѥå�����̾�Υ���ȥ꤬¸�ߤ��ʤ� 368 if (p == null) { 369 // Create a new PackageSettings entry. this can end up here because 370 // of code path mismatch or user id mismatch of an updated system partition 371 if (!create) { 372 return null; 373 } // PackageSetting ����򿷵����� 374 if (origPackage != null) { 375 // We are consuming the data from an existing package. 376 p = new PackageSetting(origPackage.name, name, codePath, resourcePath, 377 nativeLibraryPathString, vc, pkgFlags); 378 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + name 379 + " is adopting original package " + origPackage.name); 380 // Note that we will retain the new package's signature so 381 // that we can keep its data. 382 PackageSignatures s = p.signatures; 383 p.copyFrom(origPackage); 384 p.signatures = s; 385 p.sharedUser = origPackage.sharedUser; 386 p.userId = origPackage.userId; 387 p.origPackage = origPackage; 388 mRenamedPackages.put(name, origPackage.name); 389 name = origPackage.name; 390 // Update new package state. 391 p.setTimeStamp(codePath.lastModified()); 392 } else { 393 p = new PackageSetting(name, realName, codePath, resourcePath, 394 nativeLibraryPathString, vc, pkgFlags); 395 p.setTimeStamp(codePath.lastModified()); 396 p.sharedUser = sharedUser; 397 // If this is not a system app, it starts out stopped. 398 if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 399 if (DEBUG_STOPPED) { 400 RuntimeException e = new RuntimeException("here"); 401 e.fillInStackTrace(); 402 Slog.i(PackageManagerService.TAG, "Stopping package " + name, e); 403 } 404 p.stopped = true; 405 p.notLaunched = true; 406 } // SharedUserId �����ꤵ��Ƥ���Ф��� UID ����� 407 if (sharedUser != null) { 408 p.userId = sharedUser.userId; 409 } else if (PackageManagerService.MULTIPLE_APPLICATION_UIDS) { 410 // Clone the setting here for disabled system packages 411 PackageSetting dis = mDisabledSysPackages.get(name); 412 if (dis != null) { 413 // For disabled packages a new setting is created 414 // from the existing user id. This still has to be 415 // added to list of user id's 416 // Copy signatures from previous setting 417 if (dis.signatures.mSignatures != null) { 418 p.signatures.mSignatures = dis.signatures.mSignatures.clone(); 419 } 420 p.userId = dis.userId; 421 // Clone permissions 422 p.grantedPermissions = new HashSet<String>(dis.grantedPermissions); 423 // Clone component info 424 p.disabledComponents = new HashSet<String>(dis.disabledComponents); 425 p.enabledComponents = new HashSet<String>(dis.enabledComponents); 426 // Add new setting to list of user ids 427 addUserIdLPw(p.userId, p, name); 428 } else { 429 // Assign new user id 430 p.userId = newUserIdLPw(p); 431 } 432 } else { 433 p.userId = PackageManagerService.FIRST_APPLICATION_UID; 434 } 435 } 436 if (p.userId < 0) { 437 PackageManagerService.reportSettingsProblem(Log.WARN, 438 "Package " + name + " could not be assigned a valid uid"); 439 return null; 440 } // add �ѥ�᡼���� true �ʤ鿷�� PackageSetting ����� mPackages ���ɲ� 441 if (add) { 442 // Finish adding new package by adding it and updating shared 443 // user preferences 444 addPackageSettingLPw(p, name, sharedUser); 445 } 446 } 447 return p; 448 }
PackageParser.parsePackage()
frameworks/base/core/java/android/content/pm/PackageParser.java ���
PackageParser.Package ���饹 2927 public final static class Package { 2928 public String packageName; 2929 2930 // For now we only support one application per package. 2931 public final ApplicationInfo applicationInfo = new ApplicationInfo(); 2932 2933 public final ArrayList<Permission> permissions = new ArrayList<Permission>(0); 2934 public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0); 2935 public final ArrayList<Activity> activities = new ArrayList<Activity>(0); 2936 public final ArrayList<Activity> receivers = new ArrayList<Activity>(0); 2937 public final ArrayList<Provider> providers = new ArrayList<Provider>(0); 2938 public final ArrayList<Service> services = new ArrayList<Service>(0); 2939 public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0); 2940 2941 public final ArrayList<String> requestedPermissions = new ArrayList<String>(); 2942 2943 public ArrayList<String> protectedBroadcasts; 2944 2945 public ArrayList<String> usesLibraries = null; 2946 public ArrayList<String> usesOptionalLibraries = null; 2947 public String[] usesLibraryFiles = null; 2948 2949 public ArrayList<String> mOriginalPackages = null; 2950 public String mRealPackage = null; 2951 public ArrayList<String> mAdoptPermissions = null; 2952 2953 // We store the application meta-data independently to avoid multiple unwanted references 2954 public Bundle mAppMetaData = null; 2955 2956 // If this is a 3rd party app, this is the path of the zip file. 2957 public String mPath; 2958 2959 // The version code declared for this package. 2960 public int mVersionCode; 2961 2962 // The version name declared for this package. 2963 public String mVersionName; 2964 2965 // The shared user id that this package wants to use. 2966 public String mSharedUserId; 2967 2968 // The shared user label that this package wants to use. 2969 public int mSharedUserLabel; 2970 2971 // Signatures that were read from the package. 2972 public Signature mSignatures[]; 2973 2974 // For use by package manager service for quick lookup of 2975 // preferred up order. 2976 public int mPreferredOrder = 0; 2977 2978 // For use by the package manager to keep track of the path to the 2979 // file an app came from. 2980 public String mScanPath; 2981 2982 // For use by package manager to keep track of where it has done dexopt. 2983 public boolean mDidDexOpt; 2984 2985 // User set enabled state. 2986 public int mSetEnabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2987 2988 // Whether the package has been stopped. 2989 public boolean mSetStopped = false; 2990 2991 // Additional data supplied by callers. 2992 public Object mExtras; 2993 2994 // Whether an operation is currently pending on this package 2995 public boolean mOperationPending; 2996 2997 /* 2998 * Applications hardware preferences 2999 */ 3000 public final ArrayList<ConfigurationInfo> configPreferences = 3001 new ArrayList<ConfigurationInfo>(); 3002 3003 /* 3004 * Applications requested features 3005 */ 3006 public ArrayList<FeatureInfo> reqFeatures = null; 3007 3008 public int installLocation; 3009 3010 /** 3011 * Digest suitable for comparing whether this package's manifest is the 3012 * same as another. 3013 */ 3014 public ManifestDigest manifestDigest; 3015 3016 public Package(String _name) { 3017 packageName = _name; 3018 applicationInfo.packageName = _name; 3019 applicationInfo.uid = -1; 3020 } : 3053 } : // apk �ե������ AndroidManifest.xml ����ѥå������������� 390 public Package parsePackage(File sourceFile, String destCodePath, 391 DisplayMetrics metrics, int flags) { 392 mParseError = PackageManager.INSTALL_SUCCEEDED; 393 394 mArchiveSourcePath = sourceFile.getPath(); : 414 XmlResourceParser parser = null; 415 AssetManager assmgr = null; 416 Resources res = null; 417 boolean assetError = true; 418 try { 419 assmgr = new AssetManager(); 420 int cookie = assmgr.addAssetPath(mArchiveSourcePath); 421 if (cookie != 0) { 422 res = new Resources(assmgr, metrics, null); 423 assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 424 Build.VERSION.RESOURCES_SDK_INT); 425 parser = assmgr.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME); 426 assetError = false; 427 } else { 428 Slog.w(TAG, "Failed adding asset path:"+mArchiveSourcePath); 429 } 430 } catch (Exception e) { 431 Slog.w(TAG, "Unable to read AndroidManifest.xml of " 432 + mArchiveSourcePath, e); 433 } 434 if (assetError) { 435 if (assmgr != null) assmgr.close(); 436 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; 437 return null; 438 } 439 String[] errorText = new String[1]; 440 Package pkg = null; 441 Exception errorException = null; 442 try { // AndroidManifest.xml �Υѡ�����¹� 443 // XXXX todo: need to figure out correct configuration. 444 pkg = parsePackage(res, parser, flags, errorText); 445 } catch (Exception e) { 446 errorException = e; 447 mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; 448 } 449 450 451 if (pkg == null) { 452 // If we are only parsing core apps, then a null with INSTALL_SUCCEEDED 453 // just means to skip this app so don't make a fuss about it. 454 if (!mOnlyCoreApps || mParseError != PackageManager.INSTALL_SUCCEEDED) { 455 if (errorException != null) { 456 Slog.w(TAG, mArchiveSourcePath, errorException); 457 } else { 458 Slog.w(TAG, mArchiveSourcePath + " (at " 459 + parser.getPositionDescription() 460 + "): " + errorText[0]); 461 } 462 if (mParseError == PackageManager.INSTALL_SUCCEEDED) { 463 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; 464 } 465 } 466 parser.close(); 467 assmgr.close(); 468 return null; 469 } 470 471 parser.close(); 472 assmgr.close(); 473 474 // Set code and resource paths 475 pkg.mPath = destCodePath; 476 pkg.mScanPath = mArchiveSourcePath; 477 //pkg.applicationInfo.sourceDir = destCodePath; 478 //pkg.applicationInfo.publicSourceDir = destRes; 479 pkg.mSignatures = null; 480 481 return pkg; 482 } 483 : // AndroidManifest.xml ��ѡ������ƥѥå�����������֤� 812 private Package parsePackage( 813 Resources res, XmlResourceParser parser, int flags, String[] outError) 814 throws XmlPullParserException, IOException { 815 AttributeSet attrs = parser; 816 817 mParseInstrumentationArgs = null; 818 mParseActivityArgs = null; 819 mParseServiceArgs = null; 820 mParseProviderArgs = null; 821 822 String pkgName = parsePackageName(parser, attrs, flags, outError); 823 if (pkgName == null) { 824 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; 825 return null; 826 } 827 int type; 828 829 if (mOnlyCoreApps) { 830 boolean core = attrs.getAttributeBooleanValue(null, "coreApp", false); 831 if (!core) { 832 mParseError = PackageManager.INSTALL_SUCCEEDED; 833 return null; 834 } 835 } 836 837 final Package pkg = new Package(pkgName); 838 boolean foundApp = false; 839 840 TypedArray sa = res.obtainAttributes(attrs, 841 com.android.internal.R.styleable.AndroidManifest); 842 pkg.mVersionCode = sa.getInteger( 843 com.android.internal.R.styleable.AndroidManifest_versionCode, 0); 844 pkg.mVersionName = sa.getNonConfigurationString( 845 com.android.internal.R.styleable.AndroidManifest_versionName, 0); 846 if (pkg.mVersionName != null) { 847 pkg.mVersionName = pkg.mVersionName.intern(); 848 } 849 String str = sa.getNonConfigurationString( 850 com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0); 851 if (str != null && str.length() > 0) { 852 String nameError = validateName(str, true); 853 if (nameError != null && !"android".equals(pkgName)) { 854 outError[0] = "<manifest> specifies bad sharedUserId name \"" 855 + str + "\": " + nameError; 856 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID; 857 return null; 858 } 859 pkg.mSharedUserId = str.intern(); 860 pkg.mSharedUserLabel = sa.getResourceId( 861 com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0); 862 } 863 sa.recycle(); 864 865 pkg.installLocation = sa.getInteger( 866 com.android.internal.R.styleable.AndroidManifest_installLocation, 867 PARSE_DEFAULT_INSTALL_LOCATION); 868 pkg.applicationInfo.installLocation = pkg.installLocation; 869 870 // Resource boolean are -1, so 1 means we don't know the value. 871 int supportsSmallScreens = 1; 872 int supportsNormalScreens = 1; 873 int supportsLargeScreens = 1; 874 int supportsXLargeScreens = 1; 875 int resizeable = 1; 876 int anyDensity = 1; 877 878 int outerDepth = parser.getDepth(); 879 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 880 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 881 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 882 continue; 883 } 884 885 String tagName = parser.getName(); 886 if (tagName.equals("application")) { : 899 foundApp = true; 900 if (!parseApplication(pkg, res, parser, attrs, flags, outError)) { 901 return null; 902 } 903 } else if (tagName.equals("permission-group")) { 904 if (parsePermissionGroup(pkg, res, parser, attrs, outError) == null) { 905 return null; 906 } 907 } else if (tagName.equals("permission")) { 908 if (parsePermission(pkg, res, parser, attrs, outError) == null) { 909 return null; 910 } 911 } else if (tagName.equals("permission-tree")) { 912 if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) { 913 return null; 914 } 915 } else if (tagName.equals("uses-permission")) { : 926 if (name != null && !pkg.requestedPermissions.contains(name)) { 927 pkg.requestedPermissions.add(name.intern()); 928 } 929 930 XmlUtils.skipCurrentTag(parser); 931 932 } else if (tagName.equals("uses-configuration")) { : 956 pkg.configPreferences.add(cPref); 957 958 XmlUtils.skipCurrentTag(parser); 959 960 } else if (tagName.equals("uses-feature")) { : 982 pkg.reqFeatures.add(fi); : 990 XmlUtils.skipCurrentTag(parser); 991 992 } else if (tagName.equals("uses-sdk")) { 993 if (SDK_VERSION > 0) { : 1045 if (targetCode != null) { : 1057 // If the code matches, it definitely targets this SDK. 1058 pkg.applicationInfo.targetSdkVersion 1059 = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 1060 } else { 1061 pkg.applicationInfo.targetSdkVersion = targetVers; 1062 } 1063 } 1064 1065 XmlUtils.skipCurrentTag(parser); 1066 1067 } else if (tagName.equals("supports-screens")) { 1068 sa = res.obtainAttributes(attrs, 1069 com.android.internal.R.styleable.AndroidManifestSupportsScreens); 1070 1071 pkg.applicationInfo.requiresSmallestWidthDp = sa.getInteger( 1072 com.android.internal.R.styleable.AndroidManifestSupportsScreens_requiresSmallestWidthDp, 1073 0); 1074 pkg.applicationInfo.compatibleWidthLimitDp = sa.getInteger( 1075 com.android.internal.R.styleable.AndroidManifestSupportsScreens_compatibleWidthLimitDp, 1076 0); 1077 pkg.applicationInfo.largestWidthLimitDp = sa.getInteger( 1078 com.android.internal.R.styleable.AndroidManifestSupportsScreens_largestWidthLimitDp, 1079 0); : 1104 XmlUtils.skipCurrentTag(parser); 1105 1106 } else if (tagName.equals("protected-broadcast")) { : 1126 XmlUtils.skipCurrentTag(parser); 1127 1128 } else if (tagName.equals("instrumentation")) { 1129 if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) { 1130 return null; 1131 } 1132 1133 } else if (tagName.equals("original-package")) { 1134 sa = res.obtainAttributes(attrs, 1135 com.android.internal.R.styleable.AndroidManifestOriginalPackage); 1136 1137 String orig =sa.getNonConfigurationString( 1138 com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0); 1139 if (!pkg.packageName.equals(orig)) { 1140 if (pkg.mOriginalPackages == null) { 1141 pkg.mOriginalPackages = new ArrayList<String>(); 1142 pkg.mRealPackage = pkg.packageName; 1143 } 1144 pkg.mOriginalPackages.add(orig); 1145 } 1146 1147 sa.recycle(); 1148 1149 XmlUtils.skipCurrentTag(parser); 1150 1151 } else if (tagName.equals("adopt-permissions")) { 1152 sa = res.obtainAttributes(attrs, 1153 com.android.internal.R.styleable.AndroidManifestOriginalPackage); 1154 1155 String name = sa.getNonConfigurationString( 1156 com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0); 1157 1158 sa.recycle(); 1159 1160 if (name != null) { 1161 if (pkg.mAdoptPermissions == null) { 1162 pkg.mAdoptPermissions = new ArrayList<String>(); 1163 } 1164 pkg.mAdoptPermissions.add(name); 1165 } 1166 1167 XmlUtils.skipCurrentTag(parser); 1168 1169 } else if (tagName.equals("uses-gl-texture")) { 1170 // Just skip this tag 1171 XmlUtils.skipCurrentTag(parser); 1172 continue; 1173 1174 } else if (tagName.equals("compatible-screens")) { 1175 // Just skip this tag 1176 XmlUtils.skipCurrentTag(parser); 1177 continue; 1178 1179 } else if (tagName.equals("eat-comment")) { 1180 // Just skip this tag 1181 XmlUtils.skipCurrentTag(parser); 1182 continue; 1183 1184 } else if (RIGID_PARSER) { 1185 outError[0] = "Bad element under <manifest>: " 1186 + parser.getName(); 1187 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; 1188 return null; 1189 1190 } else { 1191 Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName() 1192 + " at " + mArchiveSourcePath + " " 1193 + parser.getPositionDescription()); 1194 XmlUtils.skipCurrentTag(parser); 1195 continue; 1196 } 1197 } 1198 1199 if (!foundApp && pkg.instrumentation.size() == 0) { 1200 outError[0] = "<manifest> does not contain an <application> or <instrumentation>"; 1201 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY; 1202 } 1203 1204 final int NP = PackageParser.NEW_PERMISSIONS.length; 1205 StringBuilder implicitPerms = null; 1206 for (int ip=0; ip<NP; ip++) { 1207 final PackageParser.NewPermissionInfo npi 1208 = PackageParser.NEW_PERMISSIONS[ip]; 1209 if (pkg.applicationInfo.targetSdkVersion >= npi.sdkVersion) { 1210 break; 1211 } 1212 if (!pkg.requestedPermissions.contains(npi.name)) { 1213 if (implicitPerms == null) { 1214 implicitPerms = new StringBuilder(128); 1215 implicitPerms.append(pkg.packageName); 1216 implicitPerms.append(": compat added "); 1217 } else { 1218 implicitPerms.append(' '); 1219 } 1220 implicitPerms.append(npi.name); 1221 pkg.requestedPermissions.add(npi.name); 1222 } 1223 } 1224 if (implicitPerms != null) { 1225 Slog.i(TAG, implicitPerms.toString()); 1226 } 1227 1228 if (supportsSmallScreens < 0 || (supportsSmallScreens > 0 1229 && pkg.applicationInfo.targetSdkVersion 1230 >= android.os.Build.VERSION_CODES.DONUT)) { 1231 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS; 1232 } 1233 if (supportsNormalScreens != 0) { 1234 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS; 1235 } 1236 if (supportsLargeScreens < 0 || (supportsLargeScreens > 0 1237 && pkg.applicationInfo.targetSdkVersion 1238 >= android.os.Build.VERSION_CODES.DONUT)) { 1239 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS; 1240 } 1241 if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0 1242 && pkg.applicationInfo.targetSdkVersion 1243 >= android.os.Build.VERSION_CODES.GINGERBREAD)) { 1244 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS; 1245 } 1246 if (resizeable < 0 || (resizeable > 0 1247 && pkg.applicationInfo.targetSdkVersion 1248 >= android.os.Build.VERSION_CODES.DONUT)) { 1249 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS; 1250 } 1251 if (anyDensity < 0 || (anyDensity > 0 1252 && pkg.applicationInfo.targetSdkVersion 1253 >= android.os.Build.VERSION_CODES.DONUT)) { 1254 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; 1255 } 1256 1257 return pkg; 1258 } : 484 public boolean collectCertificates(Package pkg, int flags) { 485 pkg.mSignatures = null; 486 487 WeakReference<byte[]> readBufferRef; 488 byte[] readBuffer = null; 489 synchronized (mSync) { 490 readBufferRef = mReadBuffer; 491 if (readBufferRef != null) { 492 mReadBuffer = null; 493 readBuffer = readBufferRef.get(); 494 } 495 if (readBuffer == null) { 496 readBuffer = new byte[8192]; 497 readBufferRef = new WeakReference<byte[]>(readBuffer); 498 } 499 } 500 501 try { 502 JarFile jarFile = new JarFile(mArchiveSourcePath); 503 504 Certificate[] certs = null; 505 506 if ((flags&PARSE_IS_SYSTEM) != 0) { 507 // If this package comes from the system image, then we 508 // can trust it... we'll just use the AndroidManifest.xml 509 // to retrieve its signatures, not validating all of the 510 // files. 511 JarEntry jarEntry = jarFile.getJarEntry(ANDROID_MANIFEST_FILENAME); 512 certs = loadCertificates(jarFile, jarEntry, readBuffer); 513 if (certs == null) { 514 Slog.e(TAG, "Package " + pkg.packageName 515 + " has no certificates at entry " 516 + jarEntry.getName() + "; ignoring!"); 517 jarFile.close(); 518 mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; 519 return false; 520 } 521 if (DEBUG_JAR) { 522 Slog.i(TAG, "File " + mArchiveSourcePath + ": entry=" + jarEntry 523 + " certs=" + (certs != null ? certs.length : 0)); 524 if (certs != null) { 525 final int N = certs.length; 526 for (int i=0; i<N; i++) { 527 Slog.i(TAG, " Public key: " 528 + certs[i].getPublicKey().getEncoded() 529 + " " + certs[i].getPublicKey()); 530 } 531 } 532 } 533 } else { 534 Enumeration<JarEntry> entries = jarFile.entries(); // "META-INF/MANIFEST.MF" ������� 535 final Manifest manifest = jarFile.getManifest(); 536 while (entries.hasMoreElements()) { 537 final JarEntry je = entries.nextElement(); 538 if (je.isDirectory()) continue; 539 540 final String name = je.getName(); 541 542 if (name.startsWith("META-INF/")) 543 continue; 544 // MANIFEST.MF ��� AndroidManifest.xml �� SHA1-Digest ����� 545 if (ANDROID_MANIFEST_FILENAME.equals(name)) { 546 final Attributes attributes = manifest.getAttributes(name); 547 pkg.manifestDigest = ManifestDigest.fromAttributes(attributes); 548 } 549 550 final Certificate[] localCerts = loadCertificates(jarFile, je, readBuffer); 551 if (DEBUG_JAR) { 552 Slog.i(TAG, "File " + mArchiveSourcePath + " entry " + je.getName() 553 + ": certs=" + certs + " (" 554 + (certs != null ? certs.length : 0) + ")"); 555 } 556 557 if (localCerts == null) { 558 Slog.e(TAG, "Package " + pkg.packageName 559 + " has no certificates at entry " 560 + je.getName() + "; ignoring!"); 561 jarFile.close(); 562 mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; 563 return false; 564 } else if (certs == null) { 565 certs = localCerts; 566 } else { 567 // Ensure all certificates match. 568 for (int i=0; i<certs.length; i++) { 569 boolean found = false; 570 for (int j=0; j<localCerts.length; j++) { 571 if (certs[i] != null && 572 certs[i].equals(localCerts[j])) { 573 found = true; 574 break; 575 } 576 } 577 if (!found || certs.length != localCerts.length) { 578 Slog.e(TAG, "Package " + pkg.packageName 579 + " has mismatched certificates at entry " 580 + je.getName() + "; ignoring!"); 581 jarFile.close(); 582 mParseError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 583 return false; 584 } 585 } 586 } 587 } 588 } 589 jarFile.close(); 590 591 synchronized (mSync) { 592 mReadBuffer = readBufferRef; 593 } 594 595 if (certs != null && certs.length > 0) { 596 final int N = certs.length; 597 pkg.mSignatures = new Signature[certs.length]; 598 for (int i=0; i<N; i++) { 599 pkg.mSignatures[i] = new Signature( 600 certs[i].getEncoded()); 601 } 602 } else { 603 Slog.e(TAG, "Package " + pkg.packageName 604 + " has no certificates; ignoring!"); 605 mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; 606 return false; 607 } 608 } catch (CertificateEncodingException e) { 609 Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e); 610 mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; 611 return false; 612 } catch (IOException e) { 613 Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e); 614 mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING; 615 return false; 616 } catch (RuntimeException e) { 617 Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e); 618 mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; 619 return false; 620 } 621 622 return true; 623 } : 357 private Certificate[] loadCertificates(JarFile jarFile, JarEntry je, 358 byte[] readBuffer) { 359 try { 360 // We must read the stream for the JarEntry to retrieve 361 // its certificates. 362 InputStream is = new BufferedInputStream(jarFile.getInputStream(je)); 363 while (is.read(readBuffer, 0, readBuffer.length) != -1) { 364 // not using 365 } 366 is.close(); 367 return je != null ? je.getCertificates() : null; 368 } catch (IOException e) { 369 Slog.w(TAG, "Exception reading " + je.getName() + " in " 370 + jarFile.getName(), e); 371 } catch (RuntimeException e) { 372 Slog.w(TAG, "Exception reading " + je.getName() + " in " 373 + jarFile.getName(), e); 374 } 375 return null; 376 }
Installer ���饹
frameworks/base/services/java/com/android/server/pm/Installer.java ���
17 package com.android.server.pm; : // /dev/socket/installd ���׵�����Ф��륯�饹 28 class Installer { 29 private static final String TAG = "Installer"; 30 31 private static final boolean LOCAL_DEBUG = false; 32 33 InputStream mIn; 34 35 OutputStream mOut; 36 37 LocalSocket mSocket; 38 39 byte buf[] = new byte[1024]; 40 41 int buflen = 0; 42 // /dev/socket/installd �Ȥ���³ 43 private boolean connect() { 44 if (mSocket != null) { 45 return true; 46 } 47 Slog.i(TAG, "connecting..."); 48 try { 49 mSocket = new LocalSocket(); 50 51 LocalSocketAddress address = new LocalSocketAddress("installd", 52 LocalSocketAddress.Namespace.RESERVED); 53 54 mSocket.connect(address); 55 56 mIn = mSocket.getInputStream(); 57 mOut = mSocket.getOutputStream(); 58 } catch (IOException ex) { 59 disconnect(); 60 return false; 61 } 62 return true; 63 } : // /dev/socket/installd �ؤνñ¤¹ï¿½ï¿½ï¿½ 130 private boolean writeCommand(String _cmd) { 131 byte[] cmd = _cmd.getBytes(); 132 int len = cmd.length; 133 if ((len < 1) || (len > 1024)) 134 return false; 135 buf[0] = (byte) (len & 0xff); 136 buf[1] = (byte) ((len >> 8) & 0xff); 137 try { 138 mOut.write(buf, 0, 2); 139 mOut.write(cmd, 0, len); 140 } catch (IOException ex) { 141 Slog.e(TAG, "write error"); 142 disconnect(); 143 return false; 144 } 145 return true; 146 } 147 // ������ 148 private synchronized String transaction(String cmd) { 149 if (!connect()) { 150 Slog.e(TAG, "connection failed"); 151 return "-1"; 152 } 153 154 if (!writeCommand(cmd)) { 155 /* 156 * If installd died and restarted in the background (unlikely but 157 * possible) we'll fail on the next write (this one). Try to 158 * reconnect and write the command one more time before giving up. 159 */ 160 Slog.e(TAG, "write command failed? reconnect!"); 161 if (!connect() || !writeCommand(cmd)) { 162 return "-1"; 163 } 164 } 165 if (LOCAL_DEBUG) { 166 Slog.i(TAG, "send: '" + cmd + "'"); 167 } 168 if (readReply()) { 169 String s = new String(buf, 0, buflen); 170 if (LOCAL_DEBUG) { 171 Slog.i(TAG, "recv: '" + s + "'"); 172 } 173 return s; 174 } else { 175 if (LOCAL_DEBUG) { 176 Slog.i(TAG, "fail"); 177 } 178 return "-1"; 179 } 180 } 181 // ���ޥ�ɤμ¹� 182 private int execute(String cmd) { 183 String res = transaction(cmd); 184 try { 185 return Integer.parseInt(res); 186 } catch (NumberFormatException ex) { 187 return -1; 188 } 189 } 190 191 public int install(String name, int uid, int gid) { 192 StringBuilder builder = new StringBuilder("install"); 193 builder.append(' '); 194 builder.append(name); 195 builder.append(' '); 196 builder.append(uid); 197 builder.append(' '); 198 builder.append(gid); 199 return execute(builder.toString()); 200 } 201 202 public int dexopt(String apkPath, int uid, boolean isPublic) { 203 StringBuilder builder = new StringBuilder("dexopt"); 204 builder.append(' '); 205 builder.append(apkPath); 206 builder.append(' '); 207 builder.append(uid); 208 builder.append(isPublic ? " 1" : " 0"); 209 return execute(builder.toString()); 210 } 211 212 public int movedex(String srcPath, String dstPath) { 213 StringBuilder builder = new StringBuilder("movedex"); 214 builder.append(' '); 215 builder.append(srcPath); 216 builder.append(' '); 217 builder.append(dstPath); 218 return execute(builder.toString()); 219 } : 228 public int remove(String name, int userId) { 229 StringBuilder builder = new StringBuilder("remove"); 230 builder.append(' '); 231 builder.append(name); 232 builder.append(' '); 233 builder.append(userId); 234 return execute(builder.toString()); 235 } :
PackageInstaller ���� InstallAppProgress �إ��󥹥ȡ����׵�ΰ����Ϥ�
packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java ���
�ѥå��������󥹥ȡ��� 17 package com.android.packageinstaller; : 42 /* 43 * This activity is launched when a new application is installed via side loading 44 * The package is first parsed and the user is notified of parse errors via a dialog. 45 * If the package is successfully parsed, the user is notified to turn on the install unknown 46 * applications setting. A memory check is made at this point and the user is notified of out 47 * of memory conditions if any. If the package is already existing on the device, 48 * a confirmation dialog (to replace the existing package) is presented to the user. 49 * Based on the user response the package is then installed by launching InstallAppConfirm 50 * sub activity. All state transitions are handled in this activity 51 */ 52 public class PackageInstallerActivity extends Activity implements OnCancelListener, OnClickListener { 53 private static final String TAG = "PackageInstaller"; 54 private Uri mPackageURI; 55 private boolean localLOGV = false; 56 PackageManager mPm; 57 private PackageParser.Package mPkgInfo; : 235 @Override 236 protected void onCreate(Bundle icicle) { 237 super.onCreate(icicle); 238 //get intent information 239 final Intent intent = getIntent(); 240 mPackageURI = intent.getData(); 241 mPm = getPackageManager(); // �оݥѥå������ξ�������� 242 mPkgInfo = PackageUtil.getPackageInfo(mPackageURI); 243 244 // Check for parse errors 245 if(mPkgInfo == null) { 246 Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation"); 247 showDialogInner(DLG_PACKAGE_ERROR); 248 return; 249 } 250 251 //set view 252 requestWindowFeature(Window.FEATURE_NO_TITLE); 253 setContentView(R.layout.install_start); 254 mInstallConfirm = findViewById(R.id.install_confirm_panel); 255 mInstallConfirm.setVisibility(View.INVISIBLE); 256 PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, 257 mPkgInfo.applicationInfo, mPackageURI); 258 PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); // �ȸ��������ץ�Υ��󥹥ȡ��뤬����Ĥ�����ξ�� 259 //check setting 260 if(!isInstallingUnknownAppsAllowed()) { 261 //ask user to enable setting first 262 showDialogInner(DLG_UNKNOWN_APPS); 263 return; 264 } 265 initiateInstall(); 266 } 267 268 // Generic handling when pressing back key 269 public void onCancel(DialogInterface dialog) { 270 finish(); 271 } 272 273 public void onClick(View v) { // �֥��󥹥ȡ���ץܥ��󲡲��� InstallAppProgress ��ƤӽФ� 274 if(v == mOk) { 275 // Start subactivity to actually install the application 276 Intent newIntent = new Intent(); 277 newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, 278 mPkgInfo.applicationInfo); 279 newIntent.setData(mPackageURI); 280 newIntent.setClass(this, InstallAppProgress.class); 281 String installerPackageName = getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME); 282 if (installerPackageName != null) { 283 newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName); 284 } 285 if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI); // InstallAppProgress �����ƥ��ӥƥ���Ƥ� 286 startActivity(newIntent); 287 finish(); 288 } else if(v == mCancel) { 289 // Cancel and finish 290 finish(); 291 } 292 } 293 }packages/apps/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java ���
PackageUtil ���饹 17 package com.android.packageinstaller; : 42 /** 43 * This is a utility class for defining some utility methods and constants 44 * used in the package installer application. 45 */ 46 public class PackageUtil { 47 public static final String PREFIX="com.android.packageinstaller."; 48 public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus"; 49 public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo"; 50 public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList"; 51 //intent attribute strings related to uninstall 52 public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName"; 53 54 /* 55 * Utility method to get application information for a given packageURI 56 */ 57 public static ApplicationInfo getApplicationInfo(Uri packageURI) { 58 final String archiveFilePath = packageURI.getPath(); 59 PackageParser packageParser = new PackageParser(archiveFilePath); 60 File sourceFile = new File(archiveFilePath); 61 DisplayMetrics metrics = new DisplayMetrics(); 62 metrics.setToDefaults(); 63 PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0); 64 if (pkg == null) { 65 return null; 66 } 67 return pkg.applicationInfo; 68 } 69 70 /* 71 * Utility method to get package information for a given packageURI 72 */ 73 public static PackageParser.Package getPackageInfo(Uri packageURI) { 74 final String archiveFilePath = packageURI.getPath(); 75 PackageParser packageParser = new PackageParser(archiveFilePath); 76 File sourceFile = new File(archiveFilePath); 77 DisplayMetrics metrics = new DisplayMetrics(); 78 metrics.setToDefaults(); // �����ѥå������Υѥå�������������� 79 PackageParser.Package pkg = packageParser.parsePackage(sourceFile, 80 archiveFilePath, metrics, 0); 81 // Nuke the parser reference. 82 packageParser = null; 83 return pkg; 84 } :
InstallAppProgress ���饷���ƥ�إ��󥹥ȡ����׵�����󥹥ȡ���½���
packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallAppProgress.java ���
17 package com.android.packageinstaller; : 46 /** 47 * This activity corresponds to a download progress screen that is displayed 48 * when the user tries 49 * to install an application bundled as an apk file. The result of the application install 50 * is indicated in the result code that gets set to the corresponding installation status 51 * codes defined in PackageManager. If the package being installed already exists, 52 * the existing package is replaced with the new one. 53 */ 54 public class InstallAppProgress extends Activity implements View.OnClickListener, OnCancelListener { 55 private final String TAG="InstallAppProgress"; 56 private boolean localLOGV = false; 57 private ApplicationInfo mAppInfo; 58 private Uri mPackageURI; : // ��å������ϥ�ɥ� 70 private Handler mHandler = new Handler() { 71 public void handleMessage(Message msg) { 72 switch (msg.what) { 73 case INSTALL_COMPLETE: 74 if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { 75 Intent result = new Intent(); 76 result.putExtra(Intent.EXTRA_INSTALL_RESULT, msg.arg1); 77 setResult(msg.arg1 == PackageManager.INSTALL_SUCCEEDED 78 ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER, 79 result); 80 finish(); 81 return; 82 } : 158 @Override 159 public void onCreate(Bundle icicle) { 160 super.onCreate(icicle); 161 Intent intent = getIntent(); 162 mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); 163 mPackageURI = intent.getData(); 164 initView(); 165 } : // ���󥹥ȡ��������λ�������Τ�����뤿��Υ��֥����Х��饹 200 class PackageInstallObserver extends IPackageInstallObserver.Stub { 201 public void packageInstalled(String packageName, int returnCode) { 202 Message msg = mHandler.obtainMessage(INSTALL_COMPLETE); 203 msg.arg1 = returnCode; 204 mHandler.sendMessage(msg); 205 } 206 } 207 208 public void initView() { 209 setContentView(R.layout.op_progress); 210 int installFlags = 0; 211 PackageManager pm = getPackageManager(); 212 try { // �����ѥå����������Ǥ˥��󥹥ȡ��뤺�ߤ���ǧ 213 PackageInfo pi = pm.getPackageInfo(mAppInfo.packageName, 214 PackageManager.GET_UNINSTALLED_PACKAGES); 215 if(pi != null) { 216 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 217 } 218 } catch (NameNotFoundException e) { 219 } 220 if((installFlags & PackageManager.INSTALL_REPLACE_EXISTING )!= 0) { 221 Log.w(TAG, "Replacing package:" + mAppInfo.packageName); 222 } 223 PackageUtil.AppSnippet as = PackageUtil.getAppSnippet(this, mAppInfo, 224 mPackageURI); 225 mLabel = as.label; 226 PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); 227 mStatusTextView = (TextView)findViewById(R.id.center_text); 228 mStatusTextView.setText(R.string.installing); 229 mExplanationTextView = (TextView) findViewById(R.id.center_explanation); 230 mProgressBar = (ProgressBar) findViewById(R.id.progress_bar); 231 mProgressBar.setIndeterminate(true); 232 // Hide button till progress is being displayed 233 mOkPanel = (View)findViewById(R.id.buttons_panel); 234 mDoneButton = (Button)findViewById(R.id.done_button); 235 mLaunchButton = (Button)findViewById(R.id.launch_button); 236 mOkPanel.setVisibility(View.INVISIBLE); 237 238 String installerPackageName = getIntent().getStringExtra( 239 Intent.EXTRA_INSTALLER_PACKAGE_NAME); // ���֥����Х��饹�Υ��󥹥��󥹤����� 240 PackageInstallObserver observer = new PackageInstallObserver(); // PackageManager �˥��󥹥ȡ����������� 241 pm.installPackage(mPackageURI, observer, installFlags, installerPackageName); 242 }frameworks/base/core/java/android/content/pm/PackageManager.java ���
17 package android.content.pm; : 37 /** 38 * Class for retrieving various kinds of information related to the application 39 * packages that are currently installed on the device. 40 * 41 * You can find this class through {@link Context#getPackageManager}. 42 */ 43 public abstract class PackageManager { : 2137 /** 2138 * @hide 2139 * 2140 * Install a package. Since this may take a little while, the result will 2141 * be posted back to the given observer. An installation will fail if the calling context 2142 * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the 2143 * package named in the package file's manifest is already installed, or if there's no space 2144 * available on the device. 2145 * 2146 * @param packageURI The location of the package file to install. This can be a 'file:' or a 2147 * 'content:' URI. 2148 * @param observer An observer callback to get notified when the package installation is 2149 * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be 2150 * called when that happens. observer may be null to indicate that no callback is desired. 2151 * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK}, 2152 * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}. 2153 * @param installerPackageName Optional package name of the application that is performing the 2154 * installation. This identifies which market the package came from. 2155 */ 2156 public abstract void installPackage( 2157 Uri packageURI, IPackageInstallObserver observer, int flags, 2158 String installerPackageName); :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
: 4903 /* Called when a downloaded package installation has been confirmed by the user */ 4904 public void installPackage( 4905 final Uri packageURI, final IPackageInstallObserver observer, final int flags) { 4906 installPackage(packageURI, observer, flags, null); 4907 } 4908 4909 /* Called when a downloaded package installation has been confirmed by the user */ 4910 public void installPackage( 4911 final Uri packageURI, final IPackageInstallObserver observer, final int flags, 4912 final String installerPackageName) { 4913 installPackageWithVerification(packageURI, observer, flags, installerPackageName, null, 4914 null); 4915 } 4916 4917 @Override 4918 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 4919 int flags, String installerPackageName, Uri verificationURI, 4920 ManifestDigest manifestDigest) { 4921 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 4922 // �ƤӸ��ץ������� UID ����� 4923 final int uid = Binder.getCallingUid(); 4924 4925 final int filteredFlags; 4926 // UID �� SHELL_UID �ʤ� adb ��ͳ�ǤΥ��󥹥ȡ���Ȥߤʤ� 4927 if (uid == Process.SHELL_UID || uid == 0) { 4928 if (DEBUG_INSTALL) { 4929 Slog.v(TAG, "Install from ADB"); 4930 } 4931 filteredFlags = flags | PackageManager.INSTALL_FROM_ADB; 4932 } else { 4933 filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB; 4934 } 4935 4936 final Message msg = mHandler.obtainMessage(INIT_COPY); 4937 msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName, 4938 verificationURI, manifestDigest); 4939 mHandler.sendMessage(msg); 4940 } :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
: 439 class PackageHandler extends Handler { 440 private boolean mBound = false; 441 final ArrayList<HandlerParams> mPendingInstalls = 442 new ArrayList<HandlerParams>(); 443 // DefaultContainerService �ؤ���³ 444 private boolean connectToService() { 445 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 446 " DefaultContainerService"); 447 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 448 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 449 if (mContext.bindService(service, mDefContainerConn, 450 Context.BIND_AUTO_CREATE)) { 451 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 452 mBound = true; 453 return true; 454 } 455 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 456 return false; 457 } 458 // DefaultContainerService ��������� 459 private void disconnectService() { 460 mContainerService = null; 461 mBound = false; 462 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 463 mContext.unbindService(mDefContainerConn); 464 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 465 } : 479 void doHandleMessage(Message msg) { 480 switch (msg.what) { 481 case INIT_COPY: { 482 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy"); 483 HandlerParams params = (HandlerParams) msg.obj; 484 int idx = mPendingInstalls.size(); 485 if (DEBUG_INSTALL) Slog.i(TAG, "idx=" + idx); // DefaultContainerService ��̤��³�ʤ���³���Ω���� 486 // If a bind was already initiated we dont really 487 // need to do anything. The pending install 488 // will be processed later on. 489 if (!mBound) { 490 // If this is the only one pending we might 491 // have to bind to the service again. 492 if (!connectToService()) { 493 Slog.e(TAG, "Failed to bind to media container service"); 494 params.serviceError(); 495 return; 496 } else { // ��³�����ʤ麣��Υ��󥹥ȡ����׵�ò¥¥å¡¼ï¿½ï¿½ï¿½É²ï¿½ // ����³�ϥ�ɥ��� MCS_BOUND ��å�������ư���Ф� // ���塼��Ƭʬ�Υ��󥹥ȡ��뤬��������� 497 // Once we bind to the service, the first 498 // pending request will be processed. 499 mPendingInstalls.add(idx, params); 500 } // ���Ǥ���³���ߤξ��� 501 } else { 502 mPendingInstalls.add(idx, params); 503 // Already bound to the service. Just make 504 // sure we trigger off processing the first request. 505 if (idx == 0) { 506 mHandler.sendEmptyMessage(MCS_BOUND); 507 } 508 } 509 break; 510 } 511 case MCS_BOUND: { 512 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 513 if (msg.obj != null) { 514 mContainerService = (IMediaContainerService) msg.obj; 515 } 516 if (mContainerService == null) { 517 // Something seriously wrong. Bail out 518 Slog.e(TAG, "Cannot bind to media container service"); 519 for (HandlerParams params : mPendingInstalls) { 520 mPendingInstalls.remove(0); 521 // Indicate service bind error 522 params.serviceError(); 523 } 524 mPendingInstalls.clear(); 525 } else if (mPendingInstalls.size() > 0) { // ���󥹥ȡ��ë¥ï¿½å¡¼ï¿½ï¿½ï¿½ï¿½Æ¬Ê¬ï¿½ï¿½ï¿½ï¿½ï¿½ 526 HandlerParams params = mPendingInstalls.get(0); 527 if (params != null) { 528 if (params.startCopy()) { 529 // We are done... look for more work or to 530 // go idle. 531 if (DEBUG_SD_INSTALL) Log.i(TAG, 532 "Checking for more work or unbind..."); 533 // Delete pending install 534 if (mPendingInstalls.size() > 0) { 535 mPendingInstalls.remove(0); 536 } 537 if (mPendingInstalls.size() == 0) { 538 if (mBound) { 539 if (DEBUG_SD_INSTALL) Log.i(TAG, 540 "Posting delayed MCS_UNBIND"); 541 removeMessages(MCS_UNBIND); // ���塼�����ˤʤä��� DefaultContainerService �Ȥ���³��λ 542 Message ubmsg = obtainMessage(MCS_UNBIND); 543 // Unbind after a little delay, to avoid 544 // continual thrashing. 545 sendMessageDelayed(ubmsg, 10000); 546 } 547 } else { // �ޤ����塼�˥���ȥ꤬����� MCS_BOUND �������� // �ꤲ�Ƽ��Υ���ȥ�ν����� 548 // There are more pending requests in queue. 549 // Just post MCS_BOUND message to trigger processing 550 // of next pending install. 551 if (DEBUG_SD_INSTALL) Log.i(TAG, 552 "Posting MCS_BOUND for next woek"); 553 mHandler.sendEmptyMessage(MCS_BOUND); 554 } 555 } 556 } 557 } else { 558 // Should never happen ideally. 559 Slog.w(TAG, "Empty queue"); 560 } 561 break; 562 } 563 case MCS_RECONNECT: { 564 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 565 if (mPendingInstalls.size() > 0) { 566 if (mBound) { 567 disconnectService(); 568 } 569 if (!connectToService()) { 570 Slog.e(TAG, "Failed to bind to media container service"); 571 for (HandlerParams params : mPendingInstalls) { 572 mPendingInstalls.remove(0); 573 // Indicate service bind error 574 params.serviceError(); 575 } 576 mPendingInstalls.clear(); 577 } 578 } 579 break; 580 } 581 case MCS_UNBIND: { 582 // If there is no actual work left, then time to unbind. 583 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 584 // ���󥹥ȡ����Ԥ����塼�����ʤ� DefaultContainerService �Ȥ���³��λ 585 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 586 if (mBound) { 587 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 588 589 disconnectService(); 590 } 591 } else if (mPendingInstalls.size() > 0) { 592 // There are more pending requests in queue. 593 // Just post MCS_BOUND message to trigger processing 594 // of next pending install. 595 mHandler.sendEmptyMessage(MCS_BOUND); 596 } 597 598 break; 599 } 600 case MCS_GIVE_UP: { 601 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 602 mPendingInstalls.remove(0); 603 break; 604 } : 655 case POST_INSTALL: { 656 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 657 PostInstallData data = mRunningInstalls.get(msg.arg1); 658 mRunningInstalls.delete(msg.arg1); 659 boolean deleteOld = false; 660 661 if (data != null) { 662 InstallArgs args = data.args; 663 PackageInstalledInfo res = data.res; 664 665 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { // ���������ʤ鴰λ���Τ�֥����ɥ��㥹�� 666 res.removedInfo.sendBroadcast(false, true); 667 Bundle extras = new Bundle(1); 668 extras.putInt(Intent.EXTRA_UID, res.uid); 669 final boolean update = res.removedInfo.removedPackage != null; 670 if (update) { 671 extras.putBoolean(Intent.EXTRA_REPLACING, true); 672 } 673 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 674 res.pkg.applicationInfo.packageName, 675 extras, null, null); 676 if (update) { 677 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 678 res.pkg.applicationInfo.packageName, 679 extras, null, null); 680 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 681 null, null, 682 res.pkg.applicationInfo.packageName, null); 683 } 684 if (res.removedInfo.args != null) { 685 // Remove the replaced package's older resources safely now 686 deleteOld = true; 687 } 688 } 689 // Force a gc to clear up things 690 Runtime.getRuntime().gc(); 691 // We delete after a gc for applications on sdcard. 692 if (deleteOld) { 693 synchronized (mInstallLock) { 694 res.removedInfo.args.doPostDeleteLI(true); 695 } 696 } // �ƤӸ��� installPackage() �Υ�������˥��֥����Ф���ꤷ�Ƥ���� // ��λ�λݤ������� 697 if (args.observer != null) { 698 try { 699 args.observer.packageInstalled(res.name, res.returnCode); 700 } catch (RemoteException e) { 701 Slog.i(TAG, "Observer no longer exists."); 702 } 703 } 704 } else { 705 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 706 } 707 } break; : 4731 static final void sendPackageBroadcast(String action, String pkg, 4732 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver) { 4733 IActivityManager am = ActivityManagerNative.getDefault(); 4734 if (am != null) { 4735 try { 4736 final Intent intent = new Intent(action, 4737 pkg != null ? Uri.fromParts("package", pkg, null) : null); 4738 if (extras != null) { 4739 intent.putExtras(extras); 4740 } 4741 if (targetPkg != null) { 4742 intent.setPackage(targetPkg); 4743 } 4744 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4745 am.broadcastIntent(null, intent, null, finishedReceiver, 4746 0, null, null, null, finishedReceiver != null, false); 4747 } catch (RemoteException ex) { 4748 } 4749 } 4750 }frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
��ݥ��饹 HandlerParams 5223 private abstract class HandlerParams { 5224 private static final int MAX_RETRIES = 4; 5225 5226 /** 5227 * Number of times startCopy() has been attempted and had a non-fatal 5228 * error. 5229 */ 5230 private int mRetries = 0; 5231 5232 final boolean startCopy() { 5233 boolean res; // ���󥹥ȡ����о� apk �򥤥󥹥ȡ�����إ��ԡ� 5234 try { 5235 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy"); 5236 // ��ȥ饤�����С� 5237 if (++mRetries > MAX_RETRIES) { 5238 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 5239 mHandler.sendEmptyMessage(MCS_GIVE_UP); // ���֥��å� 5240 handleServiceError(); 5241 return false; 5242 } else { // ���ԡ�������Ƥ� 5243 handleStartCopy(); 5244 res = true; 5245 } 5246 } catch (RemoteException e) { 5247 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); // DefaultContainerService �ؤ���³����ľ�� 5248 mHandler.sendEmptyMessage(MCS_RECONNECT); 5249 res = false; 5250 } // handleStartCopy() �η�̤˴�Ť��Ƹ�³������»� 5251 handleReturnCode(); 5252 return res; 5253 } 5254 5255 final void serviceError() { 5256 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 5257 handleServiceError(); 5258 handleReturnCode(); 5259 } 5260 5261 abstract void handleStartCopy() throws RemoteException; 5262 abstract void handleServiceError(); 5263 abstract void handleReturnCode(); 5264 } : InstallParams -- HandlerParams ���������饹 5338 class InstallParams extends HandlerParams { 5339 final IPackageInstallObserver observer; 5340 int flags; 5341 final Uri packageURI; 5342 final String installerPackageName; 5343 final Uri verificationURI; 5344 final ManifestDigest manifestDigest; 5345 private InstallArgs mArgs; 5346 private int mRet; 5347 // ���󥹥ȥ饯�� 5348 InstallParams(Uri packageURI, 5349 IPackageInstallObserver observer, int flags, 5350 String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest) { 5351 this.packageURI = packageURI; 5352 this.flags = flags; 5353 this.observer = observer; 5354 this.installerPackageName = installerPackageName; 5355 this.verificationURI = verificationURI; 5356 this.manifestDigest = manifestDigest; 5357 } 5358 // ���󥹥ȡ��������������Ƚ�� 5359 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) { 5360 String packageName = pkgLite.packageName; 5361 int installLocation = pkgLite.installLocation; 5362 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 5363 // reader 5364 synchronized (mPackages) { 5365 PackageParser.Package pkg = mPackages.get(packageName); 5366 if (pkg != null) { 5367 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 5368 // Check for updated system application. 5369 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 5370 if (onSd) { 5371 Slog.w(TAG, "Cannot install update to system app on sdcard"); 5372 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 5373 } 5374 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 5375 } else { 5376 if (onSd) { 5377 // Install flag overrides everything. 5378 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 5379 } 5380 // If current upgrade specifies particular preference 5381 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 5382 // Application explicitly specified internal. 5383 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 5384 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 5385 // App explictly prefers external. Let policy decide 5386 } else { 5387 // Prefer previous location 5388 if (isExternal(pkg)) { 5389 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 5390 } 5391 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 5392 } 5393 } 5394 } else { 5395 // Invalid install. Return error code 5396 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 5397 } 5398 } 5399 } 5400 // All the special cases have been taken care of. 5401 // Return result based on recommended install location. 5402 if (onSd) { 5403 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 5404 } 5405 return pkgLite.recommendedInstallLocation; 5406 } 5407 5408 /* 5409 * Invoke remote method to get package information and install 5410 * location values. Override install location based on default 5411 * policy if needed and then create install arguments based 5412 * on the install location. 5413 */ 5414 public void handleStartCopy() throws RemoteException { 5415 int ret = PackageManager.INSTALL_SUCCEEDED; 5416 final boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 5417 final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 5418 final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; 5419 PackageInfoLite pkgLite = null; 5420 5421 if (onInt && onSd) { // ̷�� 5422 // Check if both bits are set. 5423 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 5424 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5425 } else if (fwdLocked && onSd) {// ̷�� 5426 // Check for forward locked apps 5427 Slog.w(TAG, "Cannot install fwd locked apps on sdcard"); 5428 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5429 } else { 5430 final long lowThreshold; 5431 5432 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager 5433 .getService(DeviceStorageMonitorService.SERVICE); 5434 if (dsm == null) { 5435 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 5436 lowThreshold = 0L; 5437 } else { 5438 lowThreshold = dsm.getMemoryLowThreshold(); 5439 } 5440 5441 // Remote call to find out default install location 5442 try { 5443 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5444 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5445 pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags, 5446 lowThreshold); 5447 } finally { 5448 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5449 } 5450 5451 int loc = pkgLite.recommendedInstallLocation; 5452 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 5453 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5454 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 5455 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 5456 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 5457 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5458 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 5459 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 5460 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 5461 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 5462 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 5463 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 5464 } else { 5465 // Override with defaults if needed. 5466 loc = installLocationPolicy(pkgLite, flags); 5467 if (!onSd && !onInt) { 5468 // Override install location with flags 5469 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 5470 // Set the flag to install on external media. 5471 flags |= PackageManager.INSTALL_EXTERNAL; 5472 flags &= ~PackageManager.INSTALL_INTERNAL; 5473 } else { 5474 // Make sure the flag for installing on external 5475 // media is unset 5476 flags |= PackageManager.INSTALL_INTERNAL; 5477 flags &= ~PackageManager.INSTALL_EXTERNAL; 5478 } 5479 } 5480 } 5481 } 5482 // ���󥹥ȡ���ѥ�᡼������ 5483 final InstallArgs args = createInstallArgs(this); 5484 mArgs = args; 5485 5486 if (ret == PackageManager.INSTALL_SUCCEEDED) { 5487 /* 5488 * Determine if we have any installed package verifiers. If we 5489 * do, then we'll defer to them to verify the packages. 5490 */ 5491 final int requiredUid = mRequiredVerifierPackage == null ? -1 5492 : getPackageUid(mRequiredVerifierPackage); 5493 if (requiredUid != -1 && isVerificationEnabled()) { : 5578 } else { // ���� apk �򥤥󥹥ȡ�����ذ���ե�����̾�ǥ��ԡ� 5579 /* 5580 * No package verification is enabled, so immediately start 5581 * the remote call to initiate copy using temporary file. 5582 */ 5583 ret = args.copyApk(mContainerService, true); 5584 } 5585 } 5586 5587 mRet = ret; 5588 } 5589 5590 @Override 5591 void handleReturnCode() { 5592 // If mArgs is null, then MCS couldn't be reached. When it 5593 // reconnects, it will try again to install. At that point, this 5594 // will succeed. 5595 if (mArgs != null) { 5596 processPendingInstall(mArgs, mRet); 5597 } 5598 } : 5678 private InstallArgs createInstallArgs(InstallParams params) { //��ɮ�������ʹߤ� SD �����ɤؤΥ��󥹥ȡ�������ΰ��ѤϾʤ��ޤ��� 5679 if (installOnSd(params.flags)) { 5680 return new SdInstallArgs(params); 5681 } else { 5682 return new FileInstallArgs(params); 5683 } 5684 } :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
��ݥ��饹 InstallArgs 5705 static abstract class InstallArgs { 5706 final IPackageInstallObserver observer; 5707 // Always refers to PackageManager flags only 5708 final int flags; 5709 final Uri packageURI; 5710 final String installerPackageName; 5711 final ManifestDigest manifestDigest; 5712 5713 InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags, 5714 String installerPackageName, ManifestDigest manifestDigest) { 5715 this.packageURI = packageURI; 5716 this.flags = flags; 5717 this.observer = observer; 5718 this.installerPackageName = installerPackageName; 5719 this.manifestDigest = manifestDigest; 5720 } 5721 5722 abstract void createCopyFile(); 5723 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 5724 abstract int doPreInstall(int status); 5725 abstract boolean doRename(int status, String pkgName, String oldCodePath); 5726 abstract int doPostInstall(int status); 5727 abstract String getCodePath(); 5728 abstract String getResourcePath(); 5729 abstract String getNativeLibraryPath(); 5730 // Need installer lock especially for dex file removal. 5731 abstract void cleanUpResourcesLI(); 5732 abstract boolean doPostDeleteLI(boolean delete); 5733 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 5734 } 5735 FileInstallArgs -- InstallArgs ���������饹 5736 class FileInstallArgs extends InstallArgs { 5737 File installDir; 5738 String codeFileName; 5739 String resourceFileName; 5740 String libraryPath; 5741 boolean created = false; 5742 // ���󥹥ȥ饯�� 5743 FileInstallArgs(InstallParams params) { 5744 super(params.packageURI, params.observer, params.flags, params.installerPackageName, 5745 params.manifestDigest); 5746 } : // ���󥹥ȡ�����ǥ��쥯�ȥ겼�Ǥΰ���ե�����̾����� 5796 void createCopyFile() { 5797 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 5798 codeFileName = createTempPackageFile(installDir).getPath(); 5799 resourceFileName = getResourcePathFromCodePath(); 5800 created = true; 5801 } 5802 // ���󥹥ȡ�����ǥ��쥯�ȥ������ apk �����ե�����̾�ǥ��ԡ����� 5803 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 5804 if (temp) { 5805 // Generate temp file name 5806 createCopyFile(); // ����ե�����̾�� codeFileName �˥��å� 5807 } 5808 // Get a ParcelFileDescriptor to write to the output file 5809 File codeFile = new File(codeFileName); 5810 if (!created) { 5811 try { 5812 codeFile.createNewFile(); 5813 // Set permissions 5814 if (!setPermissions()) { 5815 // Failed setting permissions. 5816 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5817 } 5818 } catch (IOException e) { 5819 Slog.w(TAG, "Failed to create file " + codeFile); 5820 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5821 } 5822 } 5823 ParcelFileDescriptor out = null; 5824 try { 5825 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE); 5826 } catch (FileNotFoundException e) { 5827 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName); 5828 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5829 } 5830 // Copy the resource now 5831 int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5832 try { 5833 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5834 Intent.FLAG_GRANT_READ_URI_PERMISSION); // DefaultContainerService �����Ѥ��ƥ꥽�����򥳥ԡ� 5835 ret = imcs.copyResource(packageURI, out); 5836 } finally { 5837 try { if (out != null) out.close(); } catch (IOException e) {} 5838 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5839 } 5840 5841 return ret; 5842 } 5843 // ���󥹥ȡ��������� 5844 int doPreInstall(int status) { 5845 if (status != PackageManager.INSTALL_SUCCEEDED) { 5846 cleanUp(); 5847 } 5848 return status; 5849 } 5850 // apk �Υ�͡��� 5851 boolean doRename(int status, final String pkgName, String oldCodePath) { 5852 if (status != PackageManager.INSTALL_SUCCEEDED) { 5853 cleanUp(); 5854 return false; 5855 } else { 5856 // Rename based on packageName 5857 File codeFile = new File(getCodePath()); 5858 String apkName = getNextCodePath(oldCodePath, pkgName, ".apk"); 5859 File desFile = new File(installDir, apkName + ".apk"); 5860 if (!codeFile.renameTo(desFile)) { 5861 return false; 5862 } 5863 // Reset paths since the file has been renamed. 5864 codeFileName = desFile.getPath(); 5865 resourceFileName = getResourcePathFromCodePath(); 5866 // Set permissions 5867 if (!setPermissions()) { 5868 // Failed setting permissions. 5869 return false; 5870 } 5871 return true; 5872 } 5873 } 5874 // ���󥹥ȡ������� 5875 int doPostInstall(int status) { 5876 if (status != PackageManager.INSTALL_SUCCEEDED) { 5877 cleanUp(); 5878 } 5879 return status; 5880 } 5881 5882 String getResourcePath() { 5883 return resourceFileName; 5884 } 5885 5886 String getResourcePathFromCodePath() { 5887 String codePath = getCodePath(); 5888 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { 5889 String apkNameOnly = getApkName(codePath); 5890 return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip"; 5891 } else { 5892 return codePath; 5893 } 5894 } 5895 5896 @Override 5897 String getNativeLibraryPath() { 5898 return libraryPath; 5899 } 5900 5901 private boolean cleanUp() { 5902 boolean ret = true; 5903 String sourceDir = getCodePath(); 5904 String publicSourceDir = getResourcePath(); 5905 if (sourceDir != null) { 5906 File sourceFile = new File(sourceDir); 5907 if (!sourceFile.exists()) { 5908 Slog.w(TAG, "Package source " + sourceDir + " does not exist."); 5909 ret = false; 5910 } 5911 // Delete application's code and resources 5912 sourceFile.delete(); 5913 } 5914 if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) { 5915 final File publicSourceFile = new File(publicSourceDir); 5916 if (!publicSourceFile.exists()) { 5917 Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist."); 5918 } 5919 if (publicSourceFile.exists()) { 5920 publicSourceFile.delete(); 5921 } 5922 } 5923 return ret; 5924 } 5925 5926 void cleanUpResourcesLI() { 5927 String sourceDir = getCodePath(); 5928 if (cleanUp()) { 5929 int retCode = mInstaller.rmdex(sourceDir); 5930 if (retCode < 0) { 5931 Slog.w(TAG, "Couldn't remove dex file for package: " 5932 + " at location " 5933 + sourceDir + ", retcode=" + retCode); 5934 // we don't consider this to be a failure of the core package deletion 5935 } 5936 } 5937 } 5938 5939 private boolean setPermissions() { 5940 // TODO Do this in a more elegant way later on. for now just a hack 5941 if (!isFwdLocked()) { 5942 final int filePermissions = 5943 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP 5944 |FileUtils.S_IROTH; 5945 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1); 5946 if (retCode != 0) { 5947 Slog.e(TAG, "Couldn't set new package file permissions for " + 5948 getCodePath() 5949 + ". The return code was: " + retCode); 5950 // TODO Define new internal error 5951 return false; 5952 } 5953 return true; 5954 } 5955 return true; 5956 } 5957 5958 boolean doPostDeleteLI(boolean delete) { 5959 // XXX err, shouldn't we respect the delete flag? 5960 cleanUpResourcesLI(); 5961 return true; 5962 } 5963 5964 private boolean isFwdLocked() { 5965 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 5966 } 5967 } :frameworks/base/core/java/com/android/internal/app/IMediaContainerService.aidl ���
17 package com.android.internal.app; : 24 interface IMediaContainerService { 25 String copyResourceToContainer(in Uri packageURI, 26 String containerId, 27 String key, String resFileName); 28 int copyResource(in Uri packageURI, 29 in ParcelFileDescriptor outStream); 30 PackageInfoLite getMinimalPackageInfo(in Uri fileUri, in int flags, in long threshold); 31 boolean checkInternalFreeStorage(in Uri fileUri, in long threshold); 32 boolean checkExternalFreeStorage(in Uri fileUri); 33 ObbInfo getObbInfo(in String filename); 34 long calculateDirectorySize(in String directory); 35 }frameworks/base/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java ���
DefaultContainerService ���饹 17 package com.android.defcontainer; : 53 /* 54 * This service copies a downloaded apk to a file passed in as 55 * a ParcelFileDescriptor or to a newly created container specified 56 * by parameters. The DownloadManager gives access to this process 57 * based on its uid. This process also needs the ACCESS_DOWNLOAD_MANAGER 58 * permission to access apks downloaded via the download manager. 59 */ 60 public class DefaultContainerService extends IntentService { 61 private static final String TAG = "DefContainer"; 62 private static final boolean localLOGV = true; 63 64 private static final String LIB_DIR_NAME = "lib"; 65 66 private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() { 67 /* 68 * Creates a new container and copies resource there. 69 * @param paackageURI the uri of resource to be copied. Can be either 70 * a content uri or a file uri 71 * @param cid the id of the secure container that should 72 * be used for creating a secure container into which the resource 73 * will be copied. 74 * @param key Refers to key used for encrypting the secure container 75 * @param resFileName Name of the target resource file(relative to newly 76 * created secure container) 77 * @return Returns the new cache path where the resource has been copied into 78 * 79 */ : 90 * Copy specified resource to output stream 91 * @param packageURI the uri of resource to be copied. Should be a file 92 * uri 93 * @param outStream Remote file descriptor to be used for copying 94 * @return returns status code according to those in {@link 95 * PackageManager} 96 */ 97 public int copyResource(final Uri packageURI, ParcelFileDescriptor outStream) { 98 if (packageURI == null || outStream == null) { 99 return PackageManager.INSTALL_FAILED_INVALID_URI; 100 } 101 102 ParcelFileDescriptor.AutoCloseOutputStream autoOut 103 = new ParcelFileDescriptor.AutoCloseOutputStream(outStream); 104 105 try { 106 copyFile(packageURI, autoOut); 107 return PackageManager.INSTALL_SUCCEEDED; 108 } catch (FileNotFoundException e) { 109 Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " FNF: " 110 + e.getMessage()); 111 return PackageManager.INSTALL_FAILED_INVALID_URI; 112 } catch (IOException e) { 113 Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " IO: " 114 + e.getMessage()); 115 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 116 } 117 } : 206 }; 332 private static void copyToFile(InputStream inputStream, OutputStream out) throws IOException { 333 byte[] buffer = new byte[16384]; 334 int bytesRead; 335 while ((bytesRead = inputStream.read(buffer)) >= 0) { 336 out.write(buffer, 0, bytesRead); 337 } 338 } 339 340 private static void copyToFile(File srcFile, OutputStream out) 341 throws FileNotFoundException, IOException { 342 InputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile)); 343 try { 344 copyToFile(inputStream, out); 345 } finally { 346 try { inputStream.close(); } catch (IOException e) {} 347 } 348 } 349 350 private void copyFile(Uri pPackageURI, OutputStream outStream) throws FileNotFoundException, 351 IOException { 352 String scheme = pPackageURI.getScheme(); // �������ऴ�Ȥ˽��� 353 if (scheme == null || scheme.equals("file")) { 354 final File srcPackageFile = new File(pPackageURI.getPath()); 355 // We copy the source package file to a temp file and then rename it to the 356 // destination file in order to eliminate a window where the package directory 357 // scanner notices the new package file but it's not completely copied yet. 358 copyToFile(srcPackageFile, outStream); 359 } else if (scheme.equals("content")) { 360 ParcelFileDescriptor fd = null; 361 try { 362 fd = getContentResolver().openFileDescriptor(pPackageURI, "r"); 363 } catch (FileNotFoundException e) { 364 Slog.e(TAG, "Couldn't open file descriptor from download service. " 365 + "Failed with exception " + e); 366 throw e; 367 } 368 369 if (fd == null) { 370 Slog.e(TAG, "Provider returned no file descriptor for " + pPackageURI.toString()); 371 throw new FileNotFoundException("provider returned no file descriptor"); 372 } else { 373 if (localLOGV) { 374 Slog.i(TAG, "Opened file descriptor from download service."); 375 } 376 ParcelFileDescriptor.AutoCloseInputStream dlStream 377 = new ParcelFileDescriptor.AutoCloseInputStream(fd); 378 379 // We copy the source package file to a temp file and then rename it to the 380 // destination file in order to eliminate a window where the package directory 381 // scanner notices the new package file but it's not completely 382 // copied 383 copyToFile(dlStream, outStream); 384 } 385 } else { 386 Slog.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI); 387 throw new FileNotFoundException("Package URI is not 'file:' or 'content:'"); 388 } 389 } :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
// ���󥹥ȡ���μ½����ƤӽФ�����λ������ 5150 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 5151 // Queue up an async operation since the package installation may take a little while. 5152 mHandler.post(new Runnable() { 5153 public void run() { 5154 mHandler.removeCallbacks(this); 5155 // Result object to be returned 5156 PackageInstalledInfo res = new PackageInstalledInfo(); 5157 res.returnCode = currentStatus; 5158 res.uid = -1; 5159 res.pkg = null; 5160 res.removedInfo = new PackageRemovedInfo(); // ���󥹥ȡ��롪 5161 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 5162 args.doPreInstall(res.returnCode); 5163 synchronized (mInstallLock) { 5164 installPackageLI(args, true, res); 5165 } 5166 args.doPostInstall(res.returnCode); 5167 } 5168 5169 // A restore should be performed at this point if (a) the install 5170 // succeeded, (b) the operation is not an update, and (c) the new 5171 // package has a backupAgent defined. 5172 final boolean update = res.removedInfo.removedPackage != null; 5173 boolean doRestore = (!update 5174 && res.pkg != null 5175 && res.pkg.applicationInfo.backupAgentName != null); 5176 5177 // Set up the post-install work request bookkeeping. This will be used 5178 // and cleaned up by the post-install event handling regardless of whether 5179 // there's a restore pass performed. Token values are >= 1. 5180 int token; 5181 if (mNextInstallToken < 0) mNextInstallToken = 1; 5182 token = mNextInstallToken++; 5183 5184 PostInstallData data = new PostInstallData(args, res); 5185 mRunningInstalls.put(token, data); 5186 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 5187 5188 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 5189 // Pass responsibility to the Backup Manager. It will perform a 5190 // restore if appropriate, then pass responsibility back to the 5191 // Package Manager to run the post-install observer callbacks 5192 // and broadcasts. 5193 IBackupManager bm = IBackupManager.Stub.asInterface( 5194 ServiceManager.getService(Context.BACKUP_SERVICE)); 5195 if (bm != null) { 5196 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 5197 + " to BM for possible restore"); 5198 try { 5199 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 5200 } catch (RemoteException e) { 5201 // can't happen; the backup manager is local 5202 } catch (Exception e) { 5203 Slog.e(TAG, "Exception trying to enqueue restore", e); 5204 doRestore = false; 5205 } 5206 } else { 5207 Slog.e(TAG, "Backup Manager not found!"); 5208 doRestore = false; 5209 } 5210 } 5211 5212 if (!doRestore) { 5213 // No restore possible, or the Backup Manager was mysteriously not 5214 // available -- just fire the post-install work request directly. 5215 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); // ��å������ϥ�ɥ�ش�λ���Τ����� 5216 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 5217 mHandler.sendMessage(msg); 5218 } 5219 } 5220 }); 5221 } :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
// ���󥹥ȡ���½��� 6594 private void installPackageLI(InstallArgs args, 6595 boolean newInstall, PackageInstalledInfo res) { 6596 int pFlags = args.flags; 6597 String installerPackageName = args.installerPackageName; 6598 File tmpPackageFile = new File(args.getCodePath()); 6599 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 6600 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); 6601 boolean replace = false; 6602 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE 6603 | (newInstall ? SCAN_NEW_INSTALL : 0); 6604 // Result object to be returned 6605 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 6606 6607 // Retrieve PackageSettings and parse package 6608 int parseFlags = PackageParser.PARSE_CHATTY | 6609 (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | 6610 (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 6611 parseFlags |= mDefParseFlags; 6612 PackageParser pp = new PackageParser(tmpPackageFile.getPath()); 6613 pp.setSeparateProcesses(mSeparateProcesses); // �ѥå������ξ�������� 6614 final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, 6615 null, mMetrics, parseFlags); 6616 if (pkg == null) { 6617 res.returnCode = pp.getParseError(); 6618 return; 6619 } 6620 String pkgName = res.name = pkg.packageName; 6621 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 6622 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { 6623 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY; 6624 return; 6625 } 6626 } 6627 if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) { 6628 res.returnCode = pp.getParseError(); 6629 return; 6630 } 6631 6632 /* If the installer passed in a manifest digest, compare it now. */ 6633 if (args.manifestDigest != null) { 6634 if (DEBUG_INSTALL) { 6635 final String parsedManifest = pkg.manifestDigest == null ? "null" 6636 : pkg.manifestDigest.toString(); 6637 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 6638 + parsedManifest); 6639 } 6640 6641 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 6642 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 6643 return; 6644 } 6645 } else if (DEBUG_INSTALL) { 6646 final String parsedManifest = pkg.manifestDigest == null 6647 ? "null" : pkg.manifestDigest.toString(); 6648 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 6649 } 6650 6651 // Get rid of all references to package scan path via parser. 6652 pp = null; 6653 String oldCodePath = null; 6654 boolean systemApp = false; 6655 synchronized (mPackages) { 6656 // Check if installing already existing package 6657 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 6658 String oldName = mSettings.mRenamedPackages.get(pkgName); 6659 if (pkg.mOriginalPackages != null 6660 && pkg.mOriginalPackages.contains(oldName) 6661 && mPackages.containsKey(oldName)) { 6662 // This package is derived from an original package, 6663 // and this device has been updating from that original 6664 // name. We must continue using the original name, so 6665 // rename the new package here. 6666 pkg.setPackageName(oldName); 6667 pkgName = pkg.packageName; 6668 replace = true; 6669 } else if (mPackages.containsKey(pkgName)) { 6670 // This package, under its official name, already exists 6671 // on the device; we should replace it. 6672 replace = true; 6673 } 6674 } 6675 PackageSetting ps = mSettings.mPackages.get(pkgName); 6676 if (ps != null) { 6677 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 6678 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6679 systemApp = (ps.pkg.applicationInfo.flags & 6680 ApplicationInfo.FLAG_SYSTEM) != 0; 6681 } 6682 } 6683 } 6684 6685 if (systemApp && onSd) { 6686 // Disable updates to system apps on sdcard 6687 Slog.w(TAG, "Cannot install updates to system apps on sdcard"); 6688 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 6689 return; 6690 } 6691 // ���󥹥ȡ�����ذ���ե�����̾�ǥ��ԡ����ߤ� apk ��ѥå�����̾�˥�͡��� 6692 if (!args.doRename(res.returnCode, pkgName, oldCodePath)) { 6693 res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6694 return; 6695 } 6696 // Set application objects path explicitly after the rename 6697 setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath()); 6698 pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath(); //��ɮ�������ʹߤι������󥹥ȡ�������ΰ��ѤϾʤ��ޤ��� 6699 if (replace) { 6700 replacePackageLI(pkg, parseFlags, scanMode, 6701 installerPackageName, res); 6702 } else { 6703 installNewPackageLI(pkg, parseFlags, scanMode, 6704 installerPackageName,res); 6705 } 6706 } :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
// �������󥹥ȡ������ 6280 /* 6281 * Install a non-existing package. 6282 */ 6283 private void installNewPackageLI(PackageParser.Package pkg, 6284 int parseFlags, 6285 int scanMode, 6286 String installerPackageName, PackageInstalledInfo res) { 6287 // Remember this for later, in case we need to rollback this install 6288 String pkgName = pkg.packageName; 6289 6290 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 6291 res.name = pkgName; 6292 synchronized(mPackages) { 6293 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 6294 // A package with the same name is already installed, though 6295 // it has been renamed to an older name. The package we 6296 // are trying to install should be installed as an update to 6297 // the existing one, but that has not been requested, so bail. 6298 Slog.w(TAG, "Attempt to re-install " + pkgName 6299 + " without first uninstalling package running as " 6300 + mSettings.mRenamedPackages.get(pkgName)); 6301 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 6302 return; 6303 } 6304 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) { 6305 // Don't allow installation over an existing package with the same name. 6306 Slog.w(TAG, "Attempt to re-install " + pkgName 6307 + " without first uninstalling."); 6308 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 6309 return; 6310 } 6311 } 6312 mLastScanError = PackageManager.INSTALL_SUCCEEDED; // �����ѥå������Υǡ����ǥ��쥯�ȥ����������餿��� // �ѥå�������������롣���顼����������ͤ� null 6313 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, 6314 System.currentTimeMillis()); 6315 if (newPackage == null) { // NG 6316 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 6317 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 6318 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 6319 } 6320 } else { // OK�� packages.xml �ι��������� 6321 updateSettingsLI(newPackage, 6322 installerPackageName, 6323 res); 6324 // delete the partially installed application. the data directory will have to be 6325 // restored if it was already existing 6326 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 6327 // remove package from internal structures. Note that we want deletePackageX to 6328 // delete the package data and cache directories that it created in 6329 // scanPackageLocked, unless those directories existed before we even tried to 6330 // install. 6331 deletePackageLI( 6332 pkgName, false, 6333 dataDirExists ? PackageManager.DONT_DELETE_DATA : 0, 6334 res.removedInfo, true); 6335 } 6336 } 6337 } :frameworks/base/services/java/com/android/server/pm/PackageManagerService.java ���
// ���󥹥ȡ�������κǸ�� packages.xml �򹹿����뤿��μ�³�� 6557 private void updateSettingsLI(PackageParser.Package newPackage, 6558 String installerPackageName, PackageInstalledInfo res) { 6559 String pkgName = newPackage.packageName; 6560 synchronized (mPackages) { // �ǽ������Ǽ��Ԥ����ǽ���򸫤����Ƥβ����� 6561 //write settings. the installStatus will be incomplete at this stage. 6562 //note that the new package setting would have already been 6563 //added to mPackages. It hasn't been persisted yet. 6564 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 6565 mSettings.writeLPr(); 6566 } 6567 // �ѥå������� dex �ե�����������ξ��� 6568 if ((res.returnCode = moveDexFilesLI(newPackage)) 6569 != PackageManager.INSTALL_SUCCEEDED) { 6570 // Discontinue if moving dex files failed. 6571 return; 6572 } // ɬ�פ������ apk �˽���Υե�����ѡ��ߥå��������� 6573 if((res.returnCode = setPermissionsLI(newPackage)) 6574 != PackageManager.INSTALL_SUCCEEDED) { 6575 mInstaller.rmdex(newPackage.mScanPath); 6576 return; 6577 } else { 6578 Log.d(TAG, "New package installed in " + newPackage.mPath); 6579 } // /data/system/packages.xml �� packages.list �������˹��� 6580 synchronized (mPackages) { 6581 updatePermissionsLPw(newPackage.packageName, newPackage, 6582 newPackage.permissions.size() > 0, true, false); 6583 res.name = pkgName; 6584 res.uid = newPackage.applicationInfo.uid; 6585 res.pkg = newPackage; 6586 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 6587 mSettings.setInstallerPackageName(pkgName, installerPackageName); 6588 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 6589 //to update install status 6590 mSettings.writeLPr(); 6591 } 6592 } : // dex �ե�����������Υ����������ذ�ư 6535 // Utility method used to move dex files during install. 6536 private int moveDexFilesLI(PackageParser.Package newPackage) { 6537 int retCode; 6538 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 6539 retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath); 6540 if (retCode != 0) { 6541 if (mNoDexOpt) { 6542 /* 6543 * If we're in an engineering build, programs are lazily run 6544 * through dexopt. If the .dex file doesn't exist yet, it 6545 * will be created when the program is run next. 6546 */ 6547 Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath); 6548 } else { 6549 Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath); 6550 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6551 } 6552 } 6553 } 6554 return PackageManager.INSTALL_SUCCEEDED; 6555 } 6556 : // ɬ�פʥե�����ѡ��ߥå����� apk ������ 6708 private int setPermissionsLI(PackageParser.Package newPackage) { 6709 int retCode = 0; 6710 // TODO Gross hack but fix later. Ideally move this to be a post installation 6711 // check after alloting uid. // �����Ǥ��оݤϥե���ɥ��å����줿 apk �Τ� 6712 if (isForwardLocked(newPackage)) { 6713 File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir); 6714 try { 6715 extractPublicFiles(newPackage, destResourceFile); 6716 } catch (IOException e) { 6717 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" + 6718 " forward-locked app."); 6719 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6720 } finally { 6721 //TODO clean up the extracted public files 6722 } 6723 retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), 6724 newPackage.applicationInfo.uid); 6725 } else { 6726 // The permissions on the resource file was set when it was copied for 6727 // non forward locked apps and apps on sdcard 6728 } 6729 6730 if (retCode != 0) { 6731 Slog.e(TAG, "Couldn't set new package file permissions for " + newPackage.mPath 6732 + ". The return code was: " + retCode); 6733 // TODO Define new internal error 6734 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6735 } 6736 return PackageManager.INSTALL_SUCCEEDED; 6737 } :
(tanabe)
���ε����ؤΥ�����
/system���ǤϹ����Ǥ��ʤ��褦�ʡ�
4.0.4 �μµ��Ǥ�/data/system�Ǥ�����