之前在PKMS预装三方应用时,放在system/third_app下面扫描出现了很多错,原因就是对安装lib和oat文件不熟悉。这篇博客就分析下这两项。
一、安装lib库
安装lib库代码,主要代码都在scanPackageDirtyLI函数中,先是调用了derivePackageAbi,这个函数中就把lib库的路径创建好了,也把lib库copy到这个目录下,然后后面会调用Installd的方法,在data/data/apk相关目录 下的lib 创建软链接到真正放lib的地方。
if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
// Some system apps still use directory structure for native libraries
// in which case we might end up not detecting abi solely based on apk
// structure. Try to detect abi based on directory structure.
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
pkg.applicationInfo.primaryCpuAbi == null) {
setBundledAppAbisAndRoots(pkg, pkgSetting);
setNativeLibraryPaths(pkg);
}
} else {
if ((scanFlags & SCAN_MOVE) != 0) {
// We haven't run dex-opt for this move (since we've moved the compiled output too)
// but we already have this packages package info in the PackageSetting. We just
// use that and derive the native library path based on the new codepath.
pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
}
// Set native library paths again. For moves, the path will be updated based on the
// ABIs we've determined above. For non-moves, the path will be updated based on the
// ABIs we determined during compilation, but the path will depend on the final
// package path (after the rename away from the stage path).
setNativeLibraryPaths(pkg);
}
if (true) Slog.i(TAG, "Linking native library dir for " + path);
final int[] userIds = sUserManager.getUserIds();
synchronized (mInstallLock) {
// Make sure all user data directories are ready to roll; we're okay
// if they already exist
if (!TextUtils.isEmpty(pkg.volumeUuid)) {
for (int userId : userIds) {
if (userId != 0) {
mInstaller.createUserData(pkg.volumeUuid, pkg.packageName,
UserHandle.getUid(userId, pkg.applicationInfo.uid), userId,
pkg.applicationInfo.seinfo);
}
}
}
// Create a native library symlink only if we have native libraries
// and if the native libraries are 32 bit libraries. We do not provide
// this symlink for 64 bit libraries.
if (pkg.applicationInfo.primaryCpuAbi != null &&
!VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
for (int userId : userIds) {
if (mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
nativeLibPath, userId) < 0) {
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
"Failed linking native library dir (user=" + userId + ")");
}
}
}
}
二、 确定lib目录
那我们先从最核心的derivePackageAbi函数开始分析,derivePackageAbi这个函数一开始就调用了setNativeLibraryPaths,因此我们还是先看下这个函数:
private void setNativeLibraryPaths(PackageParser.Package pkg) {
final ApplicationInfo info = pkg.applicationInfo;
final String codePath = pkg.codePath;
final File codeFile = new Fi