android PackageManagerService

27 篇文章 1 订阅
23 篇文章 3 订阅
深入剖析Android的包管理服务(Package Manager Service, PMS),揭示其启动流程与关键组件,包括SystemServer、PackageManagerService及Settings的构造过程。PMS在Android系统中扮演核心角色,负责管理与监控所有apk安装包。
摘要由CSDN通过智能技术生成

(PMS),顾名思义,其作用就是对我们的apk安装包进行管理服务,作为Android在java层的服务之一,其与所有其他的服务一样都是由SystemServer所启动的。

package com.android.server;

public final class SystemServer {

}
#SystemServer 
  /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }

 public SystemServer() {
        // Check for factory test mode.
        //检查工厂测试模式
        mFactoryTestMode = FactoryTest.getMode();
        // Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
       //请记住,如果它是运行时重启(当sys.boot_completed已经设置)或重启
      //在开机广播发送的流程中,会向系统写入sys.boot_completed,我们依据它可以得出当前系统是否已开机加载结束,这对一些系统服务或者app判断应用状态很有效。
        mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
    }

 

#SystemServer 
private void run() { 
    try {
            traceBeginAndSlog("InitBeforeStartServices");
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it shortly.
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //
            // Default the timezone property to GMT if not set.
            //
            String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
            if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                Slog.w(TAG, "Timezone not set; setting to GMT.");
                SystemProperties.set("persist.sys.timezone", "GMT");
            }

            // If the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();

                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }

            // The system server should never make non-oneway calls
            Binder.setWarnOnBlocking(true);

            // Here we go!
            Slog.i(TAG, "Entered the Android system server!");
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
            }
            /// M: BOOTPROF
            sMtkSystemServerIns.addBootEvent("Android:SysServerInit_START");
            // In case the runtime switched since last boot (such as when
            // the old runtime was removed in an OTA), set the system
            // property so that it is in sync. We can | xq oqi't do this in
            // libnativehelper's JniInvocation::Init code where we already
            // had to fallback to a different runtime because it is
            // running as root and we need to be the system user to set
            // the property. http://b/11463182
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            // Mmmmmm... more memory!
            VMRuntime.getRuntime().clearGrowthLimit();

            // The system server has to run all of the time, so it needs to be
            // as efficient as possible with its memory usage.
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
            Build.ensureFingerprintProperty();

            // Within the system server, it is an error to access Environment paths without
            // explicitly specifying a user.
            Environment.setUserRequired(true);

            // Within the system server, any incoming Bundles should be defused
            // to avoid throwing BadParcelableException.
            BaseBundle.setShouldDefuse(true);

            // Ensure binder calls into the system always run at foreground priority.
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
           //准备消息循环
            Looper.prepareMainLooper();

            // Initialize native services.
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        /// M: Set paramters to mtkSystemserver.
        sMtkSystemServerIns.setPrameters(BOOT_TIMINGS_TRACE_LOG, mSystemServiceManager,
            mSystemContext);
        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            /// M: For mtk systemserver
            sMtkSystemServerIns.startMtkBootstrapServices();
            startCoreServices();
            /// M: for mtk other service.
            sMtkSystemServerIns.startMtkCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }
        /// M: open wtf when load is user or userdebug.
        if (!"eng".equals(Build.TYPE) && !mRuntimeRestart && !isFirstBootOrUpgrade()) {
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
            final int MAX_UPTIME_MILLIS = 60 * 1000;
            if (uptimeMillis > MAX_UPTIME_MILLIS) {
                Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                        "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
            }
        }
        /// M: BOOTPROF
        sMtkSystemServerIns.addBootEvent("Android:SysServerInit_END");
        // Loop forever.
      //进入消息循环
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
}

private PackageManagerService mPackageManagerService;
/**
 * Starts the small tangle of critical services that are needed to get
 * the system off the ground.  These services have complex mutual dependencies
 * which is why we initialize them all in one place here.  Unless your service
 * is also entwined in these dependencies, it should be initialized in one of
 * the other functions.
 */
private void startBootstrapServices() {
    ... ...
//通过PackageManagerService的静态main方法得到PackageManagerService 对象
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
  ... ...
}

 

在startBootstrapServices()方法中,通过PackageManagerService 的静态方法main方法得到一个PackageManagerService 对象。

package com.android.server.pm;

public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender {


}

 

#PackageManagerService
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
        ServiceManager.addService("package", m);
        final PackageManagerNative pmn = m.new PackageManagerNative();
        ServiceManager.addService("package_native", pmn);
        return m;
    }

 

ServiceManager是Binder进程间通信机制的守护进程,其目的非常简单,就是管理Android系统里的Binder对象。重点观察PackageManagerServer的构造过程。

SystemConfig systemConfig = SystemConfig.getInstance();

 

public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {

       ... ...
       //向事件日志写入事件,标识PackageManagerServer 启动
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis());

//SDK版本检查
if (mSdkVersion <= 0) {
            Slog.w(TAG, "**** ro.build.version.sdk not set!");
 }

//上下文环境对象
 mContext = context;
//开机模式是否是工厂模式
mFactoryTest = factoryTest;
//是否仅启动内核
mOnlyCore = onlyCore;
//构造DisplayMetrics对象以便获取尺寸数据
 mMetrics = new DisplayMetrics();
//构造Settings对象存储系统运行时的设置信息
mSettings = new Settings(mPackages);

//添加一些用户uid,首先是Setting的相关信息处理

/** * name = "android.uid.system", * uid = Process.SYSTEM_UID(1000), * pkgFlags = ApplicationInfo.FLAG_SYSTEM ,表示该应用安装在系统进程中,属于系统应用 * ,pkgPrivateFlags = ApplicationInfo.PRIVATE_FLAG_PRIVILEGED */
 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;
        }
