]> Pileus Git - ~andy/freeotp/commitdiff
Migrate Manual token entry to use a DialogFragment
authorNathaniel McCallum <npmccallum@redhat.com>
Wed, 4 Dec 2013 21:36:43 +0000 (16:36 -0500)
committerNathaniel McCallum <npmccallum@redhat.com>
Wed, 4 Dec 2013 21:36:43 +0000 (16:36 -0500)
AndroidManifest.xml
res/layout/manual.xml
src/org/fedorahosted/freeotp/AddTokenDialog.java [deleted file]
src/org/fedorahosted/freeotp/CameraDialogFragment.java
src/org/fedorahosted/freeotp/MainActivity.java
src/org/fedorahosted/freeotp/ManualDialogFragment.java [new file with mode: 0644]
src/org/fedorahosted/freeotp/ManualSecretTextWatcher.java [moved from src/org/fedorahosted/freeotp/AddTokenSecretTextWatcher.java with 70% similarity]
src/org/fedorahosted/freeotp/ManualTextWatcher.java [moved from src/org/fedorahosted/freeotp/AddTokenTextWatcher.java with 59% similarity]

index 616e0aebfe9ddaef83c2bdab71b495e7a4be4e58..e7818cb9d80e6528be62adbf8107cc68e56736d5 100644 (file)
@@ -21,8 +21,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.fedorahosted.freeotp"
-    android:versionCode="4"
-    android:versionName="1.2" >
+    android:versionCode="5"
+    android:versionName="1.3" >
 
     <uses-sdk
         android:minSdkVersion="11"
index 61e32d75bc81aea114594846419c1bffbd702c67..d2628391cf8a8e2bf71913b4269df9ee05dfff67 100644 (file)
@@ -59,7 +59,7 @@
                 android:text="@string/id" />
 
             <EditText
-                android:id="@+id/id"
+                android:id="@+id/label"
                 android:layout_width="0dp"
                 android:layout_height="match_parent"
                 android:layout_weight="1"
