Framework底层服务,AMS PMS WMS原理分析_ams pms wms,大厂面试必备技能

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新HarmonyOS鸿蒙全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img

img
img
htt

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注鸿蒙)
img

正文

start() 方法被 Lifecycle 的 onStart() 方法调用,onStart() 方法又被 SystemServiceManager 的 startService() 方法调用。

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

private void start() {

LocalServices.addService(ActivityManagerInternal.class, new LocalService());
mActivityTaskManager.onActivityManagerInternalAdded();
mUgmInternal.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();

}

(3)initPowerManagement、setSystemProcess

在 SystemServer 的 startBootstrapServices() 方法中,调用了 AMS 的 initPowerManagement() 和 setSystemProcess() 方法。

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void initPowerManagement() {
mActivityTaskManager.onInitPowerManagement();
mBatteryStatsService.initPowerManagement();
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
}

public void setSystemProcess() {
try {

synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName, false, 0, new HostingRecord(“system”));
app.setPersistent(true);
app.pid = MY_PID;
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
mPidsSelfLocked.put(app);
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
}

}

(4)setUsageStatsManager

在 SystemServer 的 startCoreServices() 方法中,调用了 AMS 的 setUsageStatsManager() 方法。

/frameworks/base/services/java/com/android/server/SystemServer.java

private void startCoreServices() {

mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));

}
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
mUsageStatsService = usageStatsManager;
mActivityTaskManager.setUsageStatsManager(usageStatsManager);
}

(5)installSystemProviders、setWindowManager、systemReady

在 SystemServer 的 startOtherServices() 方法中,调用了 AMS 的 installSystemProviders()、setWindowManager() 和 systemReady() 方法。

/frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {

WindowManagerService wm = null;

try {

mActivityManagerService.installSystemProviders(); //1

wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);

mActivityManagerService.setWindowManager(wm); //2

}

mActivityManagerService.systemReady(() -> { //3

mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);

try {
mActivityManagerService.startObservingNativeCrashes();
}

try {
startSystemUi(context, windowManagerF);
}

mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

}, BOOT_TIMINGS_TRACE_LOG);
}
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final void installSystemProviders() {
List providers;
synchronized (this) {
ProcessRecord app = mProcessList.mProcessNames.get(“system”, SYSTEM_UID);
providers = generateApplicationProvidersLocked(app);

}
if (providers != null) {
mSystemThread.installSystemProviders(providers);
}

mConstants.start(mContext.getContentResolver());
mCoreSettingsObserver = new CoreSettingsObserver(this);
mActivityTaskManager.installSystemProviders();

}

public void setWindowManager(WindowManagerService wm) {
synchronized (this) {
mWindowManager = wm;
mActivityTaskManager.setWindowManager(wm);
}
}

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
//添加 AMS 服务,方便跨进程调用
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);

synchronized(this) {

mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);
mActivityTaskManager.onSystemReady();
mUserController.onSystemReady();
mAppOpsService.systemReady();
mSystemReady = true;
}

}

已通过 ServiceManager.addService() 将 Context.ACTIVITY_SERVICE 与 AMS 绑定,因此在其他进程中可以通过如下方式获取 AMS。

IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
IActivityManager am = IActivityManager.Stub.asInterface(b);

PMS篇

PackageManagerService(简称 PMS),是 Android 系统核心服务之一,处理包管理相关的工作,常见的比如安装、卸载应用等。PMS是系统服务,那么应用层肯定有个PackageManager作为binder call client端来供使用,但是这里要注意,PackageManager是个抽象类,一般使用的是它的实现类:ApplicationPackageManager。因此PackageManager功能的具体实现还是ApplicationPackageManager这个实现类

PMS的功能

1、安装、卸载应用
2、查询permission相关信息
3、查询Application相关信息(application、activity、receiver、service、provider及相应属性等)
4、查询已安装应用
5、增加、删除permission
6、清除用户数据、缓存、代码等

接口的讲解

