-
Notifications
You must be signed in to change notification settings - Fork 0
/
RetrieveContentWithDownloadProgress.java
151 lines (137 loc) · 6.09 KB
/
RetrieveContentWithDownloadProgress.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package javinator9889.securepass.backup.drive;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.text.InputType;
import android.util.Log;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveResourceClient;
import com.google.android.gms.drive.events.OpenFileCallback;
import com.google.android.gms.tasks.Task;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamCorruptedException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javinator9889.securepass.R;
import javinator9889.securepass.data.container.ClassContainer;
import javinator9889.securepass.io.IOManager;
import javinator9889.securepass.util.cipher.FileCipher;
import javinator9889.securepass.util.values.Constants.DRIVE;
/**
* Created by Javinator9889 on 07/04/2018.
*/
public class RetrieveContentWithDownloadProgress implements IDriveDownloadOperations {
private static final String TAG = "RetrieveWithProgress";
private Context driveContext;
private Activity mainActivity;
private DriveResourceClient resourceClient;
private MaterialDialog mProgressBar;
private ExecutorService mExecutorService;
private byte[] iv;
public RetrieveContentWithDownloadProgress(@NonNull Context driveContext,
@NonNull Activity mainActivity,
@NonNull DriveResourceClient resourceClient) {
this.driveContext = driveContext;
this.mainActivity = mainActivity;
this.resourceClient = resourceClient;
mProgressBar = new MaterialDialog.Builder(driveContext)
.title(R.string.retrieving_data)
.content(R.string.wait)
.cancelable(false)
.progress(false, 100)
.build();
mExecutorService = Executors.newSingleThreadExecutor();
}
@Override
public void retrieveIvVector(DriveFile file) {
Task<DriveContents> openFileTask = resourceClient
.openFile(file, DriveFile.MODE_READ_ONLY);
openFileTask
.continueWithTask(task -> {
DriveContents contents = task.getResult();
try (InputStream stream = contents.getInputStream()) {
this.iv = ByteStreams.toByteArray(stream);
return resourceClient.discardContents(contents);
}
})
.addOnFailureListener(e -> {
Log.e(TAG, DRIVE.GOOGLE_FILE_NO_SELECTED, e);
mainActivity.finish();
});
}
@Override
public void retrieveContents(DriveFile file) {
mProgressBar.show();
resourceClient.openFile(file, DriveFile.MODE_READ_ONLY, new OpenFileCallback() {
@Override
public void onProgress(long bytesDownloaded, long bytesExpected) {
int progress = (int) (bytesDownloaded * 100 / bytesExpected);
Log.d(TAG, String.format("Download progress: %d percent", progress));
mProgressBar.setProgress(progress);
}
@Override
public void onContents(@NonNull DriveContents driveContents) {
mProgressBar.setProgress(100);
mProgressBar.dismiss();
try {
try (InputStream obtainedFile = driveContents.getInputStream()) {
IOManager io = IOManager.newInstance(driveContext);
io.writeDownloadedClass(obtainedFile);
completeDownload();
}
} catch (IOException e) {
Log.e(TAG, "IOException when retrieving contents", e);
}
}
@Override
public void onError(@NonNull Exception e) {
Log.e(TAG, "Unable to read contents", e);
mainActivity.finish();
}
});
}
private void completeDownload() {
IOManager io = IOManager.newInstance(driveContext);
InputStream obtainedStream = io.readDownloadedClass();
final StringBuilder passwordBuilder = new StringBuilder();
new MaterialDialog.Builder(driveContext)
.title(R.string.put_pass)
.content(R.string.pass_need)
.inputType(InputType.TYPE_TEXT_VARIATION_PASSWORD)
.input(null, null, false,
((dialog, input) -> passwordBuilder.append(input)))
.onAny(((dialog, which) -> {
String password = Hashing.sha256()
.hashString(passwordBuilder.toString(), StandardCharsets.UTF_8)
.toString();
try {
FileCipher fileDecrypt = FileCipher.newInstance(password,
iv);
ClassContainer restoredData =
(ClassContainer) fileDecrypt.decrypt(obtainedStream);
restoredData.storeDataInDB(); // must implement
obtainedStream.close();
io.deleteDownloadedClass();
} catch (StreamCorruptedException e) {
Log.e(TAG, "Password not correct captured");
Toast.makeText(driveContext, "Password is not correct",
Toast.LENGTH_LONG).show();
completeDownload();
} catch (Exception e) {
Log.e(TAG, "Exception during process of decrypting", e);
}
}))
.cancelable(false)
.build().show();
}
public void finish() {
this.mExecutorService.shutdown();
}
}