diff --git a/src/org/fedorahosted/freeotp/AddTokenDialog.java b/src/org/fedorahosted/freeotp/AddTokenDialog.java
deleted file mode 100644 (file)
index 9e04c8a..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * FreeOTP
- *
- * Authors: Nathaniel McCallum <npmccallum@redhat.com>
- *
- * Copyright (C) 2013  Nathaniel McCallum, Red Hat
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.fedorahosted.freeotp;
-
-import java.util.Locale;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.net.Uri;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.EditText;
-import android.widget.RadioButton;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-public abstract class AddTokenDialog extends AlertDialog {
-       private final int SHA1_OFFSET = 1;
-       private final int TOTP_OFFSET = 0;
-
-       public AddTokenDialog(Context ctx) {
-               super(ctx);
-
-               setTitle(R.string.add_token);
-               setView(getLayoutInflater().inflate(R.layout.manual, null));
-
-               setButton(BUTTON_NEGATIVE, ctx.getString(android.R.string.cancel), new OnClickListener() {
-                       @Override
-                       public void onClick(DialogInterface dialog, int which) {
-                       }
-               });
-
-               setButton(BUTTON_POSITIVE, ctx.getString(R.string.add), new OnClickListener() {
-                       @Override
-                       public void onClick(DialogInterface dialog, int which) {
-                               // Get the fields
-                               String issuer = Uri.encode(((EditText) findViewById(R.id.issuer)).getText().toString());
-                               String id = Uri.encode(((EditText) findViewById(R.id.id)).getText().toString());
-                               String secret = Uri.encode(((EditText) findViewById(R.id.secret)).getText().toString());
-                               String type = ((Spinner) findViewById(R.id.type)).getSelectedItemId() == TOTP_OFFSET ? "totp" : "hotp";
-                               String algorithm = ((Spinner) findViewById(R.id.algorithm)).getSelectedItem().toString().toLowerCase(Locale.US);
-                               int interval = Integer.parseInt(((EditText) findViewById(R.id.interval)).getText().toString());
-                               int digits = ((RadioButton) findViewById(R.id.digits6)).isChecked() ? 6 : 8;
-
-                               // Create the URI
-                               String uri = String.format(Locale.US, "otpauth://%s/%s:%s?secret=%s&algorithm=%s&digits=%d",
-                                           type, issuer, id, secret, algorithm, digits);
-                               if (type.equals("totp"))
-                                       uri = uri.concat(String.format("&period=%d", interval));
-                               else
-                                       uri = uri.concat(String.format("&counter=%d", interval));
-
-                               // Add the token
-                               addToken(uri);
-                       }
-               });
-       }
-
-       @Override
-       public void onAttachedToWindow() {
-               super.onAttachedToWindow();
-
-               // Disable the Add button
-               getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
-
-               // Set constraints on when the Add button is enabled
-               ((EditText) findViewById(R.id.issuer)).addTextChangedListener(new AddTokenTextWatcher(this));
-               ((EditText) findViewById(R.id.id)).addTextChangedListener(new AddTokenTextWatcher(this));
-               ((EditText) findViewById(R.id.secret)).addTextChangedListener(new AddTokenSecretTextWatcher(this));
-               ((EditText) findViewById(R.id.interval)).addTextChangedListener(new AddTokenTextWatcher(this));
-
-               // Select the default algorithm
-               ((Spinner) findViewById(R.id.algorithm)).setSelection(SHA1_OFFSET);
-
-               // Setup the Interval / Counter toggle
-               ((Spinner) findViewById(R.id.type)).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-                       @Override
-                       public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-                               if (position == 0) {
-                                       ((TextView) findViewById(R.id.interval_label)).setText(R.string.interval);
-                                       ((EditText) findViewById(R.id.interval)).setText("30");
-                               } else {
-                                       ((TextView) findViewById(R.id.interval_label)).setText(R.string.counter);
-                                       ((EditText) findViewById(R.id.interval)).setText("0");
-                               }
-                       }
-
-                       @Override
-                       public void onNothingSelected(AdapterView<?> parent) {
-
-                       }
-               });
-
-       }
-
-       public abstract void addToken(String uri);
-}
index 5fe64480836405428d0b5a499182c0f31d5098fc..f4c7760a91f8746dc9a2693ef45f5602a3a4638a 100644 (file)
@@ -52,12 +52,8 @@ public class CameraDialogFragment extends BaseAlertDialogFragment implements Sur
        @Override
        public void onClick(DialogInterface dialog, int which) {
                if (which == AlertDialog.BUTTON_NEUTRAL) {
-                       new AddTokenDialog(getActivity()) {
-                               @Override
-                               public void addToken(String uri) {
-                                       ((MainActivity) getActivity()).tokenURIReceived(uri);
-                               }
-                       }.show();
+                       new ManualDialogFragment().show(getFragmentManager(),
+                                       ManualDialogFragment.FRAGMENT_TAG);
                }
        }
 
index 56737ff64b9709abb90c1bd45d72dbc6ce0184a3..1eb632abed79154c96584a1a1da425b1b3413d2f 100644 (file)
@@ -101,12 +101,8 @@ public class MainActivity extends Activity implements OnMenuItemClickListener {
                                new CameraDialogFragment().show(getFragmentManager(),
                                                CameraDialogFragment.FRAGMENT_TAG);
                        } else {
-                               new AddTokenDialog(this) {
-                                       @Override
-                                       public void addToken(String uri) {
-                                               tokenURIReceived(uri);
-                                       }
-                               }.show();
+                               new ManualDialogFragment().show(getFragmentManager(),
+                                               ManualDialogFragment.FRAGMENT_TAG);
                        }
 
                        return true;
