PMS构造函数流程分析

本文详细分析了Android系统的PackageManagerService(PMS)构造函数的工作流程,包括用户管理、权限设置、Settings初始化、dex管理、系统配置加载、保护应用设置、消息循环、SELinux策略、应用解析安装等多个环节,覆盖了系统启动时对应用程序、权限、系统配置等核心元素的处理。
摘要由CSDN通过智能技术生成

1、相关代码文件

frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

frameworks\base\services\core\java\com\android\server\pm\Settings.java

frameworks\base\services\core\java\com\android\server\pm\PackageSetting.java

frameworks\base\core\java\com\android\server\SystemConfig.java

frameworks\base\core\java\android\content\pm\PackageParser.java

 

PMS构造函数主要工作流程如下如:

1.mInstaller、mMetrics等的初始化

mFactoryTest = factoryTest;
mOnlyCore = onlyCore;
mMetrics = new DisplayMetrics();
mInstaller = installer;

 2.sUserManager、mPermissionManager、mSettings的初始化

sUserManager = new UserManagerService(context, this,
        new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
mPermissionManager = PermissionManagerService.create(context,
        new DefaultPermissionGrantedCallback() {
            @Override
            public void onDefaultRuntimePermissionsGranted(int userId) {
                synchronized(mPackages) {
                    mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
                }
            }
        }, mPackages /*externalLock*/);
mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);

此处对权限管理、用户管理和settings进行了初始化

2.1、启动用户管理服务

代码通过读取/data/system/users路径下的目录和文件,将系统设置的默认用户信息读如内存中:

private UserManagerService(Context context, PackageManagerService pm,
        UserDataPreparer userDataPreparer, Object packagesLock, File dataDir) {
    mContext = context;
    mPm = pm;
    mPackagesLock = packagesLock;
    mHandler = new MainHandler();
    mUserDataPreparer = userDataPreparer;
    synchronized (mPackagesLock) {
        mUsersDir = new File(dataDir, USER_INFO_DIR);
        mUsersDir.mkdirs();
        // Make zeroth user directory, for services to migrate their files to that location
        File userZeroDir = new File(mUsersDir, String.valueOf(UserHandle.USER_SYSTEM));
        userZeroDir.mkdirs();
        FileUtils.setPermissions(mUsersDir.toString(),
                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
                -1, -1);
        mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
        initDefaultGuestRestrictions();
        readUserListLP();
        sInstance = this;
    }
    mLocalService = new LocalService();
    LocalServices.addService(UserManagerInternal.class, mLocalService);
    mLockPatternUtils = new LockPatternUtils(mContext);
    mUserStates.put(UserHandle.USER_SYSTEM, UserState.STATE_BOOTING);
}

通过添加授权回调,将每次用户的授权情况都实时的通过setting写入到本地文件中:

mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);

private final class MyHandler extends Handler {
    public MyHandler() {
        super(BackgroundThread.getHandler().getLooper());
    }

    @Override
    public void handleMessage(Message message) {
        final int userId = message.what;
        Runnable callback = (Runnable) message.obj;
        //写入到本地文件:/data/system/users/0/runtime-permissions.xml中
        writePermissionsSync(userId);
        if (callback != null) {
            callback.run();
        }
    }
}

Settings初始化将所有的用于存储package信息的路径文件都初始化:

Settings(File dataDir, PermissionSettings permission, Object lock) {
    mLock = lock;
    mPermissions = permission;
    mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);

    mSystemDir = new File(dataDir, "system");
    mSystemDir.mkdirs();
    FileUtils.setPermissions(mSystemDir.toString(),
            FileUtils.S_IRWXU|FileUtils.S_IRWXG
            |FileUtils.S_IROTH|FileUtils.S_IXOTH,
            -1, -1);
    mSettingsFilename = new File(mSystemDir, "packages.xml");
    mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
    mPackageListFilename = new File(mSystemDir, "packages.list");
    FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);

    final File kernelDir = new File("/config/sdcardfs");
    mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;

    // Deprecated: Needed for migration
    mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
    mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}

3.mSettings添加uid

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);
mSettings.addSharedUserLPw("android.uid.se", SE_UID,
        ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
    SharedUserSetting s = mSharedUsers.get(name);
    if (s != null) {
        if (s.userId == uid) {
            return s;
        }
        PackageManagerService.reportSettingsProblem(Log.ERROR,
                "Adding duplicate shared user, keeping first: " + name);
        return null;
    }
    s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
    s.userId = uid;
    if (addUserIdLPw(uid, s, name)) {
        //加入列表中
        mSharedUsers.put(name, s);
        return s;
    }
    return null;
}

