Mark resource-only splits as hasCode=false.
PackageManagerService now skips dexopt for split APKs that don't declare they have code. Also surface more detailed error messages in logs. Bug: 14975160 Change-Id: Ie6078dba724815020cee59b7fc52317e88ca097a
This commit is contained in:
@@ -846,7 +846,7 @@ public class PackageParser {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
|
||||
"Unable to read AndroidManifest.xml of " + apkPath);
|
||||
"Failed to read manifest from " + apkPath, e);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(parser);
|
||||
IoUtils.closeQuietly(assets);
|
||||
@@ -895,7 +895,7 @@ public class PackageParser {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
|
||||
"Unable to read AndroidManifest.xml of " + apkPath);
|
||||
"Failed to read manifest from " + apkPath, e);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(parser);
|
||||
IoUtils.closeQuietly(assets);
|
||||
@@ -910,9 +910,13 @@ public class PackageParser {
|
||||
* omitted here.
|
||||
*/
|
||||
private Package parseSplitApk(Package pkg, Resources res, XmlResourceParser parser, int flags,
|
||||
int splitIndex, String[] outError) throws XmlPullParserException, IOException {
|
||||
int splitIndex, String[] outError) throws XmlPullParserException, IOException,
|
||||
PackageParserException {
|
||||
AttributeSet attrs = parser;
|
||||
|
||||
// We parsed manifest tag earlier; just skip past it
|
||||
parsePackageSplitNames(parser, attrs, flags);
|
||||
|
||||
mParseInstrumentationArgs = null;
|
||||
mParseActivityArgs = null;
|
||||
mParseServiceArgs = null;
|
||||
|
||||
@@ -39,4 +39,20 @@ public class ExceptionUtils {
|
||||
throw new IOException(e.getMessage().substring(PREFIX_IO.length()));
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCompleteMessage(String msg, Throwable t) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
if (msg != null) {
|
||||
builder.append(msg).append(": ");
|
||||
}
|
||||
builder.append(t.getMessage());
|
||||
while ((t = t.getCause()) != null) {
|
||||
builder.append(": ").append(t.getMessage());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String getCompleteMessage(Throwable t) {
|
||||
return getCompleteMessage(null, t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,7 @@ import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.EventLog;
|
||||
import android.util.ExceptionUtils;
|
||||
import android.util.Log;
|
||||
import android.util.LogPrinter;
|
||||
import android.util.PrintStreamPrinter;
|
||||
@@ -9855,6 +9856,18 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
Slog.w(TAG, msg);
|
||||
}
|
||||
|
||||
public void setError(String msg, PackageParserException e) {
|
||||
returnCode = e.error;
|
||||
returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
|
||||
Slog.w(TAG, msg, e);
|
||||
}
|
||||
|
||||
public void setError(String msg, PackageManagerException e) {
|
||||
returnCode = e.error;
|
||||
returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
|
||||
Slog.w(TAG, msg, e);
|
||||
}
|
||||
|
||||
// In some error cases we want to convey more info back to the observer
|
||||
String origPackage;
|
||||
String origPermission;
|
||||
@@ -9908,8 +9921,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
|
||||
} catch (PackageManagerException e) {
|
||||
res.setError(e.error,
|
||||
"Package couldn't be installed in " + pkg.codePath + ": " + e.getMessage());
|
||||
res.setError("Package couldn't be installed in " + pkg.codePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10007,8 +10019,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
|
||||
updatedSettings = true;
|
||||
} catch (PackageManagerException e) {
|
||||
res.setError(e.error,
|
||||
"Package couldn't be installed in " + pkg.codePath + ": " + e.getMessage());
|
||||
res.setError("Package couldn't be installed in " + pkg.codePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10139,8 +10150,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
|
||||
} catch (PackageManagerException e) {
|
||||
res.setError(e.error,
|
||||
"Package couldn't be installed in " + pkg.codePath + ": " + e.getMessage());
|
||||
res.setError("Package couldn't be installed in " + pkg.codePath, e);
|
||||
}
|
||||
|
||||
if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
|
||||
@@ -10278,7 +10288,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
try {
|
||||
pkg = pp.parsePackage(tmpPackageFile, parseFlags);
|
||||
} catch (PackageParserException e) {
|
||||
res.setError(e.error, "Failed parse during installPackageLI: " + e.getMessage());
|
||||
res.setError("Failed parse during installPackageLI", e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10294,7 +10304,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
pp.collectCertificates(pkg, parseFlags);
|
||||
pp.collectManifestDigest(pkg);
|
||||
} catch (PackageParserException e) {
|
||||
res.setError(e.error, "Failed collect during installPackageLI: " + e.getMessage());
|
||||
res.setError("Failed collect during installPackageLI", e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -931,6 +931,13 @@ status_t generateAndroidManifestForSplit(Bundle* bundle, const sp<AaptAssets>& a
|
||||
|
||||
// Build an empty <application> tag (required).
|
||||
sp<XMLNode> app = XMLNode::newElement(filename, String16(), String16("application"));
|
||||
|
||||
// Add the 'hasCode' attribute which is never true for resource splits.
|
||||
if (!addTagAttribute(app, RESOURCES_ANDROID_NAMESPACE, "hasCode",
|
||||
"false", true, true)) {
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
manifest->addChild(app);
|
||||
root->addChild(manifest);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user