PackageManagerService初始化

前言

在接触了framework一段时间后,对于Android的各大服务都有了一定的了解,之前我在做应用的时候就一直好奇,应用商店这类程序究竟是怎么写的,怎么实现的。最后发现了PKMS这个东西。PKMS,其实是Android最主要的核心服务之一,界面的跳转,广播的发送,服务的启动,应用的安装以及卸载一系列Android的基础操作都离不开PKMS的帮助,我们可以把PKMS看成我们Android系统的管家,PKMS会对manifest进行解析,提取其中的组件信息,权限等一系列的有用信息进行保存,为我们之后的操作做准备。看到这有没有一种恍然大悟的感觉,估计没有。你啥都没写呢,你让我悟啥?这就是咱们为什么要把四大组件,权限这些东西在manifest里注册的原因。你注册了,安装的时候才能解析到,跳转的时候才能匹配到,系统才知道往哪跳啊。是不是很有道理,你品,你细品。。。

PKMS的成员

PKMS是一个很庞大的集团,老总呢就是PackageManagerService.java。真正的业务功能的实现都是老总来亲自做的(你要问,这么大的公司为啥全是老板干活,还缺人不。额,我也在找这种公司,找到记得联系我一下)。这就包括,应用的安装啊卸载啊这些。我们客户端,其实相当于集团的业务员,他们去帮集团拉业务,最后给老总发邮件写清楚业务的内容(binder),然后老总做完后告诉他们,他们在把结果呈现在用户面前。
分析一下上图中的成员:
PackageManagerService:Android的核心服务,用来实现功能。
IPackageManager:其实是binder,用来进行客户端与pkms之间的通信。
PackageManager:abstract类,实现在ApplicationPackageManager。
ApplicationPackageManager:PackageManager的实现类,我们在API的中getPackageManager(),实际上就是得到的ApplicationPackageManager的对象。

    @Override    public PackageManager getPackageManager() {        if (mPackageManager != null) {            return mPackageManager;        }        IPackageManager pm = ActivityThread.getPackageManager();        if (pm != null) {            // Doesn't matter if we make more than one instance.            return (mPackageManager = new ApplicationPackageManager(this, pm));        }        return null;    }

上证据,是不是不骗人。这个类包含pkms提供给客户端的全部方法,其中一部分api是隐藏的api,应用无法调用。(不许抬杠,和我说我用反射啊,源码环境下编译啊,我能拿到别的pkms的隐藏方法,那不算)。
简单来说pkms就是上述的成员结构,当然其中包含的通讯步骤十分的复杂,这些都会在之后的博客介绍binder的时候进行介绍,还有应用的安装和卸载也会单独开一篇博客。

PKMS初始化

正文来了,初始化究竟在哪里进行,我们又在初始化的时候做了些什么事?
frameworks/base/services/java/com/android/server/SystemServer.java

    private void run() {        ......        // Start services.        try {            traceBeginAndSlog("StartServices");            startBootstrapServices();            startCoreServices();            startOtherServices();            SystemServerInitThreadPool.shutdown();        } catch (Throwable ex) {            Slog.e("System", "******************************************");            Slog.e("System", "************ Failure starting system services", ex);            throw ex;        } finally {            traceEnd();        }        ......    }
private void startBootstrapServices() {       ......        // Start the package manager.        if (!mRuntimeRestart) {            MetricsLogger.histogram(null, "boot_package_manager_init_start",                    (int) SystemClock.elapsedRealtime());        }        traceBeginAndSlog("StartPackageManagerService");        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);        mFirstBoot = mPackageManagerService.isFirstBoot();        mPackageManager = mSystemContext.getPackageManager();        traceEnd();        if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {            MetricsLogger.histogram(null, "boot_package_manager_init_ready",                    (int) SystemClock.elapsedRealtime());        }    ......      }
private void startOtherServices() {      if (!mOnlyCore) {                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded");                try {                    mPackageManagerService.updatePackagesIfNeeded();                } catch (Throwable e) {...}            }      ...      try {            mPackageManagerService.systemReady();//PMS ok      } catch (Throwable e) {            reportWtf("making Package Manager Service ready", e);      }    }}

SystemServer其实是调到了PackageManagerService的main()方法。
我们继续看PackageManagerService。
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

    public static PackageManagerService main(Context context, Installer installer,            boolean factoryTest, boolean onlyCore) {        // Self-check for initial settings.        PackageManagerServiceCompilerMapping.checkProperties();        PackageManagerService m = new PackageManagerService(context, installer,                factoryTest, onlyCore);        m.enableSystemUserPackages();        ServiceManager.addService("package", m);        return m;    }

我们继续看package的构造方法。ServiceManager.addService(“package”, m);提一句这个方法把,将创造好的服务注册到ServiceManager,我们调用的时候也是从ServiceManager获取到这个它,大概理解一下把,与本章我主要想讲的内容不同,与binder相关。

    public PackageManagerService(Context context, Installer installer,            boolean factoryTest, boolean onlyCore) {        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,                SystemClock.uptimeMillis());        if (mSdkVersion <= 0) {            Slog.w(TAG, "**** ro.build.version.sdk not set!");        }        mContext = context;        mPermissionReviewRequired = context.getResources().getBoolean(                R.bool.config_permissionReviewRequired);        mFactoryTest = factoryTest;        mOnlyCore = onlyCore;        mMetrics = new DisplayMetrics();        mSettings = new Settings(mPackages);        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);        String separateProcesses = SystemProperties.get("debug.separate_processes");        if (separateProcesses != null && separateProcesses.length() > 0) {            if ("*".equals(separateProcesses)) {                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;                mSeparateProcesses = null;                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");            } else {                mDefParseFlags = 0;                mSeparateProcesses = separateProcesses.split(",");                Slog.w(TAG, "Running with debug.separate_processes: "                        + separateProcesses);            }        } else {            mDefParseFlags = 0;            mSeparateProcesses = null;        }        mInstaller = installer;        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,                "*dexopt*");        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());        mOnPermissionChangeListeners = new OnPermissionChangeListeners(                FgThread.get().getLooper());        getDefaultDisplayMetrics(context, mMetrics);        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");        SystemConfig systemConfig = SystemConfig.getInstance();        mGlobalGids = systemConfig.getGlobalGids();        mSystemPermissions = systemConfig.getSystemPermissions();        mAvailableFeatures = systemConfig.getAvailableFeatures();        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);        mProtectedPackages = new ProtectedPackages(mContext);        synchronized (mInstallLock) {        // writer        synchronized (mPackages) {            mHandlerThread = new ServiceThread(TAG,                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);            mHandlerThread.start();            mHandler = new PackageHandler(mHandlerThread.getLooper());            mProcessLoggingHandler = new ProcessLoggingHandler();            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);            mInstantAppRegistry = new InstantAppRegistry(this);            File dataDir = Environment.getDataDirectory();            mAppInstallDir = new File(dataDir, "app");            mAppLib32InstallDir = new File(dataDir, "app-lib");            mAsecInternalPath = new File(dataDir, "app-asec").getPath();            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");            sUserManager = new UserManagerService(context, this,                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);            // Propagate permission configuration in to package manager.            ArrayMap<String, SystemConfig.PermissionEntry> permConfig                    = systemConfig.getPermissions();            for (int i=0; i<permConfig.size(); i++) {                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);                BasePermission bp = mSettings.mPermissions.get(perm.name);                if (bp == null) {                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);                    mSettings.mPermissions.put(perm.name, bp);                }                if (perm.gids != null) {                    bp.setGids(perm.gids, perm.perUser);                }            }            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();            final int builtInLibCount = libConfig.size();            for (int i = 0; i < builtInLibCount; i++) {                String name = libConfig.keyAt(i);                String path = libConfig.valueAt(i);                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);            }            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);            // Clean up orphaned packages for which the code path doesn't exist            // and they are an update to a system app - caused by bug/32321269            final int packageSettingCount = mSettings.mPackages.size();            for (int i = packageSettingCount - 1; i >= 0; i--) {                PackageSetting ps = mSettings.mPackages.valueAt(i);                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {                    mSettings.mPackages.removeAt(i);                    mSettings.enableSystemPackageLPw(ps.name);                }            }            if (mFirstBoot) {                requestCopyPreoptedFiles();            }            String customResolverActivity = Resources.getSystem().getString(                    R.string.config_customResolverActivity);            if (TextUtils.isEmpty(customResolverActivity)) {                customResolverActivity = null;            } else {                mCustomResolverComponentName = ComponentName.unflattenFromString(                        customResolverActivity);            }            long startTime = SystemClock.uptimeMillis();            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,                    startTime);            final String bootClassPath = System.getenv("BOOTCLASSPATH");            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");            if (bootClassPath == null) {                Slog.w(TAG, "No BOOTCLASSPATH found!");            }            if (systemServerClassPath == null) {                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");            }            File frameworkDir = new File(Environment.getRootDirectory(), "framework");            final VersionInfo ver = mSettings.getInternalVersion();            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);            if (mIsUpgrade) {                logCriticalInfo(Log.INFO,                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);            }            // when upgrading from pre-M, promote system app permissions from install to runtime            mPromoteSystemApps =                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;            // When upgrading from pre-N, we need to handle package extraction like first boot,            // as there is no profiling data available.            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;            // save off the names of pre-existing system packages prior to scanning; we don't            // want to automatically grant runtime permissions for new system apps            if (mPromoteSystemApps) {                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();                while (pkgSettingIter.hasNext()) {                    PackageSetting ps = pkgSettingIter.next();                    if (isSystemApp(ps)) {                        mExistingSystemPackages.add(ps.name);                    }                }            }            mCacheDir = preparePackageParserCache(mIsUpgrade);            // Set flag to monitor and not change apk file paths when            // scanning install directories.            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;            if (mIsUpgrade || mFirstBoot) {                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;            }            // Collect vendor overlay packages. (Do this before scanning any apps.)            // For security and version matching reason, only consider            // overlay packages if they reside in the right directory.            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);            mParallelPackageParserCallback.findStaticOverlayPackages();            // Find base frameworks (resource packages without code).            scanDirTracedLI(frameworkDir, mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR                    | PackageParser.PARSE_IS_PRIVILEGED,                    scanFlags | SCAN_NO_DEX, 0);            // Collected privileged system packages.            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");            scanDirTracedLI(privilegedAppDir, mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);            // Collect ordinary system packages.            final File systemAppDir = new File(Environment.getRootDirectory(), "app");            scanDirTracedLI(systemAppDir, mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);            // Collected privileged vendor packages.            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");            scanDirTracedLI(privilegedVendorAppDir, mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);            // Collect all vendor packages.            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");            try {                vendorAppDir = vendorAppDir.getCanonicalFile();            } catch (IOException e) {                // failed to look up canonical path, continue with original one            }            scanDirTracedLI(vendorAppDir, mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);            // Collect all OEM packages.            final File oemAppDir = new File(Environment.getOemDirectory(), "app");            scanDirTracedLI(oemAppDir, mDefParseFlags                    | PackageParser.PARSE_IS_SYSTEM                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);            // Prune any system packages that no longer exist.            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();            if (!mOnlyCore) {                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();                while (psit.hasNext()) {                    PackageSetting ps = psit.next();                    /*                     * If this is not a system app, it can't be a                     * disable system app.                     */                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {                        continue;                    }                    /*                     * If the package is scanned, it's not erased.                     */                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);                    if (scannedPkg != null) {                        /*                         * If the system app is both scanned and in the                         * disabled packages list, then it must have been                         * added via OTA. Remove it from the currently                         * scanned package so the previously user-installed                         * application can be scanned.                         */                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "                                    + ps.name + "; removing system app.  Last known codePath="                                    + ps.codePathString + ", installStatus=" + ps.installStatus                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="                                    + scannedPkg.mVersionCode);                            removePackageLI(scannedPkg, true);                            mExpectingBetter.put(ps.name, ps.codePath);                        }                        continue;                    }                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {                        psit.remove();                        logCriticalInfo(Log.WARN, "System package " + ps.name                                + " no longer exists; it's data will be wiped");                        // Actual deletion of code and data will be handled by later                        // reconciliation step                    } else {                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {                            possiblyDeletedUpdatedSystemApps.add(ps.name);                        }                    }                }            }            //look for any incomplete package installations            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();            for (int i = 0; i < deletePkgsList.size(); i++) {                // Actual deletion of code and data will be handled by later                // reconciliation step                final String packageName = deletePkgsList.get(i).name;                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);                synchronized (mPackages) {                    mSettings.removePackageLPw(packageName);                }            }            //delete tmp files            deleteTempPackageFiles();            // Remove any shared userIDs that have no associated packages            mSettings.pruneSharedUsersLPw();            if (!mOnlyCore) {                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,                        SystemClock.uptimeMillis());                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags                        | PackageParser.PARSE_FORWARD_LOCK,                        scanFlags | SCAN_REQUIRE_KNOWN, 0);                /**                 * Remove disable package settings for any updated system                 * apps that were removed via an OTA. If they're not a                 * previously-updated app, remove them completely.                 * Otherwise, just revoke their system-level permissions.                 */                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);                    String msg;                    if (deletedPkg == null) {                        msg = "Updated system package " + deletedAppName                                + " no longer exists; it's data will be wiped";                        // Actual deletion of code and data will be handled by later                        // reconciliation step                    } else {                        msg = "Updated system app + " + deletedAppName                                + " no longer present; removing system privileges for "                                + deletedAppName;                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;                    }                    logCriticalInfo(Log.WARN, msg);                }                /**                 * Make sure all system apps that we expected to appear on                 * the userdata partition actually showed up. If they never                 * appeared, crawl back and revive the system version.                 */                for (int i = 0; i < mExpectingBetter.size(); i++) {                    final String packageName = mExpectingBetter.keyAt(i);                    if (!mPackages.containsKey(packageName)) {                        final File scanFile = mExpectingBetter.valueAt(i);                        logCriticalInfo(Log.WARN, "Expected better " + packageName                                + " but never showed up; reverting to system");                        int reparseFlags = mDefParseFlags;                        if (FileUtils.contains(privilegedAppDir, scanFile)) {                            reparseFlags = PackageParser.PARSE_IS_SYSTEM                                    | PackageParser.PARSE_IS_SYSTEM_DIR                                    | PackageParser.PARSE_IS_PRIVILEGED;                        } else if (FileUtils.contains(systemAppDir, scanFile)) {                            reparseFlags = PackageParser.PARSE_IS_SYSTEM                                    | PackageParser.PARSE_IS_SYSTEM_DIR;                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {                            reparseFlags = PackageParser.PARSE_IS_SYSTEM                                    | PackageParser.PARSE_IS_SYSTEM_DIR;                        } else if (FileUtils.contains(oemAppDir, scanFile)) {                            reparseFlags = PackageParser.PARSE_IS_SYSTEM                                    | PackageParser.PARSE_IS_SYSTEM_DIR;                        } else {                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);                            continue;                        }                        mSettings.enableSystemPackageLPw(packageName);                        try {                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);                        } catch (PackageManagerException e) {                            Slog.e(TAG, "Failed to parse original system package: "                                    + e.getMessage());                        }                    }                }            }            mExpectingBetter.clear();            // Resolve the storage manager.            mStorageManagerPackage = getStorageManagerPackageName();            // Resolve protected action filters. Only the setup wizard is allowed to            // have a high priority filter for these actions.            mSetupWizardPackage = getSetupWizardPackageName();            if (mProtectedFilters.size() > 0) {                if (DEBUG_FILTERS && mSetupWizardPackage == null) {                    Slog.i(TAG, "No setup wizard;"                        + " All protected intents capped to priority 0");                }                for (ActivityIntentInfo filter : mProtectedFilters) {                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {                        if (DEBUG_FILTERS) {                            Slog.i(TAG, "Found setup wizard;"                                + " allow priority " + filter.getPriority() + ";"                                + " package: " + filter.activity.info.packageName                                + " activity: " + filter.activity.className                                + " priority: " + filter.getPriority());                        }                        // skip setup wizard; allow it to keep the high priority filter                        continue;                    }                    if (DEBUG_FILTERS) {                        Slog.i(TAG, "Protected action; cap priority to 0;"                                + " package: " + filter.activity.info.packageName                                + " activity: " + filter.activity.className                                + " origPrio: " + filter.getPriority());                    }                    filter.setPriority(0);                }            }            mDeferProtectedFilters = false;            mProtectedFilters.clear();            // Now that we know all of the shared libraries, update all clients to have            // the correct library paths.            updateAllSharedLibrariesLPw(null);            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {                // NOTE: We ignore potential failures here during a system scan (like                // the rest of the commands above) because there's precious little we                // can do about it. A settings error is reported, though.                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);            }            // Now that we know all the packages we are keeping,            // read and update their last usage times.            mPackageUsage.read(mPackages);            mCompilerStats.read();            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,                    SystemClock.uptimeMillis());            Slog.i(TAG, "Time to scan packages: "                    + ((SystemClock.uptimeMillis()-startTime)/1000f)                    + " seconds");            // If the platform SDK has changed since the last time we booted,            // we need to re-grant app permission to catch any new ones that            // appear.  This is really a hack, and means that apps can in some            // cases get permissions that the user didn't initially explicitly            // allow...  it would be nice to have some better way to handle            // this situation.            int updateFlags = UPDATE_PERMISSIONS_ALL;            if (ver.sdkVersion != mSdkVersion) {                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "                        + mSdkVersion + "; regranting permissions for internal storage");                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;            }            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);            ver.sdkVersion = mSdkVersion;            // If this is the first boot or an update from pre-M, and it is a normal            // boot, then we need to initialize the default preferred apps across            // all defined users.            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {                for (UserInfo user : sUserManager.getUsers(true)) {                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);                    applyFactoryDefaultBrowserLPw(user.id);                    primeDomainVerificationsLPw(user.id);                }            }            // Prepare storage for system user really early during boot,            // since core system apps like SettingsProvider and SystemUI            // can't wait for user to start            final int storageFlags;            if (StorageManager.isFileEncryptedNativeOrEmulated()) {                storageFlags = StorageManager.FLAG_STORAGE_DE;            } else {                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;            }            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,                    true /* onlyCoreApps */);            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",                        Trace.TRACE_TAG_PACKAGE_MANAGER);                traceLog.traceBegin("AppDataFixup");                try {                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);                } catch (InstallerException e) {                    Slog.w(TAG, "Trouble fixing GIDs", e);                }                traceLog.traceEnd();                traceLog.traceBegin("AppDataPrepare");                if (deferPackages == null || deferPackages.isEmpty()) {                    return;                }                int count = 0;                for (String pkgName : deferPackages) {                    PackageParser.Package pkg = null;                    synchronized (mPackages) {                        PackageSetting ps = mSettings.getPackageLPr(pkgName);                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {                            pkg = ps.pkg;                        }                    }                    if (pkg != null) {                        synchronized (mInstallLock) {                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,                                    true /* maybeMigrateAppData */);                        }                        count++;                    }                }                traceLog.traceEnd();                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");            }, "prepareAppData");            // If this is first boot after an OTA, and a normal boot, then            // we need to clear code cache directories.            // Note that we do *not* clear the application profiles. These remain valid            // across OTAs and are used to drive profile verification (post OTA) and            // profile compilation (without waiting to collect a fresh set of profiles).            if (mIsUpgrade && !onlyCore) {                Slog.i(TAG, "Build fingerprint changed; clearing code caches");                for (int i = 0; i < mSettings.mPackages.size(); i++) {                    final PackageSetting ps = mSettings.mPackages.valueAt(i);                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {                        // No apps are running this early, so no need to freeze                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);                    }                }                ver.fingerprint = Build.FINGERPRINT;            }            checkDefaultBrowser();            // clear only after permissions and other defaults have been updated            mExistingSystemPackages.clear();            mPromoteSystemApps = false;            // All the changes are done during package scanning.            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;            // can downgrade to reader            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");            mSettings.writeLPr();            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,                    SystemClock.uptimeMillis());            if (!mOnlyCore) {                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();                mRequiredInstallerPackage = getRequiredInstallerLPr();                mRequiredUninstallerPackage = getRequiredUninstallerLPr();                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();                if (mIntentFilterVerifierComponent != null) {                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,                            mIntentFilterVerifierComponent);                } else {                    mIntentFilterVerifier = null;                }                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,                        SharedLibraryInfo.VERSION_UNDEFINED);                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,                        SharedLibraryInfo.VERSION_UNDEFINED);            } else {                mRequiredVerifierPackage = null;                mRequiredInstallerPackage = null;                mRequiredUninstallerPackage = null;                mIntentFilterVerifierComponent = null;                mIntentFilterVerifier = null;                mServicesSystemSharedLibraryPackageName = null;                mSharedSystemSharedLibraryPackageName = null;            }            mInstallerService = new PackageInstallerService(context, this);            final Pair<ComponentName, String> instantAppResolverComponent =                    getInstantAppResolverLPr();            if (instantAppResolverComponent != null) {                if (DEBUG_EPHEMERAL) {                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);                }                mInstantAppResolverConnection = new EphemeralResolverConnection(                        mContext, instantAppResolverComponent.first,                        instantAppResolverComponent.second);                mInstantAppResolverSettingsComponent =                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);            } else {                mInstantAppResolverConnection = null;                mInstantAppResolverSettingsComponent = null;            }            updateInstantAppInstallerLocked(null);            // Read and update the usage of dex files.            // Do this at the end of PM init so that all the packages have their            // data directory reconciled.            // At this point we know the code paths of the packages, so we can validate            // the disk file and build the internal cache.            // The usage file is expected to be small so loading and verifying it            // should take a fairly small time compare to the other activities (e.g. package            // scanning).            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();            for (int userId : currentUserIds) {                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());            }            mDexManager.load(userPackages);        } // synchronized (mPackages)        } // synchronized (mInstallLock)        // Now after opening every single application zip, make sure they        // are all flushed.  Not really needed, but keeps things nice and        // tidy.        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");        Runtime.getRuntime().gc();        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");        FallbackCategoryProvider.loadFallbacks();        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);        // The initial scanning above does many calls into installd while        // holding the mPackages lock, but we're mostly interested in yelling        // once we have a booted system.        mInstaller.setWarnIfHeld(mPackages);        // Expose private service for system components to use.        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);    }

这个构造方法我也不知道到底有几百行了,看其中的重点就可以。
主要做了下面这几件事:

1、 添加一些用户id,如system、phone等;

2、 建立并启动PackageHandler消息循环,用于处理apk安装请求如adbinstall packageinstaller安装apk时就会发送消息;

3、 解析/system/etc/permission下的xml文件,主要是platform.xml,建立permission和gid之间的关系,可以指定一个权限与几个组对应,当一个apk被授予这个权限时它也同时属于这几个组,readPermission(parser, perm);给一些底层用户分配一些权限,如shell授予各种permission,把一个权限赋予一个uid,当apk使用这个uid运行时,就具备了这个权限系统增加的一些应用需要link的扩展的jar库,系统每增加一个硬件,都要添加相应的featrue,将解析结果放入mAvailableFeatures;

4、 检查/data/system/packages.xml是否存在,里面记录了系统的ppermission,以及每个apk的name,codePath,flags,ts,version,userid等,这些信息主要是通过apk安装的时候解析AndroidManifest.xml获取到的,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存相关列表中,当有apk安装,升级,删除时会更新这个文件;

5、 检查BootClassPath,mSharedLibraries及/system/framework下的jar是否需要dexopt,需要则通过dexopt进行优化,这里面主要是调用mInstaller.dexopt进行相应的优化;

6、 建立 java 层的 installer 与 c 层的 installd 的 socket 联接,使得在上层的 install,remove,dexopt等功能最终由installd在底层实现;

7、 启动AppDirObserver线程往中监测/system/framework,/system/app,/data/app/data/app-private目录的事件,主要监听add和remove事件,对于目录监听底层通过innotify机制实现,inotify是一种文件系统的变化通知机制如文件增加、删除等事件可以立刻让用户态得知,它为用户态监视文件系统的变化提供了强大的支持,当有add event时调用scanPackageLI(File,int,int)处理,当有remove event时调用removePackageLI处理;

8、 调用scanDirLI启动apk解析,解析目录包括:/system/framework、/system/app、/vendor/app、/data/app、/data/app-private;

9、 移除临时文件;

10、 赋予package相应请求的权限;

11、 将解析出的Package的相关信息保存到相关全局变量,还有文件。

更多相关文章

  1. Android(安卓)FFmpeg移植总攻略——获取视频帧数(亲测可用)
  2. Android(安卓)记一次解决问题的过程
  3. Android创建Native Binder Service
  4. 高通平台环境搭建,编译,系统引导流程分析
  5. android TextView设置中文字体加粗实现方法
  6. Android(安卓)Activity启动(二) App内部activity跳转过程及原理
  7. 【转】 Android转屏时禁止调用onCreate
  8. LinearLayout和RelativeLayout绘制过程的对比
  9. Android学习感悟之Activity

随机推荐

  1. windows系统上安装与使用Android NDK r5
  2. Android使用Toast显示消息提示框
  3. Android应用开发学习笔记之播放音频
  4. android 退出应用程序
  5. Android实用问题汇总
  6. Android 开发学习 HelloAndroid例子
  7. Android读写XML(下)——创建XML文档
  8. Android入门教程 AsyncTask的使用及execu
  9. 如何编译MTK android模拟器
  10. Android 增加鼠标支持