resolved conflicts for merge of a5d29b2c to jb-mr1-dev-plus-aosp
Change-Id: I21512d61b5c08cee5fed69b34c3275ba5c3fc0d8
This commit is contained in:
@@ -33,6 +33,7 @@ int install(const char *pkgname, uid_t uid, gid_t gid)
|
||||
char pkgdir[PKG_PATH_MAX];
|
||||
char libsymlink[PKG_PATH_MAX];
|
||||
char applibdir[PKG_PATH_MAX];
|
||||
struct stat libStat;
|
||||
|
||||
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
|
||||
ALOGE("invalid uid/gid: %d %d\n", uid, gid);
|
||||
@@ -64,6 +65,25 @@ int install(const char *pkgname, uid_t uid, gid_t gid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lstat(libsymlink, &libStat) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (S_ISDIR(libStat.st_mode)) {
|
||||
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
|
||||
ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
|
||||
return -1;
|
||||
}
|
||||
} else if (S_ISLNK(libStat.st_mode)) {
|
||||
if (unlink(libsymlink) < 0) {
|
||||
ALOGE("couldn't unlink lib directory during install for: %s", libsymlink);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (symlink(applibdir, libsymlink) < 0) {
|
||||
ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
|
||||
strerror(errno));
|
||||
@@ -142,7 +162,7 @@ int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
|
||||
if (stat(pkgdir, &s) < 0) return -1;
|
||||
|
||||
if (s.st_uid != 0 || s.st_gid != 0) {
|
||||
ALOGE("fixing uid of non-root pkg: %s %d %d\n", pkgdir, s.st_uid, s.st_gid);
|
||||
ALOGE("fixing uid of non-root pkg: %s %lu %lu\n", pkgdir, s.st_uid, s.st_gid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -167,18 +187,30 @@ int delete_user_data(const char *pkgname, uid_t persona)
|
||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
|
||||
return -1;
|
||||
|
||||
/* delete contents, excluding "lib", but not the directory itself */
|
||||
return delete_dir_contents(pkgdir, 0, "lib");
|
||||
/* delete contents AND directory, no exceptions */
|
||||
return delete_dir_contents(pkgdir, 1, NULL);
|
||||
}
|
||||
|
||||
int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
|
||||
{
|
||||
char pkgdir[PKG_PATH_MAX];
|
||||
char applibdir[PKG_PATH_MAX];
|
||||
char libsymlink[PKG_PATH_MAX];
|
||||
struct stat libStat;
|
||||
|
||||
// Create the data dir for the package
|
||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) {
|
||||
return -1;
|
||||
}
|
||||
if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, persona)) {
|
||||
ALOGE("cannot create package lib symlink origin path\n");
|
||||
return -1;
|
||||
}
|
||||
if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
|
||||
ALOGE("cannot create package lib symlink dest path\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mkdir(pkgdir, 0751) < 0) {
|
||||
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
|
||||
return -errno;
|
||||
@@ -188,13 +220,55 @@ int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
|
||||
unlink(pkgdir);
|
||||
return -errno;
|
||||
}
|
||||
if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
|
||||
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
|
||||
|
||||
if (lstat(libsymlink, &libStat) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno));
|
||||
unlink(pkgdir);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (S_ISDIR(libStat.st_mode)) {
|
||||
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
|
||||
ALOGE("couldn't delete lib directory during install for non-primary: %s",
|
||||
libsymlink);
|
||||
unlink(pkgdir);
|
||||
return -1;
|
||||
}
|
||||
} else if (S_ISLNK(libStat.st_mode)) {
|
||||
if (unlink(libsymlink) < 0) {
|
||||
ALOGE("couldn't unlink lib directory during install for non-primary: %s",
|
||||
libsymlink);
|
||||
unlink(pkgdir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (symlink(applibdir, libsymlink) < 0) {
|
||||
ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink,
|
||||
applibdir, strerror(errno));
|
||||
unlink(pkgdir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (selinux_android_setfilecon(libsymlink, pkgname, AID_SYSTEM) < 0) {
|
||||
ALOGE("cannot setfilecon dir '%s': %s\n", libsymlink, strerror(errno));
|
||||
unlink(libsymlink);
|
||||
unlink(pkgdir);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
|
||||
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
|
||||
unlink(libsymlink);
|
||||
unlink(pkgdir);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (chown(pkgdir, uid, uid) < 0) {
|
||||
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
|
||||
unlink(libsymlink);
|
||||
unlink(pkgdir);
|
||||
return -errno;
|
||||
}
|
||||
@@ -253,7 +327,7 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
|
||||
/* Get the file stat */
|
||||
if (stat(pkg_path, &s) < 0) continue;
|
||||
/* Get the uid of the package */
|
||||
ALOGI("Adding datadir for uid = %d\n", s.st_uid);
|
||||
ALOGI("Adding datadir for uid = %lu\n", s.st_uid);
|
||||
uid = (uid_t) s.st_uid % PER_USER_RANGE;
|
||||
/* Create the directory for the target */
|
||||
make_user_data(name, uid + target_persona * PER_USER_RANGE,
|
||||
@@ -990,75 +1064,71 @@ done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linklib(const char* dataDir, const char* asecLibDir)
|
||||
int linklib(const char* pkgname, const char* asecLibDir, int userId)
|
||||
{
|
||||
char libdir[PKG_PATH_MAX];
|
||||
char pkgdir[PKG_PATH_MAX];
|
||||
char libsymlink[PKG_PATH_MAX];
|
||||
struct stat s, libStat;
|
||||
int rc = 0;
|
||||
|
||||
const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
|
||||
if (libdirLen >= PKG_PATH_MAX) {
|
||||
ALOGE("library dir len too large");
|
||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
|
||||
ALOGE("cannot create package path\n");
|
||||
return -1;
|
||||
}
|
||||
if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
|
||||
ALOGE("cannot create package lib symlink origin path\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
|
||||
ALOGE("library dir not written successfully: %s\n", strerror(errno));
|
||||
if (stat(pkgdir, &s) < 0) return -1;
|
||||
|
||||
if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
|
||||
ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stat(dataDir, &s) < 0) return -1;
|
||||
|
||||
if (chown(dataDir, AID_INSTALL, AID_INSTALL) < 0) {
|
||||
ALOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chmod(dataDir, 0700) < 0) {
|
||||
ALOGE("linklib() 1: failed to chmod '%s': %s\n", dataDir, strerror(errno));
|
||||
if (chmod(pkgdir, 0700) < 0) {
|
||||
ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lstat(libdir, &libStat) < 0) {
|
||||
ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (S_ISDIR(libStat.st_mode)) {
|
||||
if (delete_dir_contents(libdir, 1, 0) < 0) {
|
||||
if (lstat(libsymlink, &libStat) < 0) {
|
||||
if (errno != ENOENT) {
|
||||
ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
} else if (S_ISLNK(libStat.st_mode)) {
|
||||
if (unlink(libdir) < 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
} else {
|
||||
if (S_ISDIR(libStat.st_mode)) {
|
||||
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
} else if (S_ISLNK(libStat.st_mode)) {
|
||||
if (unlink(libsymlink) < 0) {
|
||||
ALOGE("couldn't unlink lib dir: %s\n", strerror(errno));
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (symlink(asecLibDir, libdir) < 0) {
|
||||
ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libdir, asecLibDir, strerror(errno));
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lchown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
|
||||
ALOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
|
||||
unlink(libdir);
|
||||
if (symlink(asecLibDir, libsymlink) < 0) {
|
||||
ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir,
|
||||
strerror(errno));
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (chmod(dataDir, s.st_mode) < 0) {
|
||||
ALOGE("linklib() 2: failed to chmod '%s': %s\n", dataDir, strerror(errno));
|
||||
if (chmod(pkgdir, s.st_mode) < 0) {
|
||||
ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
|
||||
rc = -errno;
|
||||
}
|
||||
|
||||
if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
|
||||
ALOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
|
||||
if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
|
||||
ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ static int do_movefiles(char **arg, char reply[REPLY_MAX])
|
||||
|
||||
static int do_linklib(char **arg, char reply[REPLY_MAX])
|
||||
{
|
||||
return linklib(arg[0], arg[1]);
|
||||
return linklib(arg[0], arg[1], atoi(arg[2]));
|
||||
}
|
||||
|
||||
struct cmdinfo {
|
||||
@@ -146,7 +146,7 @@ struct cmdinfo cmds[] = {
|
||||
{ "getsize", 5, do_get_size },
|
||||
{ "rmuserdata", 2, do_rm_user_data },
|
||||
{ "movefiles", 0, do_movefiles },
|
||||
{ "linklib", 2, do_linklib },
|
||||
{ "linklib", 3, do_linklib },
|
||||
{ "mkuserdata", 3, do_mk_user_data },
|
||||
{ "rmuser", 1, do_rm_user },
|
||||
{ "cloneuserdata", 3, do_clone_user_data },
|
||||
|
||||
@@ -188,6 +188,7 @@ char *build_string2(char *s1, char *s2);
|
||||
char *build_string3(char *s1, char *s2, char *s3);
|
||||
|
||||
int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);
|
||||
int ensure_media_user_dirs(userid_t userid);
|
||||
|
||||
/* commands.c */
|
||||
|
||||
@@ -209,4 +210,4 @@ int get_size(const char *pkgname, int persona, const char *apkpath, const char *
|
||||
int free_cache(int64_t free_size);
|
||||
int dexopt(const char *apk_path, uid_t uid, int is_public);
|
||||
int movefiles();
|
||||
int linklib(const char* target, const char* source);
|
||||
int linklib(const char* target, const char* source, int userId);
|
||||
|
||||
@@ -36,4 +36,5 @@ interface IMediaContainerService {
|
||||
/** Return file system stats: [0] is total bytes, [1] is available bytes */
|
||||
long[] getFileSystemStats(in String path);
|
||||
void clearDirectory(in String directory);
|
||||
long calculateInstalledSize(in String packagePath, boolean isForwardLocked);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.frameworks.coretests.install_loc">
|
||||
package="com.android.frameworks.coretests.install_bad_dex">
|
||||
|
||||
<application android:hasCode="true">
|
||||
<activity
|
||||
|
||||
@@ -981,19 +981,22 @@ public class PackageManagerTests extends AndroidTestCase {
|
||||
try {
|
||||
DeleteObserver observer = new DeleteObserver(pkgName);
|
||||
|
||||
getPm().deletePackage(pkgName, observer, flags);
|
||||
getPm().deletePackage(pkgName, observer, flags | PackageManager.DELETE_ALL_USERS);
|
||||
observer.waitForCompletion(MAX_WAIT_TIME);
|
||||
|
||||
assertUninstalled(info);
|
||||
|
||||
// Verify we received the broadcast
|
||||
long waitTime = 0;
|
||||
while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
|
||||
receiver.wait(WAIT_TIME_INCR);
|
||||
waitTime += WAIT_TIME_INCR;
|
||||
}
|
||||
if (!receiver.isDone()) {
|
||||
throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
|
||||
// TODO replace this with a CountDownLatch
|
||||
synchronized (receiver) {
|
||||
long waitTime = 0;
|
||||
while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
|
||||
receiver.wait(WAIT_TIME_INCR);
|
||||
waitTime += WAIT_TIME_INCR;
|
||||
}
|
||||
if (!receiver.isDone()) {
|
||||
throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
|
||||
}
|
||||
}
|
||||
return receiver.received;
|
||||
} finally {
|
||||
@@ -1331,7 +1334,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
||||
}
|
||||
|
||||
DeleteObserver observer = new DeleteObserver(packageName);
|
||||
getPm().deletePackage(packageName, observer, 0);
|
||||
getPm().deletePackage(packageName, observer, PackageManager.DELETE_ALL_USERS);
|
||||
observer.waitForCompletion(MAX_WAIT_TIME);
|
||||
|
||||
try {
|
||||
@@ -1357,7 +1360,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
||||
|
||||
if (info != null) {
|
||||
DeleteObserver observer = new DeleteObserver(pkgName);
|
||||
getPm().deletePackage(pkgName, observer, 0);
|
||||
getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS);
|
||||
observer.waitForCompletion(MAX_WAIT_TIME);
|
||||
assertUninstalled(info);
|
||||
}
|
||||
@@ -3126,7 +3129,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
||||
int rawResId = apk2;
|
||||
Uri packageURI = getInstallablePackage(rawResId, outFile);
|
||||
PackageParser.Package pkg = parsePackage(packageURI);
|
||||
getPm().deletePackage(pkg.packageName, null, 0);
|
||||
getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
|
||||
// Check signatures now
|
||||
int match = mContext.getPackageManager().checkSignatures(
|
||||
ip1.pkg.packageName, pkg.packageName);
|
||||
@@ -3265,7 +3268,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
// Delete app2
|
||||
PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
|
||||
getPm().deletePackage(pkg.packageName, null, 0);
|
||||
getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
|
||||
// Check signatures now
|
||||
int match = mContext.getPackageManager().checkSignatures(
|
||||
ip1.pkg.packageName, pkg.packageName);
|
||||
|
||||
@@ -259,6 +259,21 @@ public class DefaultContainerService extends IntentService {
|
||||
eraseFiles(directory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long calculateInstalledSize(String packagePath, boolean isForwardLocked)
|
||||
throws RemoteException {
|
||||
final File packageFile = new File(packagePath);
|
||||
try {
|
||||
return calculateContainerSize(packageFile, isForwardLocked) * 1024 * 1024;
|
||||
} catch (IOException e) {
|
||||
/*
|
||||
* Okay, something failed, so let's just estimate it to be 2x
|
||||
* the file size. Note this will be 0 if the file doesn't exist.
|
||||
*/
|
||||
return packageFile.length() * 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public DefaultContainerService() {
|
||||
|
||||
@@ -369,7 +369,7 @@ public final class Installer {
|
||||
* @param nativeLibPath target native library path
|
||||
* @return -1 on error
|
||||
*/
|
||||
public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath) {
|
||||
public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath, int userId) {
|
||||
if (dataPath == null) {
|
||||
Slog.e(TAG, "linkNativeLibraryDirectory dataPath is null");
|
||||
return -1;
|
||||
@@ -382,6 +382,8 @@ public final class Installer {
|
||||
builder.append(dataPath);
|
||||
builder.append(' ');
|
||||
builder.append(nativeLibPath);
|
||||
builder.append(' ');
|
||||
builder.append(userId);
|
||||
|
||||
return execute(builder.toString());
|
||||
}
|
||||
|
||||
@@ -4088,39 +4088,42 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
Log.i(TAG, "removed obsolete native libraries for system package "
|
||||
+ path);
|
||||
}
|
||||
} else if (!isForwardLocked(pkg) && !isExternal(pkg)) {
|
||||
// Update native library dir if it starts with /data/data
|
||||
if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
|
||||
setInternalAppNativeLibraryPath(pkg, pkgSetting);
|
||||
nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
|
||||
}
|
||||
} else {
|
||||
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
|
||||
/*
|
||||
* Update native library dir if it starts with
|
||||
* /data/data
|
||||
*/
|
||||
if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
|
||||
setInternalAppNativeLibraryPath(pkg, pkgSetting);
|
||||
nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
|
||||
}
|
||||
|
||||
try {
|
||||
if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
|
||||
Slog.e(TAG, "Unable to copy native libraries");
|
||||
try {
|
||||
if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
|
||||
Slog.e(TAG, "Unable to copy native libraries");
|
||||
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Unable to copy native libraries", e);
|
||||
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Unable to copy native libraries", e);
|
||||
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mInstaller.linkNativeLibraryDirectory(dataPathString,
|
||||
pkg.applicationInfo.nativeLibraryDir) == -1) {
|
||||
Slog.e(TAG, "Unable to link native library directory");
|
||||
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
Slog.i(TAG, "Linking native library dir for " + path);
|
||||
int ret = mInstaller.linkNativeLibraryDirectory(dataPathString,
|
||||
pkg.applicationInfo.nativeLibraryDir);
|
||||
if (ret < 0) {
|
||||
Slog.w(TAG, "Failed linking native library dir for " + path);
|
||||
mLastScanError = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
|
||||
return null;
|
||||
final int[] userIds = sUserManager.getUserIds();
|
||||
synchronized (mInstallLock) {
|
||||
for (int userId : userIds) {
|
||||
if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
|
||||
pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
|
||||
Slog.w(TAG, "Failed linking native library dir (user=" + userId
|
||||
+ ")");
|
||||
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
@@ -6327,8 +6330,23 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
|
||||
if (packageFile != null) {
|
||||
// Remote call to find out default install location
|
||||
pkgLite = mContainerService.getMinimalPackageInfo(
|
||||
packageFile.getAbsolutePath(), flags, lowThreshold);
|
||||
final String packageFilePath = packageFile.getAbsolutePath();
|
||||
pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags,
|
||||
lowThreshold);
|
||||
|
||||
/*
|
||||
* If we have too little free space, try to free cache
|
||||
* before giving up.
|
||||
*/
|
||||
if (pkgLite.recommendedInstallLocation
|
||||
== PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
|
||||
final long size = mContainerService.calculateInstalledSize(
|
||||
packageFilePath, isForwardLocked());
|
||||
if (mInstaller.freeCache(size + lowThreshold) >= 0) {
|
||||
pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
|
||||
flags, lowThreshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mContext.revokeUriPermission(mPackageURI,
|
||||
@@ -6350,12 +6368,12 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
ret = PackageManager.INSTALL_FAILED_INVALID_URI;
|
||||
} else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
|
||||
ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
|
||||
} else if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
|
||||
ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
|
||||
} else {
|
||||
// Override with defaults if needed.
|
||||
loc = installLocationPolicy(pkgLite, flags);
|
||||
if (!onSd && !onInt) {
|
||||
if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
|
||||
ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
|
||||
} else if (!onSd && !onInt) {
|
||||
// Override install location with flags
|
||||
if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
|
||||
// Set the flag to install on external media.
|
||||
@@ -9959,20 +9977,14 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
final File newNativeDir = new File(newNativePath);
|
||||
|
||||
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
|
||||
synchronized (mInstallLock) {
|
||||
if (mInstaller.linkNativeLibraryDirectory(
|
||||
pkg.applicationInfo.dataDir, newNativePath) < 0) {
|
||||
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
}
|
||||
NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
|
||||
newCodePath), newNativeDir);
|
||||
} else {
|
||||
synchronized (mInstallLock) {
|
||||
if (mInstaller.linkNativeLibraryDirectory(
|
||||
pkg.applicationInfo.dataDir, newNativePath) < 0) {
|
||||
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
NativeLibraryHelper.copyNativeBinariesIfNeededLI(
|
||||
new File(newCodePath), newNativeDir);
|
||||
}
|
||||
final int[] users = sUserManager.getUserIds();
|
||||
for (int user : users) {
|
||||
if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
|
||||
newNativePath, user) < 0) {
|
||||
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user