/** * * Funf: Open Sensing Framework * Copyright (C) 2010-2011 Nadav Aharony, Wei Pan, Alex Pentland. * Acknowledgments: Alan Gardner * Contact: nadav@media.mit.edu * * This file is part of Funf. * * Funf is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Funf is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Funf. If not, see <http://www.gnu.org/licenses/>. * */ package edu.mit.media.funf.storage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.FileChannel; import javax.crypto.Cipher; import javax.crypto.CipherOutputStream; import javax.crypto.SecretKey; import android.util.Log; import edu.mit.media.funf.util.IOUtil; import edu.mit.media.funf.util.LogUtil; public interface FileCopier { /** * Copy file from source to destination. FileCopier may modify content when copying or have other side effects. * * @param sourceFile * @param destinationFile * @return */ public boolean copy(File sourceFile, File destinationFile); /** * Basic FileCopier * */ public static class SimpleFileCopier implements FileCopier { @Override public boolean copy(File srcFile, File dstFile) { try { if (srcFile.exists()) { dstFile.getParentFile().mkdirs(); FileChannel src = new FileInputStream(srcFile).getChannel(); FileChannel dst = new FileOutputStream(dstFile).getChannel(); try { dst.transferFrom(src, 0, src.size()); } catch (IOException e) { Log.e(LogUtil.TAG, "Error backing up file. " + e.getLocalizedMessage()); return false; } finally { try { if (src != null) {src.close();} if (dst != null) {dst.close();} } catch (IOException e) { Log.e(LogUtil.TAG, "Error closing db files. " + e.getLocalizedMessage()); return false; } } } else { Log.e(LogUtil.TAG, "File does not exist " + srcFile.getAbsolutePath()); return false; } } catch (FileNotFoundException e) { Log.e(LogUtil.TAG, "Unable to create backup. " + e.getLocalizedMessage()); return false; } return true; } } public static class EncryptedFileCopier implements FileCopier { public static final String TAG = EncryptedFileCopier.class.getName(); private final SecretKey key; private final String transformation; public EncryptedFileCopier(SecretKey key, String transformation) { this.key = key; this.transformation = transformation; } private Cipher cipher; // Cache protected Cipher getCipher() { if (cipher == null) { synchronized (this) { if (cipher == null) { try { cipher = Cipher.getInstance(transformation); cipher.init(Cipher.ENCRYPT_MODE, key); } catch (Exception e) { Log.e(TAG, "Error creating cipher", e); } } } } return cipher; } @Override public boolean copy(File sourceFile, File destinationFile) { Log.i(TAG, "encrypting + copying " + sourceFile.getPath() + " to " + destinationFile.getPath()); Cipher ecipher = getCipher(); if (ecipher == null) { return false; } InputStream in = null; OutputStream out = null; CipherOutputStream co = null; try { in = new FileInputStream(sourceFile); out = new FileOutputStream(destinationFile); co = new CipherOutputStream(out, ecipher); byte[] buf = new byte[128*4096]; int len = 0; while ((len = in.read(buf)) > 0) { co.write(buf, 0, len); } } catch (FileNotFoundException e) { Log.e(TAG, "File not found", e); return false; } catch (IOException e) { Log.e(TAG, "IOException", e); return false; } finally { IOUtil.close(in); IOUtil.close(co); IOUtil.close(out); } Log.i(TAG, "done copy"); return true; } } }