Skip to content

Commit

Permalink
[Feature] New API NavConfiguration.setSaveStateCipher
Browse files Browse the repository at this point in the history
  • Loading branch information
rh-id committed Nov 13, 2021
1 parent ec3997c commit de77fef
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@ public Cipher getSaveStateDecryptCipher() {
return saveStateDecryptCipher;
}

/**
* Set cipher used in save state
*
* @param encrypt initialized cipher use to encrypt
* @param decrypt initialized cipher use to decrypt
* @throws NullPointerException if either encrypt or decrypt cipher is null
*/
public void setSaveStateCipher(Cipher encrypt, Cipher decrypt) {
if (encrypt == null || decrypt == null) {
throw new NullPointerException("Encrypt and Decrypt ciphers MUST NOT NULL");
}
saveStateEncryptCipher = encrypt;
saveStateDecryptCipher = decrypt;
}

public static class Builder<ACT extends Activity, SV extends StatefulView> {
private String initialRouteName;
private Map<String, StatefulViewFactory<ACT, SV>> navMap;
Expand Down
55 changes: 35 additions & 20 deletions navigator/src/main/java/m/co/rh/id/anavigator/Navigator.java
Original file line number Diff line number Diff line change
Expand Up @@ -711,31 +711,41 @@ class SnapshotHandler {

private ExecutorService mExecutorService;
private Future<Serializable> mStateSnapshot;
private File mFile;
private Cipher mEncryptCipher;
private Cipher mDecryptCipher;
private NavConfiguration mNavConfiguration;

SnapshotHandler(NavConfiguration navConfiguration) {
mFile = navConfiguration.getSaveStateFile();
mEncryptCipher = navConfiguration.getSaveStateEncryptCipher();
mDecryptCipher = navConfiguration.getSaveStateDecryptCipher();
if (mFile != null) {
mNavConfiguration = navConfiguration;
if (getFile() != null) {
loadSnapshot(); // start load as early as possible
}
}

private File getFile() {
return mNavConfiguration.getSaveStateFile();
}

private Cipher getEncryptCipher() {
return mNavConfiguration.getSaveStateEncryptCipher();
}

private Cipher getDecryptCipher() {
return mNavConfiguration.getSaveStateDecryptCipher();
}

void saveState(Serializable serializable) {
if (mFile != null) {
final File file = getFile();
final Cipher encryptCipher = getEncryptCipher();
if (file != null) {
mStateSnapshot = getExecutorService().submit(() -> {
if (!mFile.exists()) {
mFile.getParentFile().mkdirs();
mFile.createNewFile();
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(mFile);
FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(new SealedObject(serializable, mEncryptCipher));
oos.writeObject(new SealedObject(serializable, encryptCipher));
oos.close();
bos.close();
fileOutputStream.close();
Expand All @@ -748,7 +758,7 @@ void saveState(Serializable serializable) {
}

Serializable loadState() {
if (mFile != null) {
if (getFile() != null) {
if (mStateSnapshot != null) {
return getState();
}
Expand All @@ -759,17 +769,19 @@ Serializable loadState() {
}

private void loadSnapshot() {
final File file = getFile();
final Cipher decryptCipher = getDecryptCipher();
mStateSnapshot = getExecutorService().submit(() -> {
if (!mFile.exists()) {
if (!file.exists()) {
return null;
}
Serializable result = null;
try {
FileInputStream fis = new FileInputStream(mFile);
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
ObjectInputStream ois = new ObjectInputStream(bis);
result = (Serializable)
((SealedObject) ois.readObject()).getObject(mDecryptCipher);
((SealedObject) ois.readObject()).getObject(decryptCipher);
ois.close();
bis.close();
fis.close();
Expand All @@ -785,9 +797,12 @@ void clearState() {
mStateSnapshot.cancel(false);
mStateSnapshot = null;
}
getExecutorService().submit(() -> {
mFile.delete();
});
final File file = getFile();
if (file != null) {
getExecutorService().submit(() -> {
file.delete();
});
}
}

private ExecutorService getExecutorService() {
Expand Down

0 comments on commit de77fef

Please sign in to comment.