1
1
package fuzion24 .device .vulnerability .test .ui ;
2
2
3
+ import android .app .DownloadManager ;
4
+ import android .content .BroadcastReceiver ;
5
+ import android .content .Context ;
3
6
import android .content .Intent ;
7
+ import android .content .IntentFilter ;
4
8
import android .content .res .Configuration ;
5
9
import android .graphics .Color ;
6
10
import android .net .Uri ;
7
11
import android .os .Bundle ;
12
+ import android .os .Environment ;
13
+ import android .support .annotation .NonNull ;
8
14
import android .support .design .widget .CoordinatorLayout ;
9
15
import android .support .design .widget .FloatingActionButton ;
10
16
import android .support .design .widget .Snackbar ;
17
23
import android .view .MenuItem ;
18
24
import android .view .View ;
19
25
import android .widget .TextView ;
26
+ import android .widget .Toast ;
20
27
21
28
import com .afollestad .materialdialogs .DialogAction ;
22
29
import com .afollestad .materialdialogs .MaterialDialog ;
30
+ import com .nowsecure .android .vts .BuildConfig ;
23
31
import com .nowsecure .android .vts .R ;
24
32
25
33
import org .json .JSONException ;
26
34
import org .json .JSONObject ;
27
35
36
+ import java .io .File ;
28
37
import java .util .ArrayList ;
29
38
import java .util .List ;
30
39
33
42
import fuzion24 .device .vulnerability .test .VulnerabilityTestResult ;
34
43
import fuzion24 .device .vulnerability .test .VulnerabilityTestRunner ;
35
44
import fuzion24 .device .vulnerability .test .adapter .RecyclerAdapter ;
45
+ import fuzion24 .device .vulnerability .update .client .RetrofitClient ;
46
+ import fuzion24 .device .vulnerability .update .model .GithubRelease ;
47
+ import fuzion24 .device .vulnerability .update .service .GithubApiService ;
36
48
import fuzion24 .device .vulnerability .util .DeviceInfo ;
37
49
import fuzion24 .device .vulnerability .util .SharedPreferencesUtils ;
38
50
import fuzion24 .device .vulnerability .vulnerabilities .VulnerabilityResultSerialzier ;
51
+ import rx .Subscriber ;
52
+ import rx .android .schedulers .AndroidSchedulers ;
53
+ import rx .schedulers .Schedulers ;
39
54
40
55
public class MainActivity extends AppCompatActivity {
41
56
@@ -45,10 +60,27 @@ public class MainActivity extends AppCompatActivity {
45
60
46
61
private DeviceInfo devInfo ;
47
62
private ArrayList <VulnerabilityTestResult > testResults ;
48
- private RecyclerView recyclerView ;
49
63
private TextView emptyView ;
50
64
private CoordinatorLayout coordinatorLayout ;
51
- RecyclerAdapter recyclerAdapter ;
65
+ private RecyclerAdapter recyclerAdapter ;
66
+ private String downloadFilename ;
67
+
68
+ // Download manager.
69
+ private DownloadManager downloadManager ;
70
+ private BroadcastReceiver onComplete = new BroadcastReceiver () {
71
+
72
+ @ Override
73
+ public void onReceive (Context context , Intent intent ) {
74
+ String apkDirectory = String .format ("%s/%s" , Environment .getExternalStoragePublicDirectory (Environment .DIRECTORY_DOWNLOADS ).getAbsolutePath (), downloadFilename );
75
+ Intent downloadIntent = new Intent (Intent .ACTION_VIEW );
76
+
77
+ downloadIntent .setDataAndType (Uri .fromFile (new File (apkDirectory )), "application/vnd.android.package-archive" );
78
+ downloadIntent .setFlags (Intent .FLAG_ACTIVITY_NEW_TASK );
79
+
80
+ startActivity (downloadIntent );
81
+ }
82
+
83
+ };
52
84
53
85
@ Override
54
86
protected void onCreate (Bundle savedInstanceState ) {
@@ -66,9 +98,9 @@ protected void onCreate(Bundle savedInstanceState) {
66
98
testResults = new ArrayList <>();
67
99
}
68
100
101
+ RecyclerView recyclerView = (RecyclerView ) findViewById (R .id .recyclerView );
69
102
coordinatorLayout = (CoordinatorLayout ) findViewById (R .id .coordinatorLayout );
70
103
emptyView = (TextView ) findViewById (R .id .emptyView );
71
- recyclerView = (RecyclerView ) findViewById (R .id .recyclerView );
72
104
recyclerAdapter = new RecyclerAdapter (MainActivity .this , testResults );
73
105
74
106
recyclerView .setLayoutManager (new LinearLayoutManager (MainActivity .this ));
@@ -82,10 +114,10 @@ protected void onCreate(Bundle savedInstanceState) {
82
114
final TextView tvBuildModel = (TextView ) findViewById (R .id .buildModel );
83
115
final TextView tvBuildRelease = (TextView ) findViewById (R .id .buildRelease );
84
116
final TextView tvBuildSDK = (TextView ) findViewById (R .id .buildSDK );
85
-
86
117
final TextView tvBuildABIList = (TextView ) findViewById (R .id .buildABIList );
87
118
88
119
devInfo = DeviceInfo .getDeviceInfo ();
120
+
89
121
tvBuildFingerPrint .setText (devInfo .getBuildFingerPrint ());
90
122
tvBuildID .setText (devInfo .getBuildID ());
91
123
tvKernelVersion .setText (devInfo .getKernelVersion ());
@@ -96,6 +128,7 @@ protected void onCreate(Bundle savedInstanceState) {
96
128
tvBuildSDK .setText (devInfo .getBuildSDK ());
97
129
98
130
StringBuilder sb = new StringBuilder ();
131
+
99
132
for (String s : devInfo .getSupportedABIS ()) {
100
133
sb .append (s );
101
134
sb .append (" " );
@@ -111,6 +144,11 @@ public void onClick(View v) {
111
144
runTestsSuit ();
112
145
}
113
146
});
147
+
148
+ // Set the download callbacks.
149
+ downloadManager = (DownloadManager )getSystemService (DOWNLOAD_SERVICE );
150
+
151
+ registerReceiver (onComplete , new IntentFilter (DownloadManager .ACTION_DOWNLOAD_COMPLETE ));
114
152
}
115
153
116
154
@ Override
@@ -192,11 +230,74 @@ public void onClick(MaterialDialog materialDialog, DialogAction dialogAction) {
192
230
193
231
return true ;
194
232
233
+ case R .id .menu_check_updates :
234
+ checkForUpdates ();
235
+
236
+ return true ;
237
+
195
238
default :
196
239
return super .onOptionsItemSelected (item );
197
240
}
198
241
}
199
242
243
+ private void checkForUpdates () {
244
+ final MaterialDialog mProgressDialog = new MaterialDialog .Builder (this )
245
+ .title (R .string .loading )
246
+ .content (R .string .checking_updates )
247
+ .cancelable (false )
248
+ .progress (true , 0 )
249
+ .show ();
250
+
251
+ GithubApiService service = RetrofitClient .getRetrofitClient ().create (GithubApiService .class );
252
+
253
+ service .getLatestRelease ().subscribeOn (Schedulers .io ())
254
+ .observeOn (AndroidSchedulers .mainThread ())
255
+ .unsubscribeOn (Schedulers .io ())
256
+ .subscribe (new Subscriber <GithubRelease >() {
257
+
258
+ @ Override
259
+ public void onCompleted () {
260
+ mProgressDialog .dismiss ();
261
+ }
262
+
263
+ @ Override
264
+ public void onError (Throwable e ) {
265
+ Toast .makeText (MainActivity .this , R .string .update_error , Toast .LENGTH_LONG ).show ();
266
+ }
267
+
268
+ @ Override
269
+ public void onNext (final GithubRelease githubRelease ) {
270
+ Double currentVersion = Double .parseDouble (BuildConfig .VERSION_NAME .replace ("v." , "" ));
271
+ Double repositoryVersion = Double .parseDouble (githubRelease .getTag_name ().replace ("v." , "" ));
272
+
273
+ // Check if a new version is available.
274
+ if (repositoryVersion > currentVersion ) {
275
+ new MaterialDialog .Builder (MainActivity .this )
276
+ .title (R .string .update_available_title )
277
+ .content (getString (R .string .update_avaiable_description , githubRelease .getTag_name ()))
278
+ .positiveText (R .string .update )
279
+ .negativeText (R .string .dismiss )
280
+ .onPositive (new MaterialDialog .SingleButtonCallback () {
281
+ @ Override
282
+ public void onClick (@ NonNull MaterialDialog materialDialog , @ NonNull DialogAction dialogAction ) {
283
+ downloadFilename = String .format ("AndroidVTS-%s.apk" , githubRelease .getTag_name ());
284
+ downloadManager .enqueue (new DownloadManager .Request (Uri .parse (githubRelease .getAssets ().get (0 ).getBrowser_download_url ()))
285
+ .setTitle ("Android VTS" )
286
+ .setDescription (getString (R .string .downloading_update ))
287
+ .setDestinationInExternalPublicDir (Environment .DIRECTORY_DOWNLOADS , downloadFilename ));
288
+ }
289
+ })
290
+ .show ();
291
+
292
+ return ;
293
+ }
294
+
295
+ Toast .makeText (MainActivity .this , R .string .no_update_available , Toast .LENGTH_LONG ).show ();
296
+ }
297
+
298
+ });
299
+ }
300
+
200
301
private void runTestsSuit () {
201
302
new VulnerabilityTestRunner (MainActivity .this , true , new ResultsCallback () {
202
303
@ Override
@@ -288,4 +389,11 @@ protected void onSaveInstanceState(final Bundle outState) {
288
389
outState .putSerializable (SERIALIZABLE_RESULTS , testResults );
289
390
}
290
391
392
+ @ Override
393
+ public void onDestroy () {
394
+ super .onDestroy ();
395
+
396
+ unregisterReceiver (onComplete );
397
+ }
398
+
291
399
}
0 commit comments