4 * Authors: Nathaniel McCallum <npmccallum@redhat.com>
6 * Copyright (C) 2013 Nathaniel McCallum, Red Hat
7 * see file 'COPYING' for use and warranty information
9 * This program is free software you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 package org.fedorahosted.freeotp;
25 import java.security.NoSuchAlgorithmException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.Comparator;
29 import java.util.HashMap;
30 import java.util.List;
33 import org.fedorahosted.freeotp.Token.TokenUriInvalidException;
35 import android.app.AlertDialog;
36 import android.content.Context;
37 import android.content.DialogInterface;
38 import android.os.Handler;
39 import android.os.Message;
40 import android.view.View;
41 import android.view.View.OnClickListener;
42 import android.view.ViewGroup;
43 import android.widget.BaseAdapter;
44 import android.widget.ImageButton;
45 import android.widget.ProgressBar;
46 import android.widget.TextView;
48 public class TokenAdapter extends BaseAdapter {
49 private static class Ticker extends Handler {
50 private static interface OnTickListener {
51 public void tick(ProgressBar pb);
54 private final Map<ProgressBar, OnTickListener> map = new HashMap<ProgressBar, OnTickListener>();
57 public void handleMessage(Message msg) {
58 for (ProgressBar pb : map.keySet())
61 sendEmptyMessageDelayed(0, 200);
64 public void set(ProgressBar pb, OnTickListener otl) {
69 private final List<Token> tokens = new ArrayList<Token>();
70 private final Ticker ticker = new Ticker();
73 Collections.sort(tokens, new Comparator<Token>() {
75 public int compare(Token lhs, Token rhs) {
76 return lhs.getTitle().compareTo(rhs.getTitle());
81 public TokenAdapter(Context ctx) {
82 tokens.addAll(Token.getTokens(ctx));
83 ticker.sendEmptyMessageDelayed(0, 200);
88 public int getCount() {
93 public Token getItem(int position) {
94 return tokens.get(position);
98 public long getItemId(int position) {
103 public View getView(int position, View convertView, ViewGroup parent) {
104 final Context ctx = parent.getContext();
106 if (convertView == null) {
107 switch (getItem(position).getType()) {
109 convertView = View.inflate(ctx, R.layout.hotp, null);
113 convertView = View.inflate(ctx, R.layout.totp, null);
118 final Token item = getItem(position);
119 final TextView code = (TextView) convertView.findViewById(R.id.code);
120 final TextView title = (TextView) convertView.findViewById(R.id.title);
121 final ImageButton ib = (ImageButton) convertView.findViewById(R.id.button);
123 code.setText(item.getCurrentTokenValue(ctx, false));
124 title.setText(item.getTitle());
126 ib.setOnClickListener(new OnClickListener() {
128 public void onClick(View v) {
129 String delmsg = ctx.getString(R.string.delete_message);
131 AlertDialog ad = new AlertDialog.Builder(ctx)
133 .setMessage(delmsg + item.getTitle())
134 .setIcon(android.R.drawable.ic_delete)
135 .setPositiveButton(R.string.delete,
136 new DialogInterface.OnClickListener() {
138 public void onClick(DialogInterface dialog, int which) {
139 tokens.remove(tokens.indexOf(item));
141 notifyDataSetChanged();
146 .setNegativeButton(android.R.string.cancel,
147 new DialogInterface.OnClickListener() {
149 public void onClick(DialogInterface dialog, int which) {
157 switch (getItem(position).getType()) {
159 ImageButton hotp = (ImageButton) convertView.findViewById(R.id.hotpButton);
160 hotp.setOnClickListener(new OnClickListener() {
162 public void onClick(View v) {
163 code.setText(item.getCurrentTokenValue(ctx, true));
169 ProgressBar pb = (ProgressBar) convertView.findViewById(R.id.totpProgressBar);
170 ticker.set(pb, new Ticker.OnTickListener() {
172 public void tick(ProgressBar pb) {
173 int max = pb.getMax();
174 int pro = item.getProgress();
175 pb.setProgress(max - pro);
176 if (pro < max / 20 || pro > max / 20 * 19)
177 code.setText(item.getCurrentTokenValue(ctx, false));
187 public int getViewTypeCount() {
192 public int getItemViewType(int position) {
193 switch (getItem(position).getType()) {
203 public void add(Context ctx, String uri) throws NoSuchAlgorithmException, TokenUriInvalidException {
204 Token t = new Token(uri);
208 notifyDataSetChanged();