diff --git a/src/org/fedorahosted/freeotp/ManualDialogFragment.java b/src/org/fedorahosted/freeotp/ManualDialogFragment.java
new file mode 100644 (file)
index 0000000..9d525df
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * FreeOTP
+ *
+ * Authors: Nathaniel McCallum <npmccallum@redhat.com>
+ *
+ * Copyright (C) 2013  Nathaniel McCallum, Red Hat
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.fedorahosted.freeotp;
+
+import java.util.Locale;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.net.Uri;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+public class ManualDialogFragment extends BaseAlertDialogFragment implements OnItemSelectedListener {
+       public static final String FRAGMENT_TAG = "fragment_camera";
+       private static final String DEFAULT_INTERVAL = "30";
+       private static final String DEFAULT_COUNTER = "0";
+
+       private final int SHA1_OFFSET = 1;
+       private final int TOTP_OFFSET = 0;
+       private EditText mIssuer;
+       private EditText mLabel;
+       private EditText mSecret;
+       private EditText mInterval;
+       private Spinner mAlgorithm;
+       private Spinner mType;
+
+       public ManualDialogFragment() {
+               super(R.string.add_token, R.layout.manual, android.R.string.cancel, 0, R.string.add);
+       }
+
+       @Override
+       protected void onViewInflated(View view) {
+               mIssuer = (EditText) view.findViewById(R.id.issuer);
+               mLabel = (EditText) view.findViewById(R.id.label);
+               mSecret = (EditText) view.findViewById(R.id.secret);
+               mInterval = (EditText) view.findViewById(R.id.interval);
+               mAlgorithm = (Spinner) view.findViewById(R.id.algorithm);
+               mType = (Spinner) view.findViewById(R.id.type);
+
+               // Select the default algorithm
+               mAlgorithm.setSelection(SHA1_OFFSET);
+
+               // Setup the Interval / Counter toggle
+               mType.setOnItemSelectedListener(this);
+       }
+
+       @Override
+       public void onStart() {
+               super.onStart();
+
+               AlertDialog ad = (AlertDialog) getDialog();
+
+               // Disable the Add button
+               ad.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+
+               // Set constraints on when the Add button is enabled
+               TextWatcher tw = new ManualTextWatcher(ad);
+               mIssuer.addTextChangedListener(tw);
+               mLabel.addTextChangedListener(tw);
+               mSecret.addTextChangedListener(new ManualSecretTextWatcher(ad));
+               mInterval.addTextChangedListener(tw);
+       }
+
+       @Override
+       public void onClick(DialogInterface dialog, int which) {
+               if (which != AlertDialog.BUTTON_POSITIVE)
+                       return;
+
+               // Get the fields
+               String issuer = Uri.encode(mIssuer.getText().toString());
+               String label = Uri.encode(mLabel.getText().toString());
+               String secret = Uri.encode(mSecret.getText().toString());
+               String type = mType.getSelectedItemId() == TOTP_OFFSET ? "totp" : "hotp";
+               String algorithm = mAlgorithm.getSelectedItem().toString().toLowerCase(Locale.US);
+               int interval = Integer.parseInt(mInterval.getText().toString());
+               int digits = ((RadioButton) getDialog().findViewById(R.id.digits6)).isChecked() ? 6 : 8;
+
+               // Create the URI
+               String uri = String.format(Locale.US, "otpauth://%s/%s:%s?secret=%s&algorithm=%s&digits=%d",
+                                   type, issuer, label, secret, algorithm, digits);
+               if (type.equals("totp"))
+                       uri = uri.concat(String.format("&period=%d", interval));
+               else
+                       uri = uri.concat(String.format("&counter=%d", interval));
+
+               // Add the token
+               if (uri != null)
+                       ((MainActivity) getActivity()).tokenURIReceived(uri);
+       }
+
+       @Override
+       public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+               TextView tv = (TextView) getDialog().findViewById(R.id.interval_label);
+               if (position == 0) {
+                       tv.setText(R.string.interval);
+                       mInterval.setText(DEFAULT_INTERVAL);
+               } else {
+                       tv.setText(R.string.counter);
+                       mInterval.setText(DEFAULT_COUNTER);
+               }
+       }
+
+       @Override
+       public void onNothingSelected(AdapterView<?> parent) {
+       }
+}
similarity index 70%
rename from src/org/fedorahosted/freeotp/AddTokenSecretTextWatcher.java
rename to src/org/fedorahosted/freeotp/ManualSecretTextWatcher.java
index 68752ee8f00455d7582b8ae135e031ba5cd8bd03..8c77e40b7c62a3fb18db42233fe1aff94fef11b2 100644 (file)
@@ -23,25 +23,25 @@ package org.fedorahosted.freeotp;
 import android.app.AlertDialog;
 import android.text.Editable;
 
-public class AddTokenSecretTextWatcher extends AddTokenTextWatcher {
-       public AddTokenSecretTextWatcher(AlertDialog dialog) {
+public class ManualSecretTextWatcher extends ManualTextWatcher {
+       public ManualSecretTextWatcher(AlertDialog dialog) {
                super(dialog);
        }
 
        @Override
        public void afterTextChanged(Editable s) {
-               super.afterTextChanged(s);
-
-               if (s.length() == 0)
-                       return;
-
-               boolean haveData = false;
-               for (int i = s.length() - 1; i >= 0; i--) {
-                       char c = s.charAt(i);
-                       if (c != '=')
-                               haveData = true;
-                       else if (haveData)
-                               s.delete(i, i + 1);
+               if (s.length() != 0) {
+                       // Ensure that = is only permitted at the end
+                       boolean haveData = false;
+                       for (int i = s.length() - 1; i >= 0; i--) {
+                               char c = s.charAt(i);
+                               if (c != '=')
+                                       haveData = true;
+                               else if (haveData)
+                                       s.delete(i, i + 1);
+                       }
                }
+
+               super.afterTextChanged(s);
        }
 }
similarity index 59%
rename from src/org/fedorahosted/freeotp/AddTokenTextWatcher.java
rename to src/org/fedorahosted/freeotp/ManualTextWatcher.java
index 1f3a4adb620a10b8b968f45ca1f45e9a74fdf1c8..774460eef5d9488fb9a324da10191b80a412a369 100644 (file)
@@ -26,11 +26,19 @@ import android.text.TextWatcher;
 import android.widget.Button;
 import android.widget.EditText;
 
-public class AddTokenTextWatcher implements TextWatcher {
-       private final AlertDialog dialog;
+public class ManualTextWatcher implements TextWatcher {
+       private final Button mButton;
+       private final EditText mIssuer;
+       private final EditText mLabel;
+       private final EditText mSecret;
+       private final EditText mInterval;
 
-       public AddTokenTextWatcher(AlertDialog dialog) {
-               this.dialog = dialog;
+       public ManualTextWatcher(AlertDialog dialog) {
+               mButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
+               mIssuer = (EditText) dialog.findViewById(R.id.issuer);
+               mLabel = (EditText) dialog.findViewById(R.id.label);
+               mSecret = (EditText) dialog.findViewById(R.id.secret);
+               mInterval = (EditText) dialog.findViewById(R.id.interval);
        }
 
        @Override
@@ -40,24 +48,22 @@ public class AddTokenTextWatcher implements TextWatcher {
 
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
-               Button b = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
+               mButton.setEnabled(false);
 
-               b.setEnabled(false);
-
-               if (((EditText) dialog.findViewById(R.id.issuer)).getText().length() == 0)
+               if (mIssuer.getText().length() == 0)
                        return;
 
-               if (((EditText) dialog.findViewById(R.id.id)).getText().length() == 0)
+               if (mLabel.getText().length() == 0)
                        return;
 
-               if (((EditText) dialog.findViewById(R.id.secret)).getText().length() == 0 ||
-                       ((EditText) dialog.findViewById(R.id.secret)).getText().length() % 8 != 0)
+               if (mSecret.getText().length() == 0 ||
+                       mSecret.getText().length() % 8 != 0)
                        return;
 
-               if (((EditText) dialog.findViewById(R.id.interval)).getText().length() == 0)
+               if (mInterval.getText().length() == 0)
                        return;
 
-               b.setEnabled(true);
+               mButton.setEnabled(true);
        }
 
        @Override