Sometimes when AM files are modified and CODE is compiled by AS, Installation Error code: -102 may appear during the Installation of packaged APK due to compilation environment. Then, at what stage does -102 error code refer to PM?
1, PackageManagerService
frameworks\base\services\core\java\com\android\server\pm
1.1 processPendingInstall catches -102 when parsing APP and cache the result into SparseArray MrunningInstall. The key is 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); } args.doPostInstall(res.returncode, res.uid); }... PostInstallData data = new PostInstallData(args, res); mRunningInstalls.put(token, data); //-102 cache to SparseArray<PostInstallData> Mrunningmouse.if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip "+ token); // Pay attention to the token, when processing the POST_INSTALL message according to which -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); }}Copy the code
1.2 installPackageLI Capture -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); // Notice the -102 exception caught herereturn; }}Copy the code
2. PackageParser throws -102
frameworks\base\core\java\android\content\pm
2.1 parsePackage throws -102
public Package parsePackage(File packageFile, int flags) throws PackageParserException {
if (packageFile.isDirectory()) {
return parseClusterPackage(packageFile, flags);
} else {
returnparseMonolithicPackage(packageFile, flags); }}Copy the code
2.2 parseMonolithicPackage throws -102
public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
try {
final Package pkg = parseBaseApk(apkFile, assets, flags);
pkg.codePath = apkFile.getAbsolutePath();
returnpkg; } finally { IoUtils.closeQuietly(assets); }}Copy the code
2.3 parseBaseApk throws -102
Call parseBaseApk(res, Parser, Flags, outError); Raises an exception with install_parse_failed_exception = -102, caught by PackageManagerService in its 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); }}Copy the code
3 processPendingInstall of the PMS sends the POST_INSTALL message
frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
3.1 Sending a POST_INSTALL Message
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); }... }Copy the code
3.2 Notify the application layer installer
mRunningInstalls.get(msg.arg1); Fetch PostInstallData with -102 information based on token.
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); } catch (RemoteException e) {slog. I (TAG,"Observer no longer exists.");
}
}
}
}
}
}
Copy the code
4 Where does the Observer of PackageHandler come from
4.1 Application Layer 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); }}Copy the code
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);
}
Copy the code
4.3 PMS installPackage emits 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);
}
Copy the code
5 How to create an Observer in the PMS
case MCS_BOUND: {
else if (mPendingInstalls.size() > 0) {
HandlerParams params = mPendingInstalls.get(0);
if(params ! = null) {if (params.startCopy()) {
Copy the code
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;
}
Copy the code
public void handleStartCopy() throws RemoteException {
int ret = PackageManager.INSTALL_SUCCEEDED;
final InstallArgs args = createInstallArgs(this);
mArgs = args;
}
Copy the code
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); }}Copy the code
So far, the Observer of processPendingInstall is stored in MrunningMouse. If a -102 exception occurs during APP installation, the PackageInstaller can be notified.