]> git.ipfire.org Git - thirdparty/strongswan.git/blob
b89386a86d1244d4470e6e8e856ed6f69a32ed99
[thirdparty/strongswan.git] /
1 /*
2 * Copyright (C) 2012-2015 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 package org.strongswan.android.ui;
17
18 import android.content.Context;
19 import android.os.Bundle;
20 import android.text.TextUtils;
21 import android.view.Menu;
22 import android.view.MenuInflater;
23 import android.view.MenuItem;
24 import android.view.View;
25 import android.widget.ListView;
26 import android.widget.SearchView;
27 import android.widget.SearchView.OnQueryTextListener;
28
29 import org.strongswan.android.R;
30 import org.strongswan.android.logic.TrustedCertificateManager;
31 import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource;
32 import org.strongswan.android.security.TrustedCertificateEntry;
33 import org.strongswan.android.ui.adapter.TrustedCertificateAdapter;
34
35 import java.security.cert.X509Certificate;
36 import java.util.ArrayList;
37 import java.util.Collections;
38 import java.util.Hashtable;
39 import java.util.List;
40 import java.util.Map.Entry;
41 import java.util.Observable;
42 import java.util.Observer;
43
44 import androidx.fragment.app.ListFragment;
45 import androidx.loader.app.LoaderManager;
46 import androidx.loader.app.LoaderManager.LoaderCallbacks;
47 import androidx.loader.content.AsyncTaskLoader;
48 import androidx.loader.content.Loader;
49
50 public class TrustedCertificateListFragment extends ListFragment implements LoaderCallbacks<List<TrustedCertificateEntry>>, OnQueryTextListener
51 {
52 public static final String EXTRA_CERTIFICATE_SOURCE = "certificate_source";
53 private OnTrustedCertificateSelectedListener mListener;
54 private TrustedCertificateAdapter mAdapter;
55 private TrustedCertificateSource mSource = TrustedCertificateSource.SYSTEM;
56
57 /**
58 * The activity containing this fragment should implement this interface
59 */
60 public interface OnTrustedCertificateSelectedListener
61 {
62 public void onTrustedCertificateSelected(TrustedCertificateEntry selected);
63 }
64
65 @Override
66 public void onActivityCreated(Bundle savedInstanceState)
67 {
68 super.onActivityCreated(savedInstanceState);
69 setHasOptionsMenu(true);
70
71 setEmptyText(getString(R.string.no_certificates));
72
73 mAdapter = new TrustedCertificateAdapter(getActivity());
74 setListAdapter(mAdapter);
75
76 setListShown(false);
77
78 Bundle arguments = getArguments();
79 if (arguments != null)
80 {
81 mSource = (TrustedCertificateSource)arguments.getSerializable(EXTRA_CERTIFICATE_SOURCE);
82 }
83
84 LoaderManager.getInstance(this).initLoader(0, null, this);
85 }
86
87 @Override
88 public void onDestroy()
89 {
90 super.onDestroy();
91 }
92
93 @Override
94 public void onAttach(Context context)
95 {
96 super.onAttach(context);
97
98 if (context instanceof OnTrustedCertificateSelectedListener)
99 {
100 mListener = (OnTrustedCertificateSelectedListener)context;
101 }
102 }
103
104 @Override
105 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
106 {
107 MenuItem item = menu.add(R.string.search);
108 item.setIcon(android.R.drawable.ic_menu_search);
109 item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
110
111 SearchView sv = new SearchView(getActivity());
112 sv.setOnQueryTextListener(this);
113 item.setActionView(sv);
114 }
115
116 @Override
117 public boolean onQueryTextSubmit(String query)
118 { /* already handled when the text changes */
119 return true;
120 }
121
122 @Override
123 public boolean onQueryTextChange(String newText)
124 {
125 String search = TextUtils.isEmpty(newText) ? null : newText;
126 mAdapter.getFilter().filter(search);
127 return true;
128 }
129
130 @Override
131 public Loader<List<TrustedCertificateEntry>> onCreateLoader(int id, Bundle args)
132 { /* we don't need the id as we have only one loader */
133 return new CertificateListLoader(getActivity(), mSource);
134 }
135
136 @Override
137 public void onLoadFinished(Loader<List<TrustedCertificateEntry>> loader, List<TrustedCertificateEntry> data)
138 {
139 mAdapter.setData(data);
140
141 if (isResumed())
142 {
143 setListShown(true);
144 }
145 else
146 {
147 setListShownNoAnimation(true);
148 }
149 }
150
151 @Override
152 public void onLoaderReset(Loader<List<TrustedCertificateEntry>> loader)
153 {
154 mAdapter.setData(null);
155 }
156
157 @Override
158 public void onListItemClick(ListView l, View v, int position, long id)
159 {
160 if (mListener != null)
161 {
162 mListener.onTrustedCertificateSelected(mAdapter.getItem(position));
163 }
164 }
165
166 public static class CertificateListLoader extends AsyncTaskLoader<List<TrustedCertificateEntry>>
167 {
168 private List<TrustedCertificateEntry> mData;
169 private final TrustedCertificateSource mSource;
170 private TrustedCertificateManagerObserver mObserver;
171
172 public CertificateListLoader(Context context, TrustedCertificateSource source)
173 {
174 super(context);
175 mSource = source;
176 }
177
178 @Override
179 public List<TrustedCertificateEntry> loadInBackground()
180 {
181 TrustedCertificateManager certman = TrustedCertificateManager.getInstance().load();
182 Hashtable<String, X509Certificate> certificates = certman.getCACertificates(mSource);
183 List<TrustedCertificateEntry> selected;
184
185 selected = new ArrayList<TrustedCertificateEntry>();
186 for (Entry<String, X509Certificate> entry : certificates.entrySet())
187 {
188 selected.add(new TrustedCertificateEntry(entry.getKey(), entry.getValue()));
189 }
190 Collections.sort(selected);
191 return selected;
192 }
193
194 @Override
195 protected void onStartLoading()
196 {
197 if (mData != null)
198 { /* if we have data ready, deliver it directly */
199 deliverResult(mData);
200 }
201 if (takeContentChanged() || mData == null)
202 {
203 forceLoad();
204 }
205 }
206
207 @Override
208 public void deliverResult(List<TrustedCertificateEntry> data)
209 {
210 if (isReset())
211 {
212 return;
213 }
214 mData = data;
215 if (isStarted())
216 { /* if it is started we deliver the data directly,
217 * otherwise this is handled in onStartLoading */
218 if (mObserver == null)
219 {
220 mObserver = new TrustedCertificateManagerObserver();
221 TrustedCertificateManager.getInstance().addObserver(mObserver);
222 }
223 super.deliverResult(data);
224 }
225 }
226
227 @Override
228 protected void onReset()
229 {
230 if (mObserver != null)
231 {
232 TrustedCertificateManager.getInstance().deleteObserver(mObserver);
233 mObserver = null;
234 }
235 mData = null;
236 super.onReset();
237 }
238
239 @Override
240 protected void onAbandon()
241 {
242 if (mObserver != null)
243 {
244 TrustedCertificateManager.getInstance().deleteObserver(mObserver);
245 mObserver = null;
246 }
247 }
248
249 private class TrustedCertificateManagerObserver implements Observer
250 {
251 private ForceLoadContentObserver mContentObserver = new ForceLoadContentObserver();
252
253 @Override
254 public void update(Observable observable, Object data)
255 {
256 mContentObserver.onChange(false);
257 }
258 }
259 }
260 }