2 * Copyright (C) 2012-2018 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
6 * Copyright (C) secunet Security Networks AG
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 package org
.strongswan
.android
.ui
;
21 import android
.app
.Dialog
;
22 import android
.content
.DialogInterface
;
23 import android
.content
.Intent
;
24 import android
.os
.Build
;
25 import android
.os
.Bundle
;
26 import android
.text
.format
.Formatter
;
27 import android
.view
.Menu
;
28 import android
.view
.MenuItem
;
29 import android
.widget
.Toast
;
31 import org
.strongswan
.android
.R
;
32 import org
.strongswan
.android
.data
.VpnProfile
;
33 import org
.strongswan
.android
.logic
.StrongSwanApplication
;
34 import org
.strongswan
.android
.logic
.TrustedCertificateManager
;
35 import org
.strongswan
.android
.ui
.VpnProfileListFragment
.OnVpnProfileSelectedListener
;
38 import java
.util
.ArrayList
;
39 import java
.util
.List
;
41 import androidx
.appcompat
.app
.ActionBar
;
42 import androidx
.appcompat
.app
.AlertDialog
;
43 import androidx
.appcompat
.app
.AppCompatActivity
;
44 import androidx
.appcompat
.app
.AppCompatDialogFragment
;
45 import androidx
.fragment
.app
.Fragment
;
46 import androidx
.fragment
.app
.FragmentManager
;
47 import androidx
.fragment
.app
.FragmentTransaction
;
49 public class MainActivity
extends AppCompatActivity
implements OnVpnProfileSelectedListener
51 public static final String CONTACT_EMAIL
= "android@strongswan.org";
52 public static final String EXTRA_CRL_LIST
= "org.strongswan.android.CRL_LIST";
55 * Use "bring your own device" (BYOD) features
57 public static final boolean USE_BYOD
= true;
59 private static final String DIALOG_TAG
= "Dialog";
62 public void onCreate(Bundle savedInstanceState
)
64 super.onCreate(savedInstanceState
);
65 setContentView(R
.layout
.main
);
67 ActionBar bar
= getSupportActionBar();
68 bar
.setDisplayShowHomeEnabled(true);
69 bar
.setDisplayShowTitleEnabled(false);
70 bar
.setIcon(R
.mipmap
.ic_app
);
72 /* load CA certificates in a background thread */
73 ((StrongSwanApplication
)getApplication()).getExecutor().execute(() -> {
74 TrustedCertificateManager
.getInstance().load();
79 public boolean onCreateOptionsMenu(Menu menu
)
81 getMenuInflater().inflate(R
.menu
.main
, menu
);
86 public boolean onPrepareOptionsMenu(Menu menu
)
88 if (Build
.VERSION
.SDK_INT
< Build
.VERSION_CODES
.KITKAT
)
90 menu
.removeItem(R
.id
.menu_import_profile
);
96 public boolean onOptionsItemSelected(MenuItem item
)
98 switch (item
.getItemId())
100 case R
.id
.menu_import_profile
:
101 Intent intent
= new Intent(this, VpnProfileImportActivity
.class);
102 startActivity(intent
);
104 case R
.id
.menu_manage_certs
:
105 Intent certIntent
= new Intent(this, TrustedCertificatesActivity
.class);
106 startActivity(certIntent
);
108 case R
.id
.menu_crl_cache
:
111 case R
.id
.menu_show_log
:
112 Intent logIntent
= new Intent(this, LogActivity
.class);
113 startActivity(logIntent
);
115 case R
.id
.menu_settings
:
116 Intent settingsIntent
= new Intent(this, SettingsActivity
.class);
117 startActivity(settingsIntent
);
120 return super.onOptionsItemSelected(item
);
125 public void onVpnProfileSelected(VpnProfile profile
)
127 Intent intent
= new Intent(this, VpnProfileControlActivity
.class);
128 intent
.setAction(VpnProfileControlActivity
.START_PROFILE
);
129 intent
.putExtra(VpnProfileControlActivity
.EXTRA_VPN_PROFILE_ID
, profile
.getUUID().toString());
130 startActivity(intent
);
134 * Ask the user whether to clear the CRL cache.
136 private void clearCRLs()
138 final String FILE_PREFIX
= "crl-";
139 ArrayList
<String
> list
= new ArrayList
<>();
141 for (String file
: fileList())
143 if (file
.startsWith(FILE_PREFIX
))
148 if (list
.size() == 0)
150 Toast
.makeText(this, R
.string
.clear_crl_cache_msg_none
, Toast
.LENGTH_SHORT
).show();
153 removeFragmentByTag(DIALOG_TAG
);
155 Bundle args
= new Bundle();
156 args
.putStringArrayList(EXTRA_CRL_LIST
, list
);
158 CRLCacheDialog dialog
= new CRLCacheDialog();
159 dialog
.setArguments(args
);
160 dialog
.show(this.getSupportFragmentManager(), DIALOG_TAG
);
164 * Dismiss dialog if shown
166 public void removeFragmentByTag(String tag
)
168 FragmentManager fm
= getSupportFragmentManager();
169 Fragment login
= fm
.findFragmentByTag(tag
);
172 FragmentTransaction ft
= fm
.beginTransaction();
179 * Confirmation dialog to clear CRL cache
181 public static class CRLCacheDialog
extends AppCompatDialogFragment
184 public Dialog
onCreateDialog(Bundle savedInstanceState
)
186 final List
<String
> list
= getArguments().getStringArrayList(EXTRA_CRL_LIST
);
190 for (String file
: list
)
192 File crl
= getActivity().getFileStreamPath(file
);
195 size
= Formatter
.formatFileSize(getActivity(), s
);
197 AlertDialog
.Builder builder
= new AlertDialog
.Builder(getActivity())
198 .setTitle(R
.string
.clear_crl_cache_title
)
199 .setNegativeButton(android
.R
.string
.cancel
, new DialogInterface
.OnClickListener()
202 public void onClick(DialogInterface dialog
, int which
)
207 .setPositiveButton(R
.string
.clear
, new DialogInterface
.OnClickListener()
210 public void onClick(DialogInterface dialog
, int whichButton
)
212 for (String file
: list
)
214 getActivity().deleteFile(file
);
218 builder
.setMessage(getActivity().getResources().getQuantityString(R
.plurals
.clear_crl_cache_msg
, list
.size(), list
.size(), size
));
219 return builder
.create();