1.PackaeManager.java ----------------------> ApplicationPackageManager.java------------------------------->PackageManagerService.java

  • queryIntentActivities(intent, PackageManager.MATCH_ALL): 查询包含这个Intent的Activity
  • resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) : 查询是否有满足这个Intent的Activity
  • clearPackagePreferredActivities() : 清除默认的修改
  • addPreferredActivity() : 修改默认的配置
  • if (r.match > bestMatch) bestMatch = r.match;***
  • replacePreferredActivity() : 替换Intent 匹配相同的Activity
  • getPackageUid(String packageName) : 获取相应包的UID
  • getPermissionInfo(String packageName, int flags (大部分默认为0)) : 通过包名获取权限
  • getApplicationInfo(String packageName,int flags) : 检索出一个应用程序的所有信息
  • getActivityInfo(ComponentName component,int flags) : 检索出一个特定的Activity类的所有信息`
  • getPackageInfo(String packageName, int flags) : 包名获取该包名对应的应用程序的PackageInfo对象
  • getInstalledPackages(int flags(一般传值为0)) : 返回设备上所有已经安装的应用程序集合

入参params flags 附加选项的标志位,你可以理解为筛选条件,可以使用的标志位为:

GET_ACTIVITIES :(packageInfo的标志)表示 返回包(packageInfo)中包含的所有Activity信息
GET_GIDS :(packageInfo的标志)表示 返回关联的GID(groupId)
GET_CONFIGURATIONS :(packageInfo的标志)表示 配置选项信息
GET_INSTRUMENTATION :(PackageInfo的标志)表示 是否使用了instrumentation
GET_PERMISSIONS :(PackageInfo的标志)表示 是否使用了permissions
GET_PROVIDERS :(PackageInfo的标志)表示 是否使用了providers
GET_RECEIVERS :(PackageInfo的标志)表示 是否使用了recevier
GET_SERVICES :(PackageInfo的标志)表示 是否使用了service
GET_SIGNATURES :(PackageInf的标志) 表示是否使用包的签名信息
GET_UNINSTALLED_PACKAGES:参数标志位,表示检索出所有有数据的目录的应用程序(主要是卸载的)的信息

安装过程
1.准备工作

前面说到 APK 的信息会提交给 PMS 进行安装的一系列工作,具体是通过 PackageHandler 发送消息来驱动 APK 的复制和安装,其时序图如下:

上相过程中有几点需要说明:

1、在 installStage 方法中创建了 InstallParams 对象,它对应于包的安装数据,并创建 INIT_COPY 消息并发送给 PackageHandler 进行处理;
2、PackageHandler 在处理 INIT_COPY 消息时,会先判断是否绑定了 DefaultContainerService ,这是用于检查和赋值可移动文件的服务,比较耗时,所以和 PMS 并没有运行在同一个进程中,它们之间通过 IMediaContainerService 进行 IPC 通信,没有绑定则会进行绑定,之后

DefaultContainerConnection 同样是定义在 PMS 中,执行链路如下:

PackageHandler -> doHandleMessage(INIT_COPY)
-> connectToService()
{
连接成功
mBound = true;
}
-> bindServiceAsUser()
-> DefaultContainerConnection
-> onServiceConnected()
-> sendMessage(MCS_BOUND)

3、发送 MCS_BOUND 消息时,根据发送的 Message 是否带 Object 分为两种,如下所示:

void doHandleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {

//mBound用于标识是否绑定了服务,默认值为false
if (!mBound) {

if (!connectToService()) {
// 绑定 DefaultContainerConnection 成功之后会发送
// mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, Object));

//绑定服务失败则return
return;
} else {
//绑定服务成功,将请求添加到ArrayList类型的mPendingInstalls中,等待处理
mPendingInstalls.add(idx, params);
}
} else {
//已经绑定服务
mHandler.sendEmptyMessage(MCS_BOUND);
}
break;
}

}
}
}

4、 MCS_BOUND 消息的处理:

case MCS_BOUND: {
if (DEBUG_INSTALL) Slog.i(TAG, “mcs_bound”);
if (msg.obj != null) {

}
if (mContainerService == null) {//1

} elseif (mPendingInstalls.size() > 0) {//2
HandlerParams params = mPendingInstalls.get(0);//3
if (params != null) {
Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, “queueInstall”,
System.identityHashCode(params));
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, “startCopy”);
if (params.startCopy()) {//4
if (DEBUG_SD_INSTALL) Log.i(TAG,
“Checking for more work or unbind…”);
//如果APK安装成功,删除本次安装请求
if (mPendingInstalls.size() > 0) {
mPendingInstalls.remove(0);
}
if (mPendingInstalls.size() == 0) {
if (mBound) {
//如果没有安装请求了,发送解绑服务的请求
if (DEBUG_SD_INSTALL) Log.i(TAG,
“Posting delayed MCS_UNBIND”);
removeMessages(MCS_UNBIND);
Message ubmsg = obtainMessage(MCS_UNBIND);
sendMessageDelayed(ubmsg, 10000);
}
} else {
if (DEBUG_SD_INSTALL) Log.i(TAG,
“Posting MCS_BOUND for next work”);
//如果还有其他的安装请求,接着发送MCS_BOUND消息继续处理剩余的安装请求
mHandler.sendEmptyMessage(MCS_BOUND);
}
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}else {
Slog.w(TAG, “Empty queue”);
}
break;
}

2.复制APK

2.1 复制过程时序图
HandlerParams 是 PMS 中的抽象类,它的实现类为 PMS 的内部类 InstallParams。HandlerParams 的 startCopy 方法如下所示:

2.2 复制过程的源码分析
PackageManagerService.java#HandlerParams

final boolean startCopy() {
boolean res;
try {
if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
//startCopy方法尝试的次数,超过了4次,就放弃这个安装请求
if (++mRetries > MAX_RETRIES) {
Slog.w(TAG, “Failed to invoke remote methods on default container service. Giving up”);
//MCS_GIVE_UP类型消息,将本次安装请求从安装请求队列mPendingInstalls中移除掉
mHandler.sendEmptyMessage(MCS_GIVE_UP);
handleServiceError();
returnfalse;
} else {
handleStartCopy(); // 注释①
res = true;
}
} catch (RemoteException e) {
if (DEBUG_INSTALL) Slog.i(TAG, “Posting install MCS_RECONNECT”);
mHandler.sendEmptyMessage(MCS_RECONNECT);
res = false;
}
handleReturnCode();
return res;
}

在 注释① 处调用抽象方法 handleStartCopy ,具体实现在 InstallParams 中,如下所示:
PackageManagerService.java#InstallParams

public void handleStartCopy() throws RemoteException {

//确定APK的安装位置。onSd:安装到SD卡, onInt:内部存储即Data分区,ephemeral:安装到临时存储(Instant Apps安装)
finalboolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
finalboolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
finalboolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
PackageInfoLite pkgLite = null;
if (onInt && onSd) {
// APK不能同时安装在SD卡和Data分区
Slog.w(TAG, “Conflicting flags specified for installing on both internal and external”);
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
//安装标志冲突,Instant Apps不能安装到SD卡中
} elseif (onSd && ephemeral) {
Slog.w(TAG, “Conflicting flags specified for installing ephemeral on external”);
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} else {
//获取APK的少量的信息
pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
packageAbiOverride);
if (DEBUG_EPHEMERAL && ephemeral) {
Slog.v(TAG, "pkgLite for install: " + pkgLite);
}

if (ret == PackageManager.INSTALL_SUCCEEDED) {
//判断安装的位置
int loc = pkgLite.recommendedInstallLocation;
if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
} elseif (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
}

}else{
loc = installLocationPolicy(pkgLite); // 注释①

}
}
//根据InstallParams创建InstallArgs对象
final InstallArgs args = createInstallArgs(this); // 注释②
mArgs = args;
if (ret == PackageManager.INSTALL_SUCCEEDED) {

if (!origin.existing && requiredUid != -1
&& isVerificationEnabled(
verifierUser.getIdentifier(), installFlags, installerUid)) {

} else{
ret = args.copyApk(mContainerService, true); // 注释③
}
}
mRet = ret;
}

  • 注释① 处确定了 APK 的安装位置。
  • 注释②处创建 InstallArgs 对象,此对象是一个抽象类,定义了 APK 的复制和重命名APK等安装逻辑,在 Android 8.x 及之前的版本中有三个子类:FileInstallArgs、AsecInstallArgs、MoveInstallArgs。其中 FileInstallArgs 用于处理安装到非ASEC的存储空间的APK,即内部存储空间(Data分区);AsecInstallArgs 用于处理安装到ASEC(mnt/asec)即SD卡中的APK;MoveInstallArgs 用于处理已安装APK的移动的逻辑;但在 Android 9.x 之后已经去掉了 AsecInstallArgs ,
  • 注释③ 处调用 InstallArgs 的 copyApk 方法,这里以 FileInstallArgs 的实现为例,内部会调用 FileInstallArgs 的 doCopyApk 方法:

private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {

try {
finalboolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
//创建临时文件存储目录
final File tempDir =
mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); // 注释①
codeFile = tempDir;
resourceFile = tempDir;
} catch (IOException e) {
Slog.w(TAG, "Failed to create copy file: " + e);
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}

int ret = PackageManager.INSTALL_SUCCEEDED;
ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); // 注释②

return ret;
}

  • 注释① 处用于创建临时存储目录,比如 /data/app/vmdl18300388.tmp,其中 18300388 是安装的 sessionId;
  • 注释②处通过 IMediaContainerService 跨进程调用 DefaultContainerService 的 copyPackage 方法,这个方法会在 DefaultContainerService 所在的进程中将 APK 复制到临时存储目录,比如 /data/app/vmdl18300388.tmp/base.apk ,至此 APK 的复制工作结束。
3.APK的安装

3.1 APK安装时序图
在上述 APK 的赋值调用链的过程中,在 HandlerParams 的 startCopy 方法中,会调用 handleReturnCode 方法,时序图如下:

3.2 安装源码分析
PackageManagerService#handleReturnCode:

void handleReturnCode() {
if (mArgs != null) {
processPendingInstall(mArgs, mRet);
}
}

private void processPendingInstall(final InstallArgs args, final int currentStatus) {
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
PackageInstalledInfo res = new PackageInstalledInfo();
res.setReturnCode(currentStatus);
res.uid = -1;
res.pkg = null;
res.removedInfo = null;
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//安装前处理
args.doPreInstall(res.returnCode); //注释①
synchronized (mInstallLock) {
installPackageTracedLI(args, res); //注释②
}
//安装后收尾
args.doPostInstall(res.returnCode, res.uid); //注释③
}

// 安装结束发送消息
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); // 注释⑤
mHandler.sendMessage(msg);
}
});
}

  • 注释① 处检查APK的状态,在安装前确保安装环境的可靠,如果不可靠会清除复制的APK文件,注释③ 处会检测是否安装成功,失败则删除安装相关的目录和文件。安装完成之后在 注释⑤ 处会发送 POST_INSALL 消息通知已安装完成,此处稍后会说明。
  • 注释② 处的 installPackageTracedLI 会调用 PMS 的 installPackageLI 方法:
    PackageManagerService.java#installPackageLI:

private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {

PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setDisplayMetrics(mMetrics);
pp.setCallback(mPackageParserCallback);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, “parsePackage”);
final PackageParser.Package pkg;
try {
//解析APK
pkg = pp.parsePackage(tmpPackageFile, parseFlags); //注释①
} catch (PackageParserException e) {
res.setError(“Failed parse during installPackageLI”, e);
return;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}

pp = null;
String oldCodePath = null;
boolean systemApp = false;
synchronized (mPackages) {
// 检查APK是否存在
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mSettings.getRenamedPackageLPr(pkgName);//获取没被改名前的包名
if (pkg.mOriginalPackages != null
&& pkg.mOriginalPackages.contains(oldName)
&& mPackages.containsKey(oldName)) {
pkg.setPackageName(oldName); //注释②
pkgName = pkg.packageName;
replace = true;//设置标志位表示是替换安装
if (DEBUG_INSTALL) Slog.d(TAG, “Replacing existing renamed package: oldName=”

  • oldName + " pkgName=" + pkgName);
    }

    }
    PackageSetting ps = mSettings.mPackages.get(pkgName);
    //查看Settings中是否存有要安装的APK的信息,如果有就获取签名信息
    if (ps != null) { //注释③
    if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
    PackageSetting signatureCheckPs = ps;
    if (pkg.applicationInfo.isStaticSharedLibrary()) {
    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
    if (libraryEntry != null) {
    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
    }
    }
    //检查签名的正确性
    if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
  • pkg.packageName + " upgrade keys do not match the "
  • “previously installed version”);
    return;
    }
    }

    }

int N = pkg.permissions.size();
for (int i = N-1; i >= 0; i–) {
//遍历每个权限,对权限进行处理
PackageParser.Permission perm = pkg.permissions.get(i);
BasePermission bp = mSettings.mPermissions.get(perm.info.name);

}
}
}
if (systemApp) {
if (onExternal) {
//系统APP不能在SD卡上替换安装
res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
“Cannot install updates to system apps on sdcard”);
return;
} elseif (instantApp) {
//系统APP不能被Instant App替换
res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
“Cannot update a system app with an instant app”);
return;
}
}

//重命名临时文件
if (!args.doRename(res.returnCode, pkg, oldCodePath)) { //注释④
res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, “Failed rename”);
return;
}

startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);

try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
“installPackageLI”)) {

if (replace) { //注释⑤
//替换安装

replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
installerPackageName, res, args.installReason);
} else {
//安装新的APK
installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
args.user, installerPackageName, volumeUuid, res, args.installReason);
}
}

synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null) {
//更新应用程序所属的用户
res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
ps.setUpdateAvailable(false/updateAvailable/);
}

}
}

这里需要说明几点:

1、注释③处,会先检测 Settings 中保存有要安装的 APK 信息,则说明安装该 APK ,因此需要检验APK 的签名信息,确保安全的进行替换。
2、注释④处,会对临时文件重新命名,例如 /data/app/vmdl18300388.tmp/base.apk,重命名为 /data/app/包名-oONlnRRPYyleU63AveqbYA==/base.apk。新的包名后面带上的一串字母和数字的混合字符串,是使用MD5的方式对随机生成的16个字符进行加密之后的产物。
3、注释⑤处,根据 replace 来做区分,如果是替换安装就会调用replacePackageLIF方法,其方法内部还会对系统APP和非系统APP进行区分处理,如果是新安装APK会调用installNewPackageLIF方法
PackageManagerService.java#installNewPackageLIF:

private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
PackageInstalledInfo res, int installReason) {

try {
//扫描APK
PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
System.currentTimeMillis(), user);
//更新Settings信息
updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
//安装成功后,为新安装的应用程序准备数据
prepareAppDataAfterInstallLIF(newPackage);

} else {
//安装失败则删除APK
deletePackageLIF(pkgName, UserHandle.ALL, false, null,
PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
}
} catch (PackageManagerException e) {
res.setError("Package couldn’t be installed in " + pkg.codePath, e);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}

4.发送消息

在上面 processPendingInstall 方法的源码分析中,在 注释⑤ 处会发送 POST_INSTALL 消息通知安装完成,那么接下来就来具体看一看在 PackageHandler 中是怎么处理这个消息的。

class PackageHandler extends Handler {
void doHandleMessage(Message msg) {
switch (msg.what) {
… …

case POST_INSTALL: {
… …
handlePackagePostInstall();
… …
break;
}
}
}
}

private void handlePackagePostInstall(…){
// 如果已经成功的安装了应用,在发送广播之前先授予一些必要的权限
grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
args.installGrantPermissions);

// 安装完成之后发送"ACTION_PACKAGE_ADDED"广播
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
packageName, extras, null, null, firstUsers);

// 如果是升级更新安装,还会发送ACTION_PACKAGE_REPLACED和ACTION_MY_PACKAGE_REPLACED广播
// 这两个广播不同之处在于PACKAGE_REPLACE将携带一个extra信息
sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
packageName, extras, null, null, updateUsers);
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null, null, packageName, null, updateUsers);

// 执行gc操作
Runtime.getRuntime().gc();

// 调用FileInstallArgs的doPostDeleteLI进行资源清理
res.removedInfo.args.doPostDeleteLI(true);

// 回调onPackageInstalled方法
installObserver.onPackageInstalled(res.name, res.returnCode,
res.returnMsg, extras);
}

以上为主要的方法摘要,具体可总结为:

1、第一步:这里主要是先将安装信息从安装列列表中移除,这个也是前面在processPendingInstall中添加的
2、第二步:安装成功后,获取运行时权限
3、第三步:获取权限后,发送ACTION_PACKAGE_ADDED广播,告诉Laucher之流,更新icon
4、第四步:如果是升级更新则在发送两条广播

  • ACTION_PACKAGE_REPLACED:一个新版本的应用安装到设备上,替换换之前已经存在的版本
  • ACTION_MY_PACKAGE_REPLACED:应用的新版本替换旧版本被安装,只发给被更新的应用自己

5、第五步:如果安装包中设置了PRIVATE_FLAG_FORWARD_LOCK或者被要求安装在SD卡上,则调用sendResourcesChangedBroadcast方法来发送一个资源更改的广播
6、第六步:如果该应用是一个浏览器,则要清除浏览器设置,重新检查浏览器设置
7、第七步:强制调用gc,出发JVM进行垃圾回收操作
8、第八步:删除旧的安装信息
9、回调回调 IPackageInstallObserver2 的 packageInstalled 方法。告诉 PackageInstaller 安装结果。从而实现了安装回调到UI层

5.安装总结

上述几部分大致说明 PMS 处理 APK 的主要步骤,可总结如下:

1、当 PackageInstaller 将 APK 的信息提交给 PMS 处理,PMS 会通过向 PackageHandler 发送消息来驱动 APK 的复制和安装工作
2、PMS 发送 INIT_COPY 和 MCS_BOUND 类型的消息,控制 PackageHandler 来绑定 DefaultContainerService 来完成 APK 的复制等工作
3、复制 APK 完成之后,则开始进行安装 APK 的流程,包括安装前的检查、安装 APK 和安装后的收尾工作。

WMS篇

WindowManagerService服务(WMS)的实现是相当复杂的,毕竟它要管理的整个系统所有窗口的UI,而在任何一个系统中,窗口管理子系统都是极其复杂的。而WMS就是管理整个系统的窗口的。

WMS功能
  • 窗口管理:负责启动、添加、删除窗口,管理窗口大小、层级,核心成员有:WindowContainer、RootWindowContainer、* DisplayContent、TaskStack、Task、AppWindowToken、WindowState;
  • 窗口动画:由其子系统 WindowAnimator 管理;
  • 输入系统中转站:通过对窗口的触摸从而产生触摸事件,由 InputMethodService(IMS)对触摸事件进行处理,它会寻找一个最合适的窗口处理触摸反馈信息;
  • Surface 管理:为每个窗口分配一块 Surface,用于绘制要显示的内容。

WMS创建过程中线程关系

WMS 创建过程中涉及到的类主要有 SystemServer、WindowManagerService(WMS)、WindowManagerPolicy(WMP),它们都在 system_server 进程中运行,但是会在不同线程中运行,如下所示。

WMS启动流程

(1)main

public static void main(String[] args) {
new SystemServer().run();
}

(2)run

/frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
try {

// 创建Looper
Looper.prepareMainLooper();
// 加载libandroid_servers.so
System.loadLibrary(“android_servers”);
// 创建系统的 Context:ContextImpl.createSystemContext(new ActivityThread())
createSystemContext();
// 创建 SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

}

try {
//启动引导服务,ActivityManagerService、ActivityTaskManagerService、PackageManagerService、PowerManagerService、DisplayManagerService 等
startBootstrapServices();
//启动核心服务,BatteryService、UsageStatusService 等
startCoreServices();
//启动其他服务,InputManagerService、WindowManagerService、CameraService、AlarmManagerService 等
startOtherServices();

}

// 开启消息循环
Looper.loop();
}

(3)startOtherServices

/frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {

WindowManagerService wm = null;

InputManagerService inputManager = null;

try {

inputManager = new InputManagerService(context);

//PhoneWindowManager 是 WMP 的实现类
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager, false, DUMP_FLAG_PRIORITY_CRITICAL);

mActivityManagerService.setWindowManager(wm);

wm.onInitReady(); //initPolicy

//wm 的 mInputManagerCallback 属性在定义时就被初始化
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();

}

try {
wm.displayReady(); //初始化屏幕信息
}

try {
wm.systemReady(); //通知 WMS 系统的初始化完成
}

final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);

}

注意:在 WindowManagerService.main() 中,传入了 InputManagerService、PhoneWindowManager(WindowManagerPolicy 的实现类)、ActivityTaskManagerService(简称 ATMS

通过 ServiceManager.addService() 将 Context.WINDOW_SERVICE 与 WMS 绑定,因此在其他进程中可以通过如下方式获取 WMS。

IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
IWindowManager wm = IWindowManager.Stub.asInterface(b);

(3)main

public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs,
final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm) {
return main(context, im, showBootMsgs, onlyCore, policy, atm, SurfaceControl.Transaction::new);
}

public static WindowManagerService main(final Context context, final InputManagerService im, final boolean showBootMsgs,
final boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
//在 android.display 线程中创建 WMS(此时 system_server 线程阻塞)
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, atm, transactionFactory), 0);
return sInstance;
}

WMS 初始化

本节主要研究 WMS 在初始化时做的工作。

(1)构造函数

/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java

private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, boolean onlyCore,
WindowManagerPolicy policy, ActivityTaskManagerService atm, TransactionFactory transactionFactory) {

mAtmService = atm;
mContext = context;

mInputManager = inputManager;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

mPolicy = policy;
//动画管理
mAnimator = new WindowAnimator(this);
//根容器,其子容器是 DisplayContent
mRoot = new RootWindowContainer(this);
mWindowPlacerLocked = new WindowSurfacePlacer(this);

//mPolicy 是 PhoneWindowManager 对象,WindowManagerPolicy 的实现类
LocalServices.addService(WindowManagerPolicy.class, mPolicy);

//DM
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
//PM
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
//AMS
mActivityManager = ActivityManager.getService();

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

ervice atm, TransactionFactory transactionFactory) {

mAtmService = atm;
mContext = context;

mInputManager = inputManager;
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

mPolicy = policy;
//动画管理
mAnimator = new WindowAnimator(this);
//根容器,其子容器是 DisplayContent
mRoot = new RootWindowContainer(this);
mWindowPlacerLocked = new WindowSurfacePlacer(this);

//mPolicy 是 PhoneWindowManager 对象,WindowManagerPolicy 的实现类
LocalServices.addService(WindowManagerPolicy.class, mPolicy);

//DM
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
//PM
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
//AMS
mActivityManager = ActivityManager.getService();

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注鸿蒙)
[外链图片转存中…(img-68GLejKh-1713585214661)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 13
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值