diff --git a/library/src/main/java/com/danikula/videocache/Config.java b/library/src/main/java/com/danikula/videocache/Config.java index 29ab95c..9e5ee35 100644 --- a/library/src/main/java/com/danikula/videocache/Config.java +++ b/library/src/main/java/com/danikula/videocache/Config.java @@ -1,5 +1,6 @@ package com.danikula.videocache; +import com.danikula.videocache.encrypt.Cipher; import com.danikula.videocache.file.DiskUsage; import com.danikula.videocache.file.FileNameGenerator; import com.danikula.videocache.headers.HeaderInjector; @@ -19,13 +20,16 @@ class Config { public final DiskUsage diskUsage; public final SourceInfoStorage sourceInfoStorage; public final HeaderInjector headerInjector; + public final Cipher cipher; - Config(File cacheRoot, FileNameGenerator fileNameGenerator, DiskUsage diskUsage, SourceInfoStorage sourceInfoStorage, HeaderInjector headerInjector) { + Config(File cacheRoot, FileNameGenerator fileNameGenerator, DiskUsage diskUsage, SourceInfoStorage sourceInfoStorage, + HeaderInjector headerInjector, Cipher cipher) { this.cacheRoot = cacheRoot; this.fileNameGenerator = fileNameGenerator; this.diskUsage = diskUsage; this.sourceInfoStorage = sourceInfoStorage; this.headerInjector = headerInjector; + this.cipher = cipher; } File generateCacheFile(String url) { diff --git a/library/src/main/java/com/danikula/videocache/HttpProxyCacheServer.java b/library/src/main/java/com/danikula/videocache/HttpProxyCacheServer.java index 1f34ae8..186238e 100644 --- a/library/src/main/java/com/danikula/videocache/HttpProxyCacheServer.java +++ b/library/src/main/java/com/danikula/videocache/HttpProxyCacheServer.java @@ -3,6 +3,8 @@ import android.content.Context; import android.net.Uri; +import com.danikula.videocache.encrypt.Cipher; +import com.danikula.videocache.encrypt.NoCipher; import com.danikula.videocache.file.DiskUsage; import com.danikula.videocache.file.FileNameGenerator; import com.danikula.videocache.file.Md5FileNameGenerator; @@ -353,6 +355,7 @@ public static final class Builder { private DiskUsage diskUsage; private SourceInfoStorage sourceInfoStorage; private HeaderInjector headerInjector; + private Cipher cipher; public Builder(Context context) { this.sourceInfoStorage = SourceInfoStorageFactory.newSourceInfoStorage(context); @@ -360,6 +363,7 @@ public Builder(Context context) { this.diskUsage = new TotalSizeLruDiskUsage(DEFAULT_MAX_SIZE); this.fileNameGenerator = new Md5FileNameGenerator(); this.headerInjector = new EmptyHeadersInjector(); + this.cipher = new NoCipher(); } /** @@ -390,6 +394,17 @@ public Builder fileNameGenerator(FileNameGenerator fileNameGenerator) { return this; } + /** + * Overrides default cipher for cached files. + * + * @param cipher a new cipher, can't be {@code null}. + * @return a builder. + */ + public Builder cipher(Cipher cipher) { + this.cipher = checkNotNull(cipher); + return this; + } + /** * Sets max cache size in bytes. *
@@ -452,8 +467,7 @@ public HttpProxyCacheServer build() { } private Config buildConfig() { - return new Config(cacheRoot, fileNameGenerator, diskUsage, sourceInfoStorage, headerInjector); + return new Config(cacheRoot, fileNameGenerator, diskUsage, sourceInfoStorage, headerInjector, cipher); } - } } diff --git a/library/src/main/java/com/danikula/videocache/encrypt/Cipher.java b/library/src/main/java/com/danikula/videocache/encrypt/Cipher.java new file mode 100644 index 0000000..6ab88bd --- /dev/null +++ b/library/src/main/java/com/danikula/videocache/encrypt/Cipher.java @@ -0,0 +1,26 @@ +package com.danikula.videocache.encrypt; + +/** + * Defines a encryption/decryption for cached data. + * + * @author Alexey Danilov (danikula@gmail.com). + */ +public interface Cipher { + + /** + * Encrypts piece of data. Resulting byte[] array must have same size. + * + * @param data an input data to be encrypted. + * @param length an length of data to be encrypted. + */ + void encrypt(byte[] data, long length); + + /** + * Decrypts piece of data. Resulting byte[] array must have same size. + * + * @param data an input data to be decrypted. + * @param offset an offset of data to be decrypted. + * @param length a length of data to be decrypted. + */ + void decrypt(byte[] data, long offset, int length); +} diff --git a/library/src/main/java/com/danikula/videocache/encrypt/CipherAwareCacheWrapper.java b/library/src/main/java/com/danikula/videocache/encrypt/CipherAwareCacheWrapper.java new file mode 100644 index 0000000..cf614ee --- /dev/null +++ b/library/src/main/java/com/danikula/videocache/encrypt/CipherAwareCacheWrapper.java @@ -0,0 +1,55 @@ +package com.danikula.videocache.encrypt; + +import com.danikula.videocache.Cache; +import com.danikula.videocache.ProxyCacheException; + +import static com.danikula.videocache.Preconditions.checkNotNull; + +/** + * {@link Cache} that take into account encryption/decryption. + * + * @author Alexey Danilov (danikula@gmail.com). + */ +public class CipherAwareCacheWrapper implements Cache { + + private final Cache cache; + private final Cipher cipher; + + public CipherAwareCacheWrapper(Cache cache, Cipher cipher) { + this.cache = checkNotNull(cache); + this.cipher = checkNotNull(cipher); + } + + @Override + public int read(byte[] buffer, long offset, int length) throws ProxyCacheException { + cache.read(buffer, offset, length); + cipher.decrypt(buffer, offset, length); + return 0; + } + + @Override + public void append(byte[] data, int length) throws ProxyCacheException { + cipher.encrypt(data, length); + cache.append(data, length); + } + + @Override + public long available() throws ProxyCacheException { + return cache.available(); + } + + @Override + public void close() throws ProxyCacheException { + cache.close(); + } + + @Override + public void complete() throws ProxyCacheException { + cache.complete(); + } + + @Override + public boolean isCompleted() { + return cache.isCompleted(); + } +} diff --git a/library/src/main/java/com/danikula/videocache/encrypt/NoCipher.java b/library/src/main/java/com/danikula/videocache/encrypt/NoCipher.java new file mode 100644 index 0000000..f74b3ce --- /dev/null +++ b/library/src/main/java/com/danikula/videocache/encrypt/NoCipher.java @@ -0,0 +1,17 @@ +package com.danikula.videocache.encrypt; + +/** + * {@link Cipher} that does not perform any encryption/decryption. + * + * @author Alexey Danilov (danikula@gmail.com). + */ +public class NoCipher implements Cipher { + + @Override + public void encrypt(byte[] data, long length) { + } + + @Override + public void decrypt(byte[] data, long offset, int length) { + } +}