//Installer由SystemServer构造,这里通过该对象负责与底层通信,进行具体的安装卸载等操作。
 mInstaller = installer;

  synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
//启动消息处理线程
mHandlerThread = new ServiceThread(TAG,
        Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();

//通过消息处理线程的Looper对象构建一个处理消息的Handler对象
  mHandler = new PackageHandler(mHandlerThread.getLooper());
//使用看门狗监测当前消息处理线程
  Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);

//获取当前的Data目录
File dataDir = Environment.getDataDirectory();
//具体对应的是/data/app目录
 mAppInstallDir = new File(dataDir, "app");
//具体对应的是/data/app-lib目录
 mAppLib32InstallDir = new File(dataDir, "app-lib");
//具体对应的是/data/app-asec目录
 mAsecInternalPath = new File(dataDir, "app-asec").getPath();
//具体对应的是/data/app-private目录
 mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
//构造UserManagerService 对象
sUserManager = new UserManagerService(context, this,
                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);

//获取权限信息
//解析XML文件获取到系统所有权限配置信息。
//SystemConfig这个类扫描   /etc/sysconfig  和    /etc/permissions/目录,
  ArrayMap<String, SystemConfig.PermissionEntry> permConfig
                    = systemConfig.getPermissions();


//保存jar包,依赖库
   ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();


//尝试读取并解析mac_permissions.xml文件
 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();

//判断是否有自定义解析界面(自定义解析界面有什么用?)
 String customResolverActivity = Resources.getSystem().getString(
                    R.string.config_customResolverActivity);

//标识扫描开始的时间戳
long startTime = SystemClock.uptimeMillis();
//将事件写入事件日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime);

//设置扫描模式

//
 File frameworkDir = new File(Environment.getRootDirectory(), "framework");

//获取SDK版本
 final VersionInfo ver = mSettings.getInternalVersion();


//调用scanDirTracedLI  方法扫描/system/priv-app目录下的apk文件进行安装扫描模式为非优化模式
// 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);
 
//同上,针对的是/system/app目录
  // 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);

//同上,针对的是/vender/app目录
  // Collect all vendor packages.
            File vendorAppDir = new File("/vendor/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);

  // Prune any system packages that no longer exist.
//构造一个String类型的ArrayList列表,存储不存在的系统package路径
  final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
// Stub packages must either be replaced with full versions in the /data
// partition or be disabled.

 final List<String> stubSystemApps = new ArrayList<>();

if (!mOnlyCore) {
  // do this first before mucking with mPackages for the "expecting better" case
//遍历成员变量mPackages
  final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();


}


//更新相关信息,并给需要使用使用权限的apk分配相应权限
updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);


 // 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.
//如果本次启动是第一次正常启动,那么同时还需要初始化一些默认首选App
            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : sUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
                    applyFactoryDefaultBrowserLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }

//将信息写到相关文件中
mSettings.writeLPr();

//通知GC回收资源
Runtime.getRuntime().gc();
         }
}
    
}

 

#Settings构造函数,主要是一些文件初始化工作
Settings(Object lock) {
       // Environment.getDataDirectory() : /data
        this(Environment.getDataDirectory(), lock);
    }

    Settings(File dataDir, Object lock) {
        mLock = lock;

        mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);

        mSystemDir = new File(dataDir, "system");// /data/system
        mSystemDir.mkdirs();
        FileUtils.setPermissions(mSystemDir.toString(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG
                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                -1, -1);
        // /data/system/packages.xml
        mSettingsFilename = new File(mSystemDir, "packages.xml");
       // /data/system/packages-backup.xml
        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
        // /data/system/packages.list
        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");
    }

Settings.addSharedUserLPw()


#Settings
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
   // mSharedUsers:ArrayMap<String, SharedUserSetting> 是一个Map,key值为uid字符窜描述,value为SharedUserSetting
    SharedUserSetting s = mSharedUsers.get(name);
    if (s != null) {// 从Map中直接取出来
        if (s.userId == uid) {
            return s;
        }
        PackageManagerService.reportSettingsProblem(Log.ERROR,
                "Adding duplicate shared user, keeping first: " + name);
        return null;
    }
// Map中没有,生成一个
    s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
    s.userId = uid;
    if (addUserIdLPw(uid, s, name)) {
        mSharedUsers.put(name, s);
        return s;
    }
    return null;
}

#Settings
    private boolean addUserIdLPw(int uid, Object obj, Object name) {
        if (uid > Process.LAST_APPLICATION_UID) {  // uid > 19999
            return false;
        }

        if (uid >= Process.FIRST_APPLICATION_UID) { // uid >= 10000 && uid <= 19999-->普通APK所在的进程UID
            int N = mUserIds.size();
            final int index = uid - Process.FIRST_APPLICATION_UID;
            while (index >= N) {
                mUserIds.add(null);
                N++;
            }
            if (mUserIds.get(index) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate user id: " + uid
                        + " name=" + name);
                return false;
            }
            mUserIds.set(index, obj);
        } else { // uid < 10000 && uid > 0-->系统APK所在的进程UID
            if (mOtherUserIds.get(uid) != null) {
                PackageManagerService.reportSettingsProblem(Log.ERROR,
                        "Adding duplicate shared id: " + uid
                                + " name=" + name);
                return false;
            }
            mOtherUserIds.put(uid, obj);
        }
        return true;
    }

 

整个PackageManagerService的构造过程很长,但是,逻辑并不复杂,条理也很清晰。总体来说,PackageManagerService的作用就如它名字所述的那样,主要用来管理应用程序包。

 

 

参考《Android源码设计模式》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值