diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-06-29 14:05:01 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-29 14:05:01 -0700 |
commit | 2c22882181e867c9ba4e74ee973b87a71db3389f (patch) | |
tree | 6593873639d24d7fba98e9b7d9cad8f709bf8de9 | |
parent | 9e1fb41b4fbfbd190560cf48f24939703a13eca5 (diff) | |
parent | 292f8bc9d1b790ab975a87a842c7fabc908b97e0 (diff) | |
download | frameworks_base-2c22882181e867c9ba4e74ee973b87a71db3389f.zip frameworks_base-2c22882181e867c9ba4e74ee973b87a71db3389f.tar.gz frameworks_base-2c22882181e867c9ba4e74ee973b87a71db3389f.tar.bz2 |
Merge "Plumb information from the framework about asec container size."
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | cmds/installd/commands.c | 15 | ||||
-rw-r--r-- | cmds/installd/installd.c | 8 | ||||
-rw-r--r-- | cmds/installd/installd.h | 3 | ||||
-rwxr-xr-x | core/java/android/content/pm/PackageStats.java | 11 | ||||
-rw-r--r-- | core/java/android/os/storage/IMountService.java | 33 | ||||
-rw-r--r-- | core/java/com/android/internal/content/PackageHelper.java | 10 | ||||
-rw-r--r-- | services/java/com/android/server/MountService.java | 24 | ||||
-rw-r--r-- | services/java/com/android/server/pm/Installer.java | 7 | ||||
-rw-r--r-- | services/java/com/android/server/pm/PackageManagerService.java | 29 |
10 files changed, 129 insertions, 12 deletions
diff --git a/api/current.txt b/api/current.txt index a49fa9f..f21a4f3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5897,6 +5897,7 @@ package android.content.pm { field public long codeSize; field public long dataSize; field public long externalCacheSize; + field public long externalCodeSize; field public long externalDataSize; field public long externalMediaSize; field public long externalObbSize; diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index d45ac19..26b9113 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -288,8 +288,9 @@ int protect(char *pkgname, gid_t gid) } int get_size(const char *pkgname, const char *apkpath, - const char *fwdlock_apkpath, - int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize) + const char *fwdlock_apkpath, const char *asecpath, + int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, + int64_t* _asecsize) { DIR *d; int dfd; @@ -300,6 +301,7 @@ int get_size(const char *pkgname, const char *apkpath, int64_t codesize = 0; int64_t datasize = 0; int64_t cachesize = 0; + int64_t asecsize = 0; /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. @@ -324,6 +326,14 @@ int get_size(const char *pkgname, const char *apkpath, } } + /* compute asec size if it is given + */ + if (asecpath != NULL && asecpath[0] != '!') { + if (stat(asecpath, &s) == 0) { + asecsize += stat_size(&s); + } + } + if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, 0)) { goto done; } @@ -370,6 +380,7 @@ done: *_codesize = codesize; *_datasize = datasize; *_cachesize = cachesize; + *_asecsize = asecsize; return 0; } diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index c062d36..feb6b92 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -77,16 +77,18 @@ static int do_get_size(char **arg, char reply[REPLY_MAX]) int64_t codesize = 0; int64_t datasize = 0; int64_t cachesize = 0; + int64_t asecsize = 0; int res = 0; /* pkgdir, apkpath */ - res = get_size(arg[0], arg[1], arg[2], &codesize, &datasize, &cachesize); + res = get_size(arg[0], arg[1], arg[2], arg[3], &codesize, &datasize, &cachesize, &asecsize); /* * Each int64_t can take up 22 characters printed out. Make sure it * doesn't go over REPLY_MAX in the future. */ - snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64, codesize, datasize, cachesize); + snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, + codesize, datasize, cachesize, asecsize); return res; } @@ -137,7 +139,7 @@ struct cmdinfo cmds[] = { { "freecache", 1, do_free_cache }, { "rmcache", 1, do_rm_cache }, { "protect", 2, do_protect }, - { "getsize", 3, do_get_size }, + { "getsize", 4, do_get_size }, { "rmuserdata", 2, do_rm_user_data }, { "movefiles", 0, do_movefiles }, { "linklib", 2, do_linklib }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index e5f6739..c5872b8 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -143,7 +143,8 @@ int move_dex(const char *src, const char *dst); int rm_dex(const char *path); int protect(char *pkgname, gid_t gid); int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpath, - int64_t *codesize, int64_t *datasize, int64_t *cachesize); + const char *asecpath, int64_t *codesize, int64_t *datasize, int64_t *cachesize, + int64_t *asecsize); int free_cache(int64_t free_size); int dexopt(const char *apk_path, uid_t uid, int is_public); int movefiles(); diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java index 11068e5..1205da7 100755 --- a/core/java/android/content/pm/PackageStats.java +++ b/core/java/android/content/pm/PackageStats.java @@ -40,6 +40,12 @@ public class PackageStats implements Parcelable { public long cacheSize; /** + * Size of the secure container on external storage holding the + * application's code. + */ + public long externalCodeSize; + + /** * Size of the external data used by the application (e.g., * <sdcard>/Android/data/<app>) */ @@ -80,6 +86,8 @@ public class PackageStats implements Parcelable { sb.append(dataSize); sb.append(",cacheSize="); sb.append(cacheSize); + sb.append(",externalCodeSize="); + sb.append(externalCodeSize); sb.append(",externalDataSize="); sb.append(externalDataSize); sb.append(",externalCacheSize="); @@ -100,6 +108,7 @@ public class PackageStats implements Parcelable { codeSize = source.readLong(); dataSize = source.readLong(); cacheSize = source.readLong(); + externalCodeSize = source.readLong(); externalDataSize = source.readLong(); externalCacheSize = source.readLong(); externalMediaSize = source.readLong(); @@ -111,6 +120,7 @@ public class PackageStats implements Parcelable { codeSize = pStats.codeSize; dataSize = pStats.dataSize; cacheSize = pStats.cacheSize; + externalCodeSize = pStats.externalCodeSize; externalDataSize = pStats.externalDataSize; externalCacheSize = pStats.externalCacheSize; externalMediaSize = pStats.externalMediaSize; @@ -126,6 +136,7 @@ public class PackageStats implements Parcelable { dest.writeLong(codeSize); dest.writeLong(dataSize); dest.writeLong(cacheSize); + dest.writeLong(externalCodeSize); dest.writeLong(externalDataSize); dest.writeLong(externalCacheSize); dest.writeLong(externalMediaSize); diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index c2dc8ae..9302060 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -655,6 +655,26 @@ public interface IMountService extends IInterface { } return _result; } + + /* + * Returns the filesystem path of a mounted secure container. + */ + public String getSecureContainerFilesystemPath(String id) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + String _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(id); + mRemote.transact(Stub.TRANSACTION_getSecureContainerFilesystemPath, _data, _reply, 0); + _reply.readException(); + _result = _reply.readString(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } } private static final String DESCRIPTOR = "IMountService"; @@ -719,6 +739,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_getVolumeList = IBinder.FIRST_CALL_TRANSACTION + 29; + static final int TRANSACTION_getSecureContainerFilesystemPath = IBinder.FIRST_CALL_TRANSACTION + 30; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1031,6 +1053,15 @@ public interface IMountService extends IInterface { reply.writeParcelableArray(result, 0); return true; } + case TRANSACTION_getSecureContainerFilesystemPath: { + data.enforceInterface(DESCRIPTOR); + String id; + id = data.readString(); + String path = getSecureContainerFilesystemPath(id); + reply.writeNoException(); + reply.writeString(path); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1210,4 +1241,6 @@ public interface IMountService extends IInterface { * Returns list of all mountable volumes. */ public Parcelable[] getVolumeList() throws RemoteException; + + public String getSecureContainerFilesystemPath(String id) throws RemoteException; } diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index b57046c..ec64552 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -135,6 +135,16 @@ public class PackageHelper { return null; } + public static String getSdFilesystem(String cid) { + try { + return getMountService().getSecureContainerFilesystemPath(cid); + } catch (RemoteException e) { + Log.e(TAG, "Failed to get container path for " + cid + + " with exception " + e); + } + return null; + } + public static boolean finalizeSdDir(String cid) { try { int rc = getMountService().finalizeSecureContainer(cid); diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index d3244ec..54e5432 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -1626,6 +1626,30 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC } } + public String getSecureContainerFilesystemPath(String id) { + validatePermission(android.Manifest.permission.ASEC_ACCESS); + waitForReady(); + warnOnNotMounted(); + + try { + ArrayList<String> rsp = mConnector.doCommand(String.format("asec fspath %s", id)); + String []tok = rsp.get(0).split(" "); + int code = Integer.parseInt(tok[0]); + if (code != VoldResponseCode.AsecPathResult) { + throw new IllegalStateException(String.format("Unexpected response code %d", code)); + } + return tok[1]; + } catch (NativeDaemonConnectorException e) { + int code = e.getCode(); + if (code == VoldResponseCode.OpFailedStorageNotFound) { + Slog.i(TAG, String.format("Container '%s' not found", id)); + return null; + } else { + throw new IllegalStateException(String.format("Unexpected response code %d", code)); + } + } + } + public void finishMediaUpdate() { mHandler.sendEmptyMessage(H_UNMOUNT_PM_DONE); } diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java index d10aa97..11ccd60 100644 --- a/services/java/com/android/server/pm/Installer.java +++ b/services/java/com/android/server/pm/Installer.java @@ -307,7 +307,7 @@ class Installer { } public int getSizeInfo(String pkgName, String apkPath, String fwdLockApkPath, - PackageStats pStats) { + String asecPath, PackageStats pStats) { StringBuilder builder = new StringBuilder("getsize"); builder.append(' '); builder.append(pkgName); @@ -315,17 +315,20 @@ class Installer { builder.append(apkPath); builder.append(' '); builder.append(fwdLockApkPath != null ? fwdLockApkPath : "!"); + builder.append(' '); + builder.append(asecPath != null ? asecPath : "!"); String s = transaction(builder.toString()); String res[] = s.split(" "); - if ((res == null) || (res.length != 4)) { + if ((res == null) || (res.length != 5)) { return -1; } try { pStats.codeSize = Long.parseLong(res[1]); pStats.dataSize = Long.parseLong(res[2]); pStats.cacheSize = Long.parseLong(res[3]); + pStats.externalCodeSize = Long.parseLong(res[4]); return Integer.parseInt(res[0]); } catch (NumberFormatException e) { return -1; diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 5a9dae9..22e2dde 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -75,6 +75,7 @@ import android.os.Bundle; import android.os.Environment; import android.os.FileObserver; import android.os.FileUtils; +import android.os.FileUtils.FileStatus; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -4887,8 +4888,7 @@ public class PackageManagerService extends IPackageManager.Stub { private final IPackageStatsObserver mObserver; - public MeasureParams(PackageStats stats, boolean success, - IPackageStatsObserver observer) { + public MeasureParams(PackageStats stats, boolean success, IPackageStatsObserver observer) { mObserver = observer; mStats = stats; mSuccess = success; @@ -5480,6 +5480,17 @@ public class PackageManagerService extends IPackageManager.Stub { } } + /** + * Extract the MountService "container ID" from the full code path of an + * .apk. + */ + static String cidFromCodePath(String fullCodePath) { + int eidx = fullCodePath.lastIndexOf("/"); + String subStr1 = fullCodePath.substring(0, eidx); + int sidx = subStr1.lastIndexOf("/"); + return subStr1.substring(sidx+1, eidx); + } + class SdInstallArgs extends InstallArgs { static final String RES_FILE_NAME = "pkg.apk"; @@ -6831,6 +6842,7 @@ public class PackageManagerService extends IPackageManager.Stub { } PackageParser.Package p; boolean dataOnly = false; + String asecPath = null; synchronized (mPackages) { p = mPackages.get(packageName); if(p == null) { @@ -6842,6 +6854,12 @@ public class PackageManagerService extends IPackageManager.Stub { } p = ps.pkg; } + if (p != null && isExternal(p)) { + String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir); + if (secureContainerId != null) { + asecPath = PackageHelper.getSdFilesystem(secureContainerId); + } + } } String publicSrcDir = null; if(!dataOnly) { @@ -6850,10 +6868,13 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); return false; } - publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null; + if (isForwardLocked(p)) { + publicSrcDir = applicationInfo.publicSourceDir; + } } if (mInstaller != null) { - int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir, pStats); + int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir, + asecPath, pStats); if (res < 0) { return false; } else { |