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.Locale;
25 import android.app.AlertDialog;
26 import android.content.DialogInterface;
27 import android.net.Uri;
28 import android.text.TextWatcher;
29 import android.view.View;
30 import android.widget.AdapterView;
31 import android.widget.AdapterView.OnItemSelectedListener;
32 import android.widget.EditText;
33 import android.widget.RadioButton;
34 import android.widget.Spinner;
35 import android.widget.TextView;
37 public class ManualDialogFragment extends BaseAlertDialogFragment implements OnItemSelectedListener {
38 public static final String FRAGMENT_TAG = "fragment_camera";
39 private static final String DEFAULT_INTERVAL = "30";
40 private static final String DEFAULT_COUNTER = "0";
42 private final int SHA1_OFFSET = 1;
43 private final int TOTP_OFFSET = 0;
44 private EditText mIssuer;
45 private EditText mLabel;
46 private EditText mSecret;
47 private EditText mInterval;
48 private Spinner mAlgorithm;
49 private Spinner mType;
51 public ManualDialogFragment() {
52 super(R.string.add_token, R.layout.manual, android.R.string.cancel, 0, R.string.add);
56 protected void onViewInflated(View view) {
57 mIssuer = (EditText) view.findViewById(R.id.issuer);
58 mLabel = (EditText) view.findViewById(R.id.label);
59 mSecret = (EditText) view.findViewById(R.id.secret);
60 mInterval = (EditText) view.findViewById(R.id.interval);
61 mAlgorithm = (Spinner) view.findViewById(R.id.algorithm);
62 mType = (Spinner) view.findViewById(R.id.type);
64 // Select the default algorithm
65 mAlgorithm.setSelection(SHA1_OFFSET);
67 // Setup the Interval / Counter toggle
68 mType.setOnItemSelectedListener(this);
72 public void onStart() {
75 AlertDialog ad = (AlertDialog) getDialog();
77 // Disable the Add button
78 ad.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
80 // Set constraints on when the Add button is enabled
81 TextWatcher tw = new ManualTextWatcher(ad);
82 mIssuer.addTextChangedListener(tw);
83 mLabel.addTextChangedListener(tw);
84 mSecret.addTextChangedListener(new ManualSecretTextWatcher(ad));
85 mInterval.addTextChangedListener(tw);
89 public void onClick(DialogInterface dialog, int which) {
90 if (which != AlertDialog.BUTTON_POSITIVE)
94 String issuer = Uri.encode(mIssuer.getText().toString());
95 String label = Uri.encode(mLabel.getText().toString());
96 String secret = Uri.encode(mSecret.getText().toString());
97 String type = mType.getSelectedItemId() == TOTP_OFFSET ? "totp" : "hotp";
98 String algorithm = mAlgorithm.getSelectedItem().toString().toLowerCase(Locale.US);
99 int interval = Integer.parseInt(mInterval.getText().toString());
100 int digits = ((RadioButton) getDialog().findViewById(R.id.digits6)).isChecked() ? 6 : 8;
103 String uri = String.format(Locale.US, "otpauth://%s/%s:%s?secret=%s&algorithm=%s&digits=%d",
104 type, issuer, label, secret, algorithm, digits);
105 if (type.equals("totp"))
106 uri = uri.concat(String.format("&period=%d", interval));
108 uri = uri.concat(String.format("&counter=%d", interval));
112 ((MainActivity) getActivity()).tokenURIReceived(uri);
116 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
117 TextView tv = (TextView) getDialog().findViewById(R.id.interval_label);
119 tv.setText(R.string.interval);
120 mInterval.setText(DEFAULT_INTERVAL);
122 tv.setText(R.string.counter);
123 mInterval.setText(DEFAULT_COUNTER);
128 public void onNothingSelected(AdapterView<?> parent) {