diff options
author | Kenny Root <kroot@google.com> | 2012-04-25 15:40:52 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-25 15:40:52 -0700 |
commit | 1fa1de527e541c88fb3809279b67b0dc29419bac (patch) | |
tree | 69105136a6397b0af3594d976df4db5404f37269 /packages | |
parent | d7a2a428db781b3fae5df395dccac1bcab867bd5 (diff) | |
parent | 6dceb88f1c7c42c6ab43834af2c993d599895d82 (diff) | |
download | frameworks_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.java | 120 |
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++; |