15b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu/* 25b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * Copyright (C) 2009 The Android Open Source Project 35b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * 45b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * Licensed under the Apache License, Version 2.0 (the "License"); 55b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * you may not use this file except in compliance with the License. 65b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * You may obtain a copy of the License at 75b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * 85b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * http://www.apache.org/licenses/LICENSE-2.0 95b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * 105b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * Unless required by applicable law or agreed to in writing, software 115b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * distributed under the License is distributed on an "AS IS" BASIS, 125b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * See the License for the specific language governing permissions and 145b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * limitations under the License. 155b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu */ 165b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu 175b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapupackage com.android.internal.content; 185b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu 192782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport android.os.FileUtils; 20679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapuimport android.os.IBinder; 21679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapuimport android.os.RemoteException; 22679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapuimport android.os.ServiceManager; 232782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport android.os.storage.IMountService; 24679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapuimport android.os.storage.StorageResultCode; 25679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapuimport android.util.Log; 26679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 27679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapuimport java.io.File; 282782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.io.FileOutputStream; 292782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.io.IOException; 302782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.io.InputStream; 312782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.util.Collections; 322782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.util.zip.ZipEntry; 332782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.util.zip.ZipFile; 342782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport java.util.zip.ZipOutputStream; 352782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root 362782a478d0214cf71a32d4537fc9fb191d1072fbKenny Rootimport libcore.io.IoUtils; 37679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 385b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu/** 395b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * Constants used internally between the PackageManager 405b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu * and media container service transports. 41679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu * Some utility methods to invoke MountService api. 425b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu */ 435b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapupublic class PackageHelper { 445b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu public static final int RECOMMEND_INSTALL_INTERNAL = 1; 455b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu public static final int RECOMMEND_INSTALL_EXTERNAL = 2; 465b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu public static final int RECOMMEND_FAILED_INSUFFICIENT_STORAGE = -1; 475b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu public static final int RECOMMEND_FAILED_INVALID_APK = -2; 48a2b6c3775ed6b8924232d6a01bae4a19740a15f8Suchi Amalapurapu public static final int RECOMMEND_FAILED_INVALID_LOCATION = -3; 49a2b6c3775ed6b8924232d6a01bae4a19740a15f8Suchi Amalapurapu public static final int RECOMMEND_FAILED_ALREADY_EXISTS = -4; 508a9ab24a5c9b595ac0268fcade4b5bbfe7c45c2dSuchi Amalapurapu public static final int RECOMMEND_MEDIA_UNAVAILABLE = -5; 511ebd74acf9977daa42133507e970dab88e08f0efKenny Root public static final int RECOMMEND_FAILED_INVALID_URI = -6; 521ebd74acf9977daa42133507e970dab88e08f0efKenny Root 53cf6eaeaae9e6745dd6e07540812c79821d7043c2Suchi Amalapurapu private static final boolean localLOGV = true; 54679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu private static final String TAG = "PackageHelper"; 55089262dc022d87e31eefc536025be6c015c7ebdeSuchi Amalapurapu // App installation location settings values 56089262dc022d87e31eefc536025be6c015c7ebdeSuchi Amalapurapu public static final int APP_INSTALL_AUTO = 0; 57089262dc022d87e31eefc536025be6c015c7ebdeSuchi Amalapurapu public static final int APP_INSTALL_INTERNAL = 1; 58089262dc022d87e31eefc536025be6c015c7ebdeSuchi Amalapurapu public static final int APP_INSTALL_EXTERNAL = 2; 59679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 6007ba2ae327dbf209da5bafee9cdcb40e03e29d58Kenny Root public static IMountService getMountService() throws RemoteException { 61679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu IBinder service = ServiceManager.getService("mount"); 62679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (service != null) { 63679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return IMountService.Stub.asInterface(service); 64679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } else { 65679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Can't get mount service"); 6607ba2ae327dbf209da5bafee9cdcb40e03e29d58Kenny Root throw new RemoteException("Could not contact mount service"); 67679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 68679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 69679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 706dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root public static String createSdDir(int sizeMb, String cid, String sdEncKey, int uid, 716dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root boolean isExternal) { 72679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu // Create mount point via MountService 7307ba2ae327dbf209da5bafee9cdcb40e03e29d58Kenny Root try { 7407ba2ae327dbf209da5bafee9cdcb40e03e29d58Kenny Root IMountService mountService = getMountService(); 7562e1b4e9d41a01db423b5e4684ecf529ed46106dKenny Root 7607ba2ae327dbf209da5bafee9cdcb40e03e29d58Kenny Root if (localLOGV) 7707ba2ae327dbf209da5bafee9cdcb40e03e29d58Kenny Root Log.i(TAG, "Size of container " + sizeMb + " MB"); 78679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 796dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid, 806dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root isExternal); 81679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (rc != StorageResultCode.OperationSucceeded) { 82679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to create secure container " + cid); 83679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return null; 84679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 85679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu String cachePath = mountService.getSecureContainerPath(cid); 86cf6eaeaae9e6745dd6e07540812c79821d7043c2Suchi Amalapurapu if (localLOGV) Log.i(TAG, "Created secure container " + cid + 87679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu " at " + cachePath); 88679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return cachePath; 89679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 90679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "MountService running?"); 91679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 92679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return null; 93679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 94679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 95679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static String mountSdDir(String cid, String key, int ownerUid) { 96679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 97679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu int rc = getMountService().mountSecureContainer(cid, key, ownerUid); 98679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (rc != StorageResultCode.OperationSucceeded) { 99679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.i(TAG, "Failed to mount container " + cid + " rc : " + rc); 100679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return null; 101679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 102679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return getMountService().getSecureContainerPath(cid); 103679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 104679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "MountService running?"); 105679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 106679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return null; 107679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 108679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 109679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static boolean unMountSdDir(String cid) { 110679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 111cf6eaeaae9e6745dd6e07540812c79821d7043c2Suchi Amalapurapu int rc = getMountService().unmountSecureContainer(cid, true); 112679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (rc != StorageResultCode.OperationSucceeded) { 113679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc); 114679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 115679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 116679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return true; 117679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 118679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "MountService running?"); 119679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 120679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 121679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 122679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 123679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static boolean renameSdDir(String oldId, String newId) { 124679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 125679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu int rc = getMountService().renameSecureContainer(oldId, newId); 126679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (rc != StorageResultCode.OperationSucceeded) { 127679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to rename " + oldId + " to " + 128679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu newId + "with rc " + rc); 129679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 130679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 131679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return true; 132679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 133679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.i(TAG, "Failed ot rename " + oldId + " to " + newId + 134679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu " with exception : " + e); 135679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 136679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 137679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 138679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 139679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static String getSdDir(String cid) { 140679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 141679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return getMountService().getSecureContainerPath(cid); 142679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 143679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to get container path for " + cid + 144679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu " with exception " + e); 145679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 146679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return null; 147679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 148679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 149292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn public static String getSdFilesystem(String cid) { 150292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn try { 151292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn return getMountService().getSecureContainerFilesystemPath(cid); 152292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn } catch (RemoteException e) { 153292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn Log.e(TAG, "Failed to get container path for " + cid + 154292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn " with exception " + e); 155292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn } 156292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn return null; 157292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn } 158292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn 159679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static boolean finalizeSdDir(String cid) { 160679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 161679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu int rc = getMountService().finalizeSecureContainer(cid); 162679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (rc != StorageResultCode.OperationSucceeded) { 163679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.i(TAG, "Failed to finalize container " + cid); 164679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 165679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 166679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return true; 167679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 168679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to finalize container " + cid + 169679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu " with exception " + e); 170679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 171679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 172679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 173679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 174679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static boolean destroySdDir(String cid) { 175679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 176cf6eaeaae9e6745dd6e07540812c79821d7043c2Suchi Amalapurapu if (localLOGV) Log.i(TAG, "Forcibly destroying container " + cid); 177cf6eaeaae9e6745dd6e07540812c79821d7043c2Suchi Amalapurapu int rc = getMountService().destroySecureContainer(cid, true); 178679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu if (rc != StorageResultCode.OperationSucceeded) { 179679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.i(TAG, "Failed to destroy container " + cid); 180679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 181679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 182679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return true; 183679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 184679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to destroy container " + cid + 185679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu " with exception " + e); 186679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 187679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 188679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 189679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 190679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static String[] getSecureContainerList() { 191679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 192679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return getMountService().getSecureContainerList(); 193679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 194679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to get secure container list with exception" + 195679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu e); 196679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 197679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return null; 198679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 199679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu 200679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu public static boolean isContainerMounted(String cid) { 201679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu try { 202679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return getMountService().isSecureContainerMounted(cid); 203679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } catch (RemoteException e) { 204679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu Log.e(TAG, "Failed to find out if container " + cid + " mounted"); 205679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 206679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu return false; 207679bba339ef6948091180c776d6a284cddd812f5Suchi Amalapurapu } 2082782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root 2096dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root public static int extractPublicFiles(String packagePath, File publicZipFile) 2102782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root throws IOException { 2116dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root final FileOutputStream fstr; 2126dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root final ZipOutputStream publicZipOutStream; 2136dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root 2146dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root if (publicZipFile == null) { 2156dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root fstr = null; 2166dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root publicZipOutStream = null; 2176dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } else { 2186dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root fstr = new FileOutputStream(publicZipFile); 2196dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root publicZipOutStream = new ZipOutputStream(fstr); 2206dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } 2216dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root 2226dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root int size = 0; 2236dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root 2242782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root try { 2252782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root final ZipFile privateZip = new ZipFile(packagePath); 2262782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root try { 2272782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root // Copy manifest, resources.arsc and res directory to public zip 2282782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root for (final ZipEntry zipEntry : Collections.list(privateZip.entries())) { 2292782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root final String zipEntryName = zipEntry.getName(); 2302782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root if ("AndroidManifest.xml".equals(zipEntryName) 2312782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root || "resources.arsc".equals(zipEntryName) 2322782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root || zipEntryName.startsWith("res/")) { 2336dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root size += zipEntry.getSize(); 2346dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root if (publicZipFile != null) { 2356dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root copyZipEntry(zipEntry, privateZip, publicZipOutStream); 2366dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } 2372782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2382782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2392782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } finally { 2406dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root try { privateZip.close(); } catch (IOException e) {} 2412782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2422782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root 2436dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root if (publicZipFile != null) { 2446dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root publicZipOutStream.finish(); 2456dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root publicZipOutStream.flush(); 2466dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root FileUtils.sync(fstr); 2476dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root publicZipOutStream.close(); 2486dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR 2496dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1); 2506dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } 2512782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } finally { 2522782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root IoUtils.closeQuietly(publicZipOutStream); 2532782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2546dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root 2556dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root return size; 2562782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2572782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root 2582782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root private static void copyZipEntry(ZipEntry zipEntry, ZipFile inZipFile, 2592782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root ZipOutputStream outZipStream) throws IOException { 2602782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root byte[] buffer = new byte[4096]; 2612782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root int num; 2622782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root 2632782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root ZipEntry newEntry; 2642782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root if (zipEntry.getMethod() == ZipEntry.STORED) { 2652782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root // Preserve the STORED method of the input entry. 2662782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root newEntry = new ZipEntry(zipEntry); 2672782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } else { 2682782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root // Create a new entry so that the compressed len is recomputed. 2692782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root newEntry = new ZipEntry(zipEntry.getName()); 2702782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2712782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root outZipStream.putNextEntry(newEntry); 2722782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root 2732782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root final InputStream data = inZipFile.getInputStream(zipEntry); 2742782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root try { 2752782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root while ((num = data.read(buffer)) > 0) { 2762782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root outZipStream.write(buffer, 0, num); 2772782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2782782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root outZipStream.flush(); 2792782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } finally { 2802782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root IoUtils.closeQuietly(data); 2812782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2822782a478d0214cf71a32d4537fc9fb191d1072fbKenny Root } 2836dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root 2846dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root public static boolean fixSdPermissions(String cid, int gid, String filename) { 2856dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root try { 2866dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root int rc = getMountService().fixPermissionsSecureContainer(cid, gid, filename); 2876dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root if (rc != StorageResultCode.OperationSucceeded) { 2886dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root Log.i(TAG, "Failed to fixperms container " + cid); 2896dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root return false; 2906dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } 2916dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root return true; 2926dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } catch (RemoteException e) { 2936dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root Log.e(TAG, "Failed to fixperms container " + cid + " with exception " + e); 2946dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } 2956dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root return false; 2966dceb88f1c7c42c6ab43834af2c993d599895d82Kenny Root } 2975b993ce7bc29e43a3215a50ce6ce5d6550d4e5e2Suchi Amalapurapu} 298