summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2012-04-25 15:40:52 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-04-25 15:40:52 -0700
commit1fa1de527e541c88fb3809279b67b0dc29419bac (patch)
tree69105136a6397b0af3594d976df4db5404f37269 /packages
parentd7a2a428db781b3fae5df395dccac1bcab867bd5 (diff)
parent6dceb88f1c7c42c6ab43834af2c993d599895d82 (diff)
downloadframeworks_base-1fa1de527e541c88fb3809279b67b0dc29419bac.zip
frameworks_base-1fa1de527e541c88fb3809279b67b0dc29419bac.tar.gz
frameworks_base-1fa1de527e541c88fb3809279b67b0dc29419bac.tar.bz2
Merge "Allow forward locked apps to be in ASECs" into jb-dev
Diffstat (limited to 'packages')
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java120
1 files changed, 78 insertions, 42 deletions
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 8e3a3c5..3eec18c 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -81,13 +81,15 @@ public class DefaultContainerService extends IntentService {
* @return Returns the new cache path where the resource has been copied into
*
*/
- public String copyResourceToContainer(final Uri packageURI,
- final String cid,
- final String key, final String resFileName) {
+ public String copyResourceToContainer(final Uri packageURI, final String cid,
+ final String key, final String resFileName, final String publicResFileName,
+ boolean isExternal, boolean isForwardLocked) {
if (packageURI == null || cid == null) {
return null;
}
- return copyResourceInner(packageURI, cid, key, resFileName);
+
+ return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName,
+ isExternal, isForwardLocked);
}
/*
@@ -169,22 +171,23 @@ public class DefaultContainerService extends IntentService {
}
@Override
- public boolean checkInternalFreeStorage(Uri packageUri, long threshold)
- throws RemoteException {
+ public boolean checkInternalFreeStorage(Uri packageUri, boolean isForwardLocked,
+ long threshold) throws RemoteException {
final File apkFile = new File(packageUri.getPath());
try {
- return isUnderInternalThreshold(apkFile, threshold);
- } catch (FileNotFoundException e) {
+ return isUnderInternalThreshold(apkFile, isForwardLocked, threshold);
+ } catch (IOException e) {
return true;
}
}
@Override
- public boolean checkExternalFreeStorage(Uri packageUri) throws RemoteException {
+ public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked)
+ throws RemoteException {
final File apkFile = new File(packageUri.getPath());
try {
- return isUnderExternalThreshold(apkFile);
- } catch (FileNotFoundException e) {
+ return isUnderExternalThreshold(apkFile, isForwardLocked);
+ } catch (IOException e) {
return true;
}
}
@@ -259,12 +262,16 @@ public class DefaultContainerService extends IntentService {
return mBinder;
}
- private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) {
- // Make sure the sdcard is mounted.
- String status = Environment.getExternalStorageState();
- if (!status.equals(Environment.MEDIA_MOUNTED)) {
- Slog.w(TAG, "Make sure sdcard is mounted.");
- return null;
+ private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName,
+ String publicResFileName, boolean isExternal, boolean isForwardLocked) {
+
+ if (isExternal) {
+ // Make sure the sdcard is mounted.
+ String status = Environment.getExternalStorageState();
+ if (!status.equals(Environment.MEDIA_MOUNTED)) {
+ Slog.w(TAG, "Make sure sdcard is mounted.");
+ return null;
+ }
}
// The .apk file
@@ -272,17 +279,18 @@ public class DefaultContainerService extends IntentService {
File codeFile = new File(codePath);
// Calculate size of container needed to hold base APK.
- int sizeMb;
+ final int sizeMb;
try {
- sizeMb = calculateContainerSize(codeFile);
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "File does not exist when trying to copy " + codeFile.getPath());
+ sizeMb = calculateContainerSize(codeFile, isForwardLocked);
+ } catch (IOException e) {
+ Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath());
return null;
}
// Create new container
- final String newCachePath;
- if ((newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid())) == null) {
+ final String newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(),
+ isExternal);
+ if (newCachePath == null) {
Slog.e(TAG, "Failed to create container " + newCid);
return null;
}
@@ -303,6 +311,30 @@ public class DefaultContainerService extends IntentService {
return null;
}
+ if (isForwardLocked) {
+ File publicZipFile = new File(newCachePath, publicResFileName);
+ try {
+ PackageHelper.extractPublicFiles(resFile.getAbsolutePath(), publicZipFile);
+ if (localLOGV) {
+ Slog.i(TAG, "Copied resources to " + publicZipFile);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Could not chown public APK " + publicZipFile.getAbsolutePath() + ": "
+ + e.getMessage());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+
+ try {
+ Libcore.os.chmod(resFile.getAbsolutePath(), 0640);
+ Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644);
+ } catch (ErrnoException e) {
+ Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+ }
+
final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
if (sharedLibraryDir.mkdir()) {
int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir);
@@ -412,18 +444,13 @@ public class DefaultContainerService extends IntentService {
int prefer;
boolean checkBoth = false;
+ final boolean isForwardLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
+
check_inner : {
/*
* Explicit install flags should override the manifest settings.
*/
- if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
- /*
- * Forward-locked applications cannot be installed on SD card,
- * so only allow checking internal storage.
- */
- prefer = PREFER_INTERNAL;
- break check_inner;
- } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
+ if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
prefer = PREFER_INTERNAL;
break check_inner;
} else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
@@ -473,8 +500,8 @@ public class DefaultContainerService extends IntentService {
boolean fitsOnInternal = false;
if (checkBoth || prefer == PREFER_INTERNAL) {
try {
- fitsOnInternal = isUnderInternalThreshold(apkFile, threshold);
- } catch (FileNotFoundException e) {
+ fitsOnInternal = isUnderInternalThreshold(apkFile, isForwardLocked, threshold);
+ } catch (IOException e) {
return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
}
}
@@ -482,8 +509,8 @@ public class DefaultContainerService extends IntentService {
boolean fitsOnSd = false;
if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) {
try {
- fitsOnSd = isUnderExternalThreshold(apkFile);
- } catch (FileNotFoundException e) {
+ fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked);
+ } catch (IOException e) {
return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
}
}
@@ -527,13 +554,17 @@ public class DefaultContainerService extends IntentService {
* @return true if file fits under threshold
* @throws FileNotFoundException when APK does not exist
*/
- private boolean isUnderInternalThreshold(File apkFile, long threshold)
- throws FileNotFoundException {
- final long size = apkFile.length();
+ private boolean isUnderInternalThreshold(File apkFile, boolean isForwardLocked, long threshold)
+ throws IOException {
+ long size = apkFile.length();
if (size == 0 && !apkFile.exists()) {
throw new FileNotFoundException();
}
+ if (isForwardLocked) {
+ size += PackageHelper.extractPublicFiles(apkFile.getAbsolutePath(), null);
+ }
+
final StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath());
final long availInternalSize = (long) internalStats.getAvailableBlocks()
* (long) internalStats.getBlockSize();
@@ -549,12 +580,13 @@ public class DefaultContainerService extends IntentService {
* @return true if file fits
* @throws IOException when file does not exist
*/
- private boolean isUnderExternalThreshold(File apkFile) throws FileNotFoundException {
+ private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked)
+ throws IOException {
if (Environment.isExternalStorageEmulated()) {
return false;
}
- final int sizeMb = calculateContainerSize(apkFile);
+ final int sizeMb = calculateContainerSize(apkFile, isForwardLocked);
final int availSdMb;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
@@ -573,9 +605,9 @@ public class DefaultContainerService extends IntentService {
*
* @param apkFile file from which to calculate size
* @return size in megabytes (2^20 bytes)
- * @throws FileNotFoundException when file does not exist
+ * @throws IOException when there is a problem reading the file
*/
- private int calculateContainerSize(File apkFile) throws FileNotFoundException {
+ private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException {
// Calculate size of container needed to hold base APK.
long sizeBytes = apkFile.length();
if (sizeBytes == 0 && !apkFile.exists()) {
@@ -586,6 +618,10 @@ public class DefaultContainerService extends IntentService {
// container size.
sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(apkFile);
+ if (forwardLocked) {
+ sizeBytes += PackageHelper.extractPublicFiles(apkFile.getPath(), null);
+ }
+
int sizeMb = (int) (sizeBytes >> 20);
if ((sizeBytes - (sizeMb * 1024 * 1024)) > 0) {
sizeMb++;