4 * Authors: Nathaniel McCallum <npmccallum@redhat.com>
6 * Copyright (C) 2013 Nathaniel McCallum, Red Hat
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 package org.fedorahosted.freeotp;
23 import java.util.HashMap;
26 import org.fedorahosted.freeotp.Token.TokenUriInvalidException;
28 import android.app.AlertDialog;
29 import android.content.Context;
30 import android.content.DialogInterface;
31 import android.os.Handler;
32 import android.os.Message;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.View.OnClickListener;
36 import android.view.ViewGroup;
37 import android.widget.BaseAdapter;
38 import android.widget.ImageButton;
39 import android.widget.ProgressBar;
40 import android.widget.TextView;
42 public class TokenAdapter extends BaseAdapter {
43 private static class Ticker extends Handler {
44 private static interface OnTickListener {
45 public void tick(ProgressBar pb);
48 private final Map<ProgressBar, OnTickListener> map = new HashMap<ProgressBar, OnTickListener>();
51 public void handleMessage(Message msg) {
52 for (ProgressBar pb : map.keySet())
55 sendEmptyMessageDelayed(0, 200);
58 public void set(ProgressBar pb, OnTickListener otl) {
63 private static class ViewHolder {
70 private final TokenStore ts;
71 private final Ticker ticker = new Ticker();
73 public TokenAdapter(Context ctx) {
74 ts = new TokenStore(ctx);
75 ticker.sendEmptyMessageDelayed(0, 200);
79 public int getCount() {
80 return ts.getTokenCount();
84 public Token getItem(int position) {
85 return ts.get(position);
89 public long getItemId(int position) {
94 public View getView(int position, View convertView, ViewGroup parent) {
95 Token token = ts.get(position);
97 if (convertView == null)
98 convertView = newView(parent.getContext(), token.getType(), parent);
100 bindView(parent.getContext(), convertView, token, position);
104 public void bindView(Context ctx, View view, Token token, int position) {
105 ViewHolder holder = (ViewHolder) view.getTag();
106 holder.index = position;
107 holder.token = token;
109 holder.code.setText(token.getPlaceholder());
110 holder.title.setText(token.getIssuer() + ": " + token.getLabel());
113 public View newView(Context ctx, Token.TokenType type, ViewGroup parent) {
114 LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
115 ViewHolder holder = new ViewHolder();
120 view = inflater.inflate(R.layout.hotp, parent, false);
121 ImageButton hotp = (ImageButton) view.findViewById(R.id.hotpButton);
123 hotp.setOnClickListener(new OnClickListener() {
125 public void onClick(View v) {
126 ViewHolder holder = (ViewHolder) v.getTag();
127 holder.code.setText(holder.token.getCode());
128 holder.token.increment();
129 ts.save(holder.token);
135 view = inflater.inflate(R.layout.totp, parent, false);
136 ProgressBar pb = (ProgressBar) view.findViewById(R.id.totpProgressBar);
138 ticker.set(pb, new Ticker.OnTickListener() {
140 public void tick(ProgressBar pb) {
141 ViewHolder holder = (ViewHolder) pb.getTag();
142 pb.setProgress(pb.getMax() - holder.token.getProgress());
143 holder.code.setText(holder.token.getCode());
149 ImageButton ib = (ImageButton) view.findViewById(R.id.button);
151 ib.setOnClickListener(new OnClickListener() {
153 public void onClick(View v) {
154 final ViewHolder holder = (ViewHolder) v.getTag();
156 StringBuilder sb = new StringBuilder();
157 sb.append(v.getContext().getString(R.string.delete_message));
158 sb.append(holder.token.getIssuer());
160 sb.append(holder.token.getLabel());
162 AlertDialog ad = new AlertDialog.Builder(v.getContext())
164 .setMessage(sb.toString())
165 .setIcon(android.R.drawable.ic_delete)
166 .setPositiveButton(R.string.delete,
167 new DialogInterface.OnClickListener() {
169 public void onClick(DialogInterface dialog, int which) {
170 ts.del(holder.index);
171 notifyDataSetChanged();
176 .setNegativeButton(android.R.string.cancel,
177 new DialogInterface.OnClickListener() {
179 public void onClick(DialogInterface dialog, int which) {
188 holder.code = (TextView) view.findViewById(R.id.code);
189 holder.title = (TextView) view.findViewById(R.id.title);
196 public int getViewTypeCount() {
201 public int getItemViewType(int position) {
202 switch (getItem(position).getType()) {
208 return IGNORE_ITEM_VIEW_TYPE;
212 public void add(Context ctx, String uri) throws TokenUriInvalidException {
213 ts.add(new Token(uri));
214 notifyDataSetChanged();