4.mPackageDexOptimizer、mDexManager初始化

mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
        "*dexopt*");
DexManager.Listener dexManagerListener = DexLogger.getListener(this,
        installer, mInstallLock);
mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock,
        dexManagerListener);

 5.初始化默认系统配置,各种白名单

SystemConfig systemConfig = SystemConfig.getInstance();

SystemConfig负责从system/etc目录中读取xml文件,将其中预置的应用或者设置读取到列表中保存,如feature列表,省点白名单,共享库,允许使用流量列表等

 

 // Group-ids that are given to all packages as read from etc/permissions/*.xml.
int[] mGlobalGids;

// These are the built-in uid -> permission mappings that were read from the
// system configuration files.
final SparseArray<ArraySet<String>> mSystemPermissions = new SparseArray<>();

// These are the built-in shared libraries that were read from the
// system configuration files.  Keys are the library names; strings are the
// paths to the libraries.
final ArrayMap<String, String> mSharedLibraries  = new ArrayMap<>();

// These are the features this devices supports that were read from the
// system configuration files.
final ArrayMap<String, FeatureInfo> mAvailableFeatures = new ArrayMap<>();

// These are the features which this device doesn't support; the OEM
// partition uses these to opt-out of features from the system image.
final ArraySet<String> mUnavailableFeatures = new ArraySet<>();
// These are the permission -> gid mappings that were read from the
// system configuration files.
final ArrayMap<String, PermissionEntry> mPermissions = new ArrayMap<>();

// These are the packages that are white-listed to be able to run in the
// background while in power save mode (but not whitelisted from device idle modes),
// as read from the configuration files.
final ArraySet<String> mAllowInPowerSaveExceptIdle = new ArraySet<>();

// These are the packages that are white-listed to be able to run in the
// background while in power save mode, as read from the configuration files.
final ArraySet<String> mAllowInPowerSave = new ArraySet<>();

// These are the packages that are white-listed to be able to run in the
// background while in data-usage save mode, as read from the configuration files.
final ArraySet<String> mAllowInDataUsageSave = new ArraySet<>();

// These are the packages that are white-listed to be able to run background location
// without throttling, as read from the configuration files.
final ArraySet<String> mAllowUnthrottledLocation = new ArraySet<>();

// These are the action strings of broadcasts which are whitelisted to
// be delivered anonymously even to apps which target O+.
final ArraySet<String> mAllowImplicitBroadcasts = new ArraySet<>();

// These are the package names of apps which should be in the 'always'
// URL-handling state upon factory reset.
final ArraySet<String> mLinkedApps = new ArraySet<>();

// These are the packages that are whitelisted to be able to run as system user
final ArraySet<String> mSystemUserWhitelistedApps = new ArraySet<>();

// These are the packages that should not run under system user
final ArraySet<String> mSystemUserBlacklistedApps = new ArraySet<>();

// These are the components that are enabled by default as VR mode listener services.
final ArraySet<ComponentName> mDefaultVrComponents = new ArraySet<>();

// These are the permitted backup transport service components
final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();

// Package names that are exempted from private API blacklisting
final ArraySet<String> mHiddenApiPackageWhitelist = new ArraySet<>();

SystemConfig() {
    // Read configuration from system
    readPermissions(Environment.buildPath(
            Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);

    // Read configuration from the old permissions dir
    readPermissions(Environment.buildPath(
            Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);

    // Vendors are only allowed to customze libs, features and privapp permissions
    int vendorPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PRIVAPP_PERMISSIONS;
    if (Build.VERSION.FIRST_SDK_INT <= Build.VERSION_CODES.O_MR1) {
        // For backward compatibility
        vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
    }
    readPermissions(Environment.buildPath(
            Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);

    // Allow ODM to customize system configs as much as Vendor, because /odm is another
    // vendor partition other than /vendor.
    int odmPermissionFlag = vendorPermissionFlag;
    readPermissions(Environment.buildPath(
            Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);

    // Allow OEM to customize features and OEM permissions
    int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS;
    readPermissions(Environment.buildPath(
            Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);

    // Allow Product to customize system configs around libs, features, permissions and apps
    int productPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
            ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
    readPermissions(Environment.buildPath(
            Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
    readPermissions(Environment.buildPath(
            Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);
}

6.初始化保护应用

mProtectedPackages = new ProtectedPackages(mContext);

7.初始化内部消息循环,加入watchdog

mHandlerThread = new ServiceThread(TAG,
        Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值