Merge "Don't call into pkg mgr svc w/ lock held" into nyc-mr1-dev
This commit is contained in:
@@ -109,6 +109,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
final int installerUid;
|
final int installerUid;
|
||||||
final SessionParams params;
|
final SessionParams params;
|
||||||
final long createdMillis;
|
final long createdMillis;
|
||||||
|
final int defaultContainerGid;
|
||||||
|
|
||||||
/** Staging location where client data is written. */
|
/** Staging location where client data is written. */
|
||||||
final File stageDir;
|
final File stageDir;
|
||||||
@@ -199,13 +200,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
private final Handler.Callback mHandlerCallback = new Handler.Callback() {
|
private final Handler.Callback mHandlerCallback = new Handler.Callback() {
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(Message msg) {
|
public boolean handleMessage(Message msg) {
|
||||||
|
// Cache package manager data without the lock held
|
||||||
|
final PackageInfo pkgInfo = mPm.getPackageInfo(
|
||||||
|
params.appPackageName, PackageManager.GET_SIGNATURES /*flags*/, userId);
|
||||||
|
final ApplicationInfo appInfo = mPm.getApplicationInfo(
|
||||||
|
params.appPackageName, 0, userId);
|
||||||
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (msg.obj != null) {
|
if (msg.obj != null) {
|
||||||
mRemoteObserver = (IPackageInstallObserver2) msg.obj;
|
mRemoteObserver = (IPackageInstallObserver2) msg.obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
commitLocked();
|
commitLocked(pkgInfo, appInfo);
|
||||||
} catch (PackageManagerException e) {
|
} catch (PackageManagerException e) {
|
||||||
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
|
final String completeMsg = ExceptionUtils.getCompleteMessage(e);
|
||||||
Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
|
Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg);
|
||||||
@@ -264,6 +271,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
} else {
|
} else {
|
||||||
mPermissionsAccepted = false;
|
mPermissionsAccepted = false;
|
||||||
}
|
}
|
||||||
|
final int uid = mPm.getPackageUid(PackageManagerService.DEFAULT_CONTAINER_PACKAGE,
|
||||||
|
PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
|
||||||
|
defaultContainerGid = UserHandle.getSharedAppGid(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionInfo generateInfo() {
|
public SessionInfo generateInfo() {
|
||||||
@@ -520,7 +530,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget();
|
mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void commitLocked() throws PackageManagerException {
|
private void commitLocked(PackageInfo pkgInfo, ApplicationInfo appInfo)
|
||||||
|
throws PackageManagerException {
|
||||||
if (mDestroyed) {
|
if (mDestroyed) {
|
||||||
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed");
|
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed");
|
||||||
}
|
}
|
||||||
@@ -538,7 +549,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
// Verify that stage looks sane with respect to existing application.
|
// Verify that stage looks sane with respect to existing application.
|
||||||
// This currently only ensures packageName, versionCode, and certificate
|
// This currently only ensures packageName, versionCode, and certificate
|
||||||
// consistency.
|
// consistency.
|
||||||
validateInstallLocked();
|
validateInstallLocked(pkgInfo, appInfo);
|
||||||
|
|
||||||
Preconditions.checkNotNull(mPackageName);
|
Preconditions.checkNotNull(mPackageName);
|
||||||
Preconditions.checkNotNull(mSignatures);
|
Preconditions.checkNotNull(mSignatures);
|
||||||
@@ -650,7 +661,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
* Note that upgrade compatibility is still performed by
|
* Note that upgrade compatibility is still performed by
|
||||||
* {@link PackageManagerService}.
|
* {@link PackageManagerService}.
|
||||||
*/
|
*/
|
||||||
private void validateInstallLocked() throws PackageManagerException {
|
private void validateInstallLocked(PackageInfo pkgInfo, ApplicationInfo appInfo)
|
||||||
|
throws PackageManagerException {
|
||||||
mPackageName = null;
|
mPackageName = null;
|
||||||
mVersionCode = -1;
|
mVersionCode = -1;
|
||||||
mSignatures = null;
|
mSignatures = null;
|
||||||
@@ -729,10 +741,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
|
|
||||||
if (removeSplitList.size() > 0) {
|
if (removeSplitList.size() > 0) {
|
||||||
// validate split names marked for removal
|
// validate split names marked for removal
|
||||||
final int flags = mSignatures == null ? PackageManager.GET_SIGNATURES : 0;
|
|
||||||
final PackageInfo pkg = mPm.getPackageInfo(params.appPackageName, flags, userId);
|
|
||||||
for (String splitName : removeSplitList) {
|
for (String splitName : removeSplitList) {
|
||||||
if (!ArrayUtils.contains(pkg.splitNames, splitName)) {
|
if (!ArrayUtils.contains(pkgInfo.splitNames, splitName)) {
|
||||||
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
|
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
|
||||||
"Split not found: " + splitName);
|
"Split not found: " + splitName);
|
||||||
}
|
}
|
||||||
@@ -740,11 +750,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
|
|
||||||
// ensure we've got appropriate package name, version code and signatures
|
// ensure we've got appropriate package name, version code and signatures
|
||||||
if (mPackageName == null) {
|
if (mPackageName == null) {
|
||||||
mPackageName = pkg.packageName;
|
mPackageName = pkgInfo.packageName;
|
||||||
mVersionCode = pkg.versionCode;
|
mVersionCode = pkgInfo.versionCode;
|
||||||
}
|
}
|
||||||
if (mSignatures == null) {
|
if (mSignatures == null) {
|
||||||
mSignatures = pkg.signatures;
|
mSignatures = pkgInfo.signatures;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,8 +767,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Partial installs must be consistent with existing install
|
// Partial installs must be consistent with existing install
|
||||||
final ApplicationInfo app = mPm.getApplicationInfo(mPackageName, 0, userId);
|
if (appInfo == null) {
|
||||||
if (app == null) {
|
|
||||||
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
|
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
|
||||||
"Missing existing base package for " + mPackageName);
|
"Missing existing base package for " + mPackageName);
|
||||||
}
|
}
|
||||||
@@ -766,8 +775,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
final PackageLite existing;
|
final PackageLite existing;
|
||||||
final ApkLite existingBase;
|
final ApkLite existingBase;
|
||||||
try {
|
try {
|
||||||
existing = PackageParser.parsePackageLite(new File(app.getCodePath()), 0);
|
existing = PackageParser.parsePackageLite(new File(appInfo.getCodePath()), 0);
|
||||||
existingBase = PackageParser.parseApkLite(new File(app.getBaseCodePath()),
|
existingBase = PackageParser.parseApkLite(new File(appInfo.getBaseCodePath()),
|
||||||
PackageParser.PARSE_COLLECT_CERTIFICATES);
|
PackageParser.PARSE_COLLECT_CERTIFICATES);
|
||||||
} catch (PackageParserException e) {
|
} catch (PackageParserException e) {
|
||||||
throw PackageManagerException.from(e);
|
throw PackageManagerException.from(e);
|
||||||
@@ -777,7 +786,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
|
|
||||||
// Inherit base if not overridden
|
// Inherit base if not overridden
|
||||||
if (mResolvedBaseFile == null) {
|
if (mResolvedBaseFile == null) {
|
||||||
mResolvedBaseFile = new File(app.getBaseCodePath());
|
mResolvedBaseFile = new File(appInfo.getBaseCodePath());
|
||||||
mResolvedInheritedFiles.add(mResolvedBaseFile);
|
mResolvedInheritedFiles.add(mResolvedBaseFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,7 +803,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inherit compiled oat directory.
|
// Inherit compiled oat directory.
|
||||||
final File packageInstallDir = (new File(app.getBaseCodePath())).getParentFile();
|
final File packageInstallDir = (new File(appInfo.getBaseCodePath())).getParentFile();
|
||||||
mInheritedFilesBase = packageInstallDir;
|
mInheritedFilesBase = packageInstallDir;
|
||||||
final File oatDir = new File(packageInstallDir, "oat");
|
final File oatDir = new File(packageInstallDir, "oat");
|
||||||
if (oatDir.exists()) {
|
if (oatDir.exists()) {
|
||||||
@@ -822,7 +831,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertApkConsistent(String tag, ApkLite apk) throws PackageManagerException {
|
private void assertApkConsistent(String tag, ApkLite apk)
|
||||||
|
throws PackageManagerException {
|
||||||
if (!mPackageName.equals(apk.packageName)) {
|
if (!mPackageName.equals(apk.packageName)) {
|
||||||
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package "
|
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package "
|
||||||
+ apk.packageName + " inconsistent with " + mPackageName);
|
+ apk.packageName + " inconsistent with " + mPackageName);
|
||||||
@@ -1035,10 +1045,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
|||||||
"Failed to finalize container " + cid);
|
"Failed to finalize container " + cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int uid = mPm.getPackageUid(PackageManagerService.DEFAULT_CONTAINER_PACKAGE,
|
if (!PackageHelper.fixSdPermissions(cid, defaultContainerGid, null)) {
|
||||||
PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
|
|
||||||
final int gid = UserHandle.getSharedAppGid(uid);
|
|
||||||
if (!PackageHelper.fixSdPermissions(cid, gid, null)) {
|
|
||||||
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
|
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
|
||||||
"Failed to fix permissions on container " + cid);
|
"Failed to fix permissions on container " + cid);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user