有时修改AM文件,AS编译代码时,可能因编译环境导致打包得到的APK安装时出现Installation error code: -102的现象,那-102错误码到底是指PM在何阶段出现的?
1、PackageManagerService
frameworks\base\services\core\java\com\android\server\pm
1.1 processPendingInstall在解析APP时,捕获-102,并将结果缓存至SparseArray mRunningInstalls中,对应key为token。
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
PackageInstalledInfo res = new PackageInstalledInfo();
res.returnCode = currentStatus;
res.uid = -1;
res.pkg = null;
res.removedInfo = new PackageRemovedInfo();
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
args.doPreInstall(res.returnCode);
synchronized (mInstallLock) {
installPackageLI(args, res);//解析,捕获-102异常,保存在res中
}
args.doPostInstall(res.returnCode, res.uid);
}
...
PostInstallData data = new PostInstallData(args, res);
mRunningInstalls.put(token, data);//-102缓存至SparseArray<PostInstallData> mRunningInstalls中。
if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);//注意token,在处理POST_INSTALL消息时会根据其取出-102
...
if (!doRestore) {
// No restore possible, or the Backup Manager was mysteriously not
// available -- just fire the post-install work request directly.
if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
mHandler.sendMessage(msg);
}
}
1.2 installPackageLI 捕获-102
private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
// Result object to be returned
res.returnCode = PackageManager.INSTALL_SUCCEEDED;
...
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setDisplayMetrics(mMetrics);
final PackageParser.Package pkg;
try {
pkg = pp.parsePackage(tmpPackageFile, parseFlags);
} catch (PackageParserException e) {
res.setError("Failed parse during installPackageLI", e);//注意在此处捕获-102异常
return;
}
}
2、PackageParser抛出-102
frameworks\base\core\java\android\content\pm
2.1 parsePackage 抛出-102
public Package parsePackage(File packageFile, int flags) throws PackageParserException {
if (packageFile.isDirectory()) {
return parseClusterPackage(packageFile, flags);
} else {
return parseMonolithicPackage(packageFile, flags);
}
}
2.2 parseMonolithicPackage 抛出-102
public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
try {
final Package pkg = parseBaseApk(apkFile, assets, flags);
pkg.codePath = apkFile.getAbsolutePath();
return pkg;
} finally {
IoUtils.closeQuietly(assets);
}
}
2.3 parseBaseApk 抛出-102
在调用parseBaseApk(res, parser, flags, outError);会抛出错误码为INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102的异常,由PackageManagerService在其installPackageLI中捕获。
private Package parseBaseApk(File apkFile, AssetManager assets, int flags)
throws PackageParserException {
try {
res = new Resources(assets, mMetrics, null);
assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Build.VERSION.RESOURCES_SDK_INT);
parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
final String[] outError = new String[1];
final Package pkg = parseBaseApk(res, parser, flags, outError);
if (pkg == null) {
throw new PackageParserException(mParseError,
apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
}
pkg.volumeUuid = volumeUuid;
pkg.baseCodePath = apkPath;
pkg.mSignatures = null;
return pkg;
} catch (PackageParserException e) {
throw e;
} catch (Exception e) {
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
"Failed to read manifest from " + apkPath, e);
} finally {
IoUtils.closeQuietly(parser);
}
}
3 PMS的processPendingInstall 发送POST_INSTALL消息
frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
3.1 发送POST_INSTALL消息
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
...
if (!doRestore) {
// No restore possible, or the Backup Manager was mysteriously not
// available -- just fire the post-install work request directly.
if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
mHandler.sendMessage(msg);
}
...
}
3.2 通知应用层安装器
mRunningInstalls.get(msg.arg1);根据token取出含有-102信息的PostInstallData。
class PackageHandler extends Handler {
void doHandleMessage(Message msg) {
switch (msg.what) {
case POST_INSTALL: {
if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
PostInstallData data = mRunningInstalls.get(msg.arg1);
if (data != null) {
InstallArgs args = data.args;
PackageInstalledInfo res = data.res;
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
if (args.observer != null) {
try {
Bundle extras = extrasForInstallResult(res);
args.observer.onPackageInstalled(res.name, res.returnCode,
res.returnMsg, extras);//通知应用层安装器,PMS出现-102异常
} catch (RemoteException e) {
Slog.i(TAG, "Observer no longer exists.");
}
}
}
}
}
}
4 PackageHandler的observer从何来
4.1 应用层PackageInstaller
packages/apps/PackageInstaller
public class InstallAppProgress{
PackageInstallObserver observer = new PackageInstallObserver();
pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
}
class PackageInstallObserver extends IPackageInstallObserver.Stub {
public void packageInstalled(String packageName, int returnCode) {
Message msg = mHandler.obtainMessage(INSTALL_COMPLETE);
msg.arg1 = returnCode;
mHandler.sendMessage(msg);
}
}
4.2 ApplicationPackageManager installPackage
frameworks\base\core\java\android\app\ApplicationPackageManager.java
public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
String installerPackageName) {
final VerificationParams verificationParams = new VerificationParams(null, null,
null, VerificationParams.NO_UID, null);
installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
installerPackageName, verificationParams, null);
}
4.3 PMS installPackage 发出INIT_COPY
frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
@Override
public void installPackage(String originPath, IPackageInstallObserver2 observer,
int installFlags, String installerPackageName, VerificationParams verificationParams,
String packageAbiOverride) {
installPackageAsUser(originPath, observer, installFlags, installerPackageName,
verificationParams, packageAbiOverride, UserHandle.getCallingUserId());
}
public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId) {
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName,
null, verificationParams, user, packageAbiOverride, null);
mHandler.sendMessage(msg);
}
5 PMS中observer的创建过程
case MCS_BOUND: {
else if (mPendingInstalls.size() > 0) {
HandlerParams params = mPendingInstalls.get(0);
if (params != null) {
if (params.startCopy()) {
final boolean startCopy() {
boolean res;
try {
if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
if (++mRetries > MAX_RETRIES) {
Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
mHandler.sendEmptyMessage(MCS_GIVE_UP);
handleServiceError();
return false;
} 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;
}
public void handleStartCopy() throws RemoteException {
int ret = PackageManager.INSTALL_SUCCEEDED;
final InstallArgs args = createInstallArgs(this);
mArgs = args;
}
void handleReturnCode() {
// If mArgs is null, then MCS couldn't be reached. When it
// reconnects, it will try again to install. At that point, this
// will succeed.
if (mArgs != null) {
processPendingInstall(mArgs, mRet);
}
}
至此,processPendingInstall中的observer就存储在mRunningInstalls中了。这样APP安装时,解析出现-102异常,就可以通知应用层PackageInstaller了。