Methods Summary |
---|
public static long | calculateInstalledSize(android.content.pm.PackageParser.PackageLite pkg, boolean isForwardLocked, java.lang.String abiOverride)
NativeLibraryHelper.Handle handle = null;
try {
handle = NativeLibraryHelper.Handle.create(pkg);
return calculateInstalledSize(pkg, handle, isForwardLocked, abiOverride);
} finally {
IoUtils.closeQuietly(handle);
}
|
public static long | calculateInstalledSize(android.content.pm.PackageParser.PackageLite pkg, NativeLibraryHelper.Handle handle, boolean isForwardLocked, java.lang.String abiOverride)
long sizeBytes = 0;
// Include raw APKs, and possibly unpacked resources
for (String codePath : pkg.getAllCodePaths()) {
final File codeFile = new File(codePath);
sizeBytes += codeFile.length();
if (isForwardLocked) {
sizeBytes += PackageHelper.extractPublicFiles(codeFile, null);
}
}
// Include all relevant native code
sizeBytes += NativeLibraryHelper.sumNativeBinariesWithOverride(handle, abiOverride);
return sizeBytes;
|
private static void | copyZipEntry(java.util.zip.ZipEntry zipEntry, java.util.zip.ZipFile inZipFile, java.util.zip.ZipOutputStream outZipStream)
byte[] buffer = new byte[4096];
int num;
ZipEntry newEntry;
if (zipEntry.getMethod() == ZipEntry.STORED) {
// Preserve the STORED method of the input entry.
newEntry = new ZipEntry(zipEntry);
} else {
// Create a new entry so that the compressed len is recomputed.
newEntry = new ZipEntry(zipEntry.getName());
}
outZipStream.putNextEntry(newEntry);
final InputStream data = inZipFile.getInputStream(zipEntry);
try {
while ((num = data.read(buffer)) > 0) {
outZipStream.write(buffer, 0, num);
}
outZipStream.flush();
} finally {
IoUtils.closeQuietly(data);
}
|
public static java.lang.String | createSdDir(long sizeBytes, java.lang.String cid, java.lang.String sdEncKey, int uid, boolean isExternal)
// Round up to nearest MB, plus another MB for filesystem overhead
final int sizeMb = (int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES) + 1;
try {
IMountService mountService = getMountService();
if (localLOGV)
Log.i(TAG, "Size of container " + sizeMb + " MB");
int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
isExternal);
if (rc != StorageResultCode.OperationSucceeded) {
Log.e(TAG, "Failed to create secure container " + cid);
return null;
}
String cachePath = mountService.getSecureContainerPath(cid);
if (localLOGV) Log.i(TAG, "Created secure container " + cid +
" at " + cachePath);
return cachePath;
} catch (RemoteException e) {
Log.e(TAG, "MountService running?");
}
return null;
|
public static boolean | destroySdDir(java.lang.String cid)
try {
if (localLOGV) Log.i(TAG, "Forcibly destroying container " + cid);
int rc = getMountService().destroySecureContainer(cid, true);
if (rc != StorageResultCode.OperationSucceeded) {
Log.i(TAG, "Failed to destroy container " + cid);
return false;
}
return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to destroy container " + cid +
" with exception " + e);
}
return false;
|
public static long | extractPublicFiles(java.io.File apkFile, java.io.File publicZipFile)Extract public files for the single given APK.
final FileOutputStream fstr;
final ZipOutputStream publicZipOutStream;
if (publicZipFile == null) {
fstr = null;
publicZipOutStream = null;
} else {
fstr = new FileOutputStream(publicZipFile);
publicZipOutStream = new ZipOutputStream(fstr);
Log.d(TAG, "Extracting " + apkFile + " to " + publicZipFile);
}
long size = 0L;
try {
final ZipFile privateZip = new ZipFile(apkFile.getAbsolutePath());
try {
// Copy manifest, resources.arsc and res directory to public zip
for (final ZipEntry zipEntry : Collections.list(privateZip.entries())) {
final String zipEntryName = zipEntry.getName();
if ("AndroidManifest.xml".equals(zipEntryName)
|| "resources.arsc".equals(zipEntryName)
|| zipEntryName.startsWith("res/")) {
size += zipEntry.getSize();
if (publicZipFile != null) {
copyZipEntry(zipEntry, privateZip, publicZipOutStream);
}
}
}
} finally {
try { privateZip.close(); } catch (IOException e) {}
}
if (publicZipFile != null) {
publicZipOutStream.finish();
publicZipOutStream.flush();
FileUtils.sync(fstr);
publicZipOutStream.close();
FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR
| FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1);
}
} finally {
IoUtils.closeQuietly(publicZipOutStream);
}
return size;
|
public static boolean | finalizeSdDir(java.lang.String cid)
try {
int rc = getMountService().finalizeSecureContainer(cid);
if (rc != StorageResultCode.OperationSucceeded) {
Log.i(TAG, "Failed to finalize container " + cid);
return false;
}
return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to finalize container " + cid +
" with exception " + e);
}
return false;
|
public static boolean | fixSdPermissions(java.lang.String cid, int gid, java.lang.String filename)
try {
int rc = getMountService().fixPermissionsSecureContainer(cid, gid, filename);
if (rc != StorageResultCode.OperationSucceeded) {
Log.i(TAG, "Failed to fixperms container " + cid);
return false;
}
return true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to fixperms container " + cid + " with exception " + e);
}
return false;
|
public static android.os.storage.IMountService | getMountService()
IBinder service = ServiceManager.getService("mount");
if (service != null) {
return IMountService.Stub.asInterface(service);
} else {
Log.e(TAG, "Can't get mount service");
throw new RemoteException("Could not contact mount service");
}
|
public static java.lang.String | getSdDir(java.lang.String cid)
try {
return getMountService().getSecureContainerPath(cid);
} catch (RemoteException e) {
Log.e(TAG, "Failed to get container path for " + cid +
" with exception " + e);
}
return null;
|
public static java.lang.String | getSdFilesystem(java.lang.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 java.lang.String[] | getSecureContainerList()
try {
return getMountService().getSecureContainerList();
} catch (RemoteException e) {
Log.e(TAG, "Failed to get secure container list with exception" +
e);
}
return null;
|
public static boolean | isContainerMounted(java.lang.String cid)
try {
return getMountService().isSecureContainerMounted(cid);
} catch (RemoteException e) {
Log.e(TAG, "Failed to find out if container " + cid + " mounted");
}
return false;
|
public static java.lang.String | mountSdDir(java.lang.String cid, java.lang.String key, int ownerUid)
return mountSdDir(cid, key, ownerUid, true);
|
public static java.lang.String | mountSdDir(java.lang.String cid, java.lang.String key, int ownerUid, boolean readOnly)
try {
int rc = getMountService().mountSecureContainer(cid, key, ownerUid, readOnly);
if (rc != StorageResultCode.OperationSucceeded) {
Log.i(TAG, "Failed to mount container " + cid + " rc : " + rc);
return null;
}
return getMountService().getSecureContainerPath(cid);
} catch (RemoteException e) {
Log.e(TAG, "MountService running?");
}
return null;
|
public static boolean | renameSdDir(java.lang.String oldId, java.lang.String newId)
try {
int rc = getMountService().renameSecureContainer(oldId, newId);
if (rc != StorageResultCode.OperationSucceeded) {
Log.e(TAG, "Failed to rename " + oldId + " to " +
newId + "with rc " + rc);
return false;
}
return true;
} catch (RemoteException e) {
Log.i(TAG, "Failed ot rename " + oldId + " to " + newId +
" with exception : " + e);
}
return false;
|
public static java.lang.String | replaceEnd(java.lang.String str, java.lang.String before, java.lang.String after)
if (!str.endsWith(before)) {
throw new IllegalArgumentException(
"Expected " + str + " to end with " + before);
}
return str.substring(0, str.length() - before.length()) + after;
|
public static boolean | resizeSdDir(long sizeBytes, java.lang.String cid, java.lang.String sdEncKey)
// Round up to nearest MB, plus another MB for filesystem overhead
final int sizeMb = (int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES) + 1;
try {
IMountService mountService = getMountService();
int rc = mountService.resizeSecureContainer(cid, sizeMb, sdEncKey);
if (rc == StorageResultCode.OperationSucceeded) {
return true;
}
} catch (RemoteException e) {
Log.e(TAG, "MountService running?");
}
Log.e(TAG, "Failed to create secure container " + cid);
return false;
|
public static int | resolveInstallLocation(android.content.Context context, java.lang.String packageName, int installLocation, long sizeBytes, int installFlags)Given a requested {@link PackageInfo#installLocation} and calculated
install size, pick the actual location to install the app.
ApplicationInfo existingInfo = null;
try {
existingInfo = context.getPackageManager().getApplicationInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES);
} catch (NameNotFoundException ignored) {
}
final int prefer;
final boolean checkBoth;
if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
prefer = RECOMMEND_INSTALL_INTERNAL;
checkBoth = false;
} else if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
prefer = RECOMMEND_INSTALL_EXTERNAL;
checkBoth = false;
} else if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
prefer = RECOMMEND_INSTALL_INTERNAL;
checkBoth = false;
} else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
prefer = RECOMMEND_INSTALL_EXTERNAL;
checkBoth = true;
} else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
// When app is already installed, prefer same medium
if (existingInfo != null) {
if ((existingInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
prefer = RECOMMEND_INSTALL_EXTERNAL;
} else {
prefer = RECOMMEND_INSTALL_INTERNAL;
}
} else {
prefer = RECOMMEND_INSTALL_INTERNAL;
}
checkBoth = true;
} else {
prefer = RECOMMEND_INSTALL_INTERNAL;
checkBoth = false;
}
final boolean emulated = Environment.isExternalStorageEmulated();
final StorageManager storage = StorageManager.from(context);
boolean fitsOnInternal = false;
if (checkBoth || prefer == RECOMMEND_INSTALL_INTERNAL) {
final File target = Environment.getDataDirectory();
fitsOnInternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
}
boolean fitsOnExternal = false;
if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) {
final File target = new UserEnvironment(UserHandle.USER_OWNER)
.getExternalStorageDirectory();
// External is only an option when size is known
if (sizeBytes > 0) {
fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
}
}
if (prefer == RECOMMEND_INSTALL_INTERNAL) {
if (fitsOnInternal) {
return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
}
} else if (!emulated && prefer == RECOMMEND_INSTALL_EXTERNAL) {
if (fitsOnExternal) {
return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
}
}
if (checkBoth) {
if (fitsOnInternal) {
return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
} else if (!emulated && fitsOnExternal) {
return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
}
}
/*
* If they requested to be on the external media by default, return that
* the media was unavailable. Otherwise, indicate there was insufficient
* storage space available.
*/
if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)
&& !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
} else {
return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
}
|
public static boolean | unMountSdDir(java.lang.String cid)
try {
int rc = getMountService().unmountSecureContainer(cid, true);
if (rc != StorageResultCode.OperationSucceeded) {
Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc);
return false;
}
return true;
} catch (RemoteException e) {
Log.e(TAG, "MountService running?");
}
return false;
|