From da37b5175ee800d21b5de6e4b59cb7acf23e0286 Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Wed, 6 Jun 2018 17:23:40 +0200 Subject: [PATCH] Finish up HOTP support Close #1 --- .../main/java/me/impy/aegis/otp/HotpInfo.java | 4 ++++ .../main/java/me/impy/aegis/otp/OtpInfo.java | 1 - .../java/me/impy/aegis/ui/MainActivity.java | 5 +++++ .../me/impy/aegis/ui/views/EntryAdapter.java | 21 +++++++++++++++++++ .../me/impy/aegis/ui/views/EntryHolder.java | 14 ++++++++++++- .../me/impy/aegis/ui/views/EntryListView.java | 6 ++++++ .../res/drawable/ic_refresh_black_24dp.xml | 7 +++++++ app/src/main/res/layout/card_entry.xml | 19 ++++++++++++++--- 8 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/ic_refresh_black_24dp.xml diff --git a/app/src/main/java/me/impy/aegis/otp/HotpInfo.java b/app/src/main/java/me/impy/aegis/otp/HotpInfo.java index de465c96..1b406128 100644 --- a/app/src/main/java/me/impy/aegis/otp/HotpInfo.java +++ b/app/src/main/java/me/impy/aegis/otp/HotpInfo.java @@ -60,4 +60,8 @@ public class HotpInfo extends OtpInfo { } _counter = counter; } + + public void incrementCounter() throws OtpInfoException { + setCounter(getCounter() + 1); + } } diff --git a/app/src/main/java/me/impy/aegis/otp/OtpInfo.java b/app/src/main/java/me/impy/aegis/otp/OtpInfo.java index 03d36dcd..fff34f45 100644 --- a/app/src/main/java/me/impy/aegis/otp/OtpInfo.java +++ b/app/src/main/java/me/impy/aegis/otp/OtpInfo.java @@ -95,7 +95,6 @@ public abstract class OtpInfo implements Serializable { String algo = obj.getString("algo"); int digits = obj.getInt("digits"); - switch (type) { case "totp": int period = obj.getInt("period"); diff --git a/app/src/main/java/me/impy/aegis/ui/MainActivity.java b/app/src/main/java/me/impy/aegis/ui/MainActivity.java index f65a2ff9..a0744bba 100644 --- a/app/src/main/java/me/impy/aegis/ui/MainActivity.java +++ b/app/src/main/java/me/impy/aegis/ui/MainActivity.java @@ -438,4 +438,9 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene public void onEntryDrop(DatabaseEntry entry) { saveDatabase(); } + + @Override + public void onEntryChange(DatabaseEntry entry) { + saveDatabase(); + } } diff --git a/app/src/main/java/me/impy/aegis/ui/views/EntryAdapter.java b/app/src/main/java/me/impy/aegis/ui/views/EntryAdapter.java index 755e8a20..b3675ca5 100644 --- a/app/src/main/java/me/impy/aegis/ui/views/EntryAdapter.java +++ b/app/src/main/java/me/impy/aegis/ui/views/EntryAdapter.java @@ -13,7 +13,9 @@ import java.util.UUID; import me.impy.aegis.R; import me.impy.aegis.db.DatabaseEntry; import me.impy.aegis.helpers.ItemTouchHelperAdapter; +import me.impy.aegis.otp.HotpInfo; import me.impy.aegis.otp.OtpInfo; +import me.impy.aegis.otp.OtpInfoException; import me.impy.aegis.otp.TotpInfo; public class EntryAdapter extends RecyclerView.Adapter implements ItemTouchHelperAdapter { @@ -124,6 +126,24 @@ public class EntryAdapter extends RecyclerView.Adapter implements I return _listener.onLongEntryClick(_entries.get(position)); } }); + holder.setOnRefreshClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // this will only be called if the entry is of type HotpInfo + try { + ((HotpInfo)entry.getInfo()).incrementCounter(); + } catch (OtpInfoException e) { + throw new RuntimeException(e); + } + + // notify the listener that the counter has been incremented + // this gives it a chance to save the database + _listener.onEntryChange(entry); + + // finally, refresh the code in the UI + holder.refreshCode(); + } + }); } public int getUniformPeriod() { @@ -163,5 +183,6 @@ public class EntryAdapter extends RecyclerView.Adapter implements I boolean onLongEntryClick(DatabaseEntry entry); void onEntryMove(DatabaseEntry entry1, DatabaseEntry entry2); void onEntryDrop(DatabaseEntry entry); + void onEntryChange(DatabaseEntry entry); } } diff --git a/app/src/main/java/me/impy/aegis/ui/views/EntryHolder.java b/app/src/main/java/me/impy/aegis/ui/views/EntryHolder.java index 70b868c0..990648a9 100644 --- a/app/src/main/java/me/impy/aegis/ui/views/EntryHolder.java +++ b/app/src/main/java/me/impy/aegis/ui/views/EntryHolder.java @@ -12,6 +12,8 @@ import me.impy.aegis.R; import me.impy.aegis.db.DatabaseEntry; import me.impy.aegis.helpers.TextDrawableHelper; import me.impy.aegis.helpers.UiRefresher; +import me.impy.aegis.otp.HotpInfo; +import me.impy.aegis.otp.OtpInfoException; import me.impy.aegis.otp.TotpInfo; public class EntryHolder extends RecyclerView.ViewHolder { @@ -20,6 +22,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { private TextView _profileIssuer; private ImageView _profileDrawable; private DatabaseEntry _entry; + private ImageView _buttonRefresh; private PeriodProgressBar _progressBar; @@ -31,6 +34,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { _profileCode = view.findViewById(R.id.profile_code); _profileIssuer = view.findViewById(R.id.profile_issuer); _profileDrawable = view.findViewById(R.id.ivTextDrawable); + _buttonRefresh = view.findViewById(R.id.buttonRefresh); _progressBar = view.findViewById(R.id.progressBar); int primaryColorId = view.getContext().getResources().getColor(R.color.colorPrimary); @@ -53,11 +57,15 @@ public class EntryHolder extends RecyclerView.ViewHolder { public void setData(DatabaseEntry entry, boolean showIssuer, boolean showProgress) { _entry = entry; + // only show the progress bar if there is no uniform period and the entry type is TotpInfo _progressBar.setVisibility(showProgress ? View.VISIBLE : View.INVISIBLE); if (showProgress) { _progressBar.setPeriod(((TotpInfo)entry.getInfo()).getPeriod()); } + // only show the button if this entry is of type HotpInfo + _buttonRefresh.setVisibility(entry.getInfo() instanceof HotpInfo ? View.VISIBLE : View.GONE); + _profileName.setText(entry.getName()); _profileIssuer.setText(""); if (showIssuer) { @@ -70,6 +78,10 @@ public class EntryHolder extends RecyclerView.ViewHolder { refreshCode(); } + public void setOnRefreshClickListener(View.OnClickListener listener) { + _buttonRefresh.setOnClickListener(listener); + } + public void startRefreshLoop() { _refresher.start(); } @@ -78,7 +90,7 @@ public class EntryHolder extends RecyclerView.ViewHolder { _refresher.stop(); } - private void refreshCode() { + public void refreshCode() { String otp = _entry.getInfo().getOtp(); _profileCode.setText(otp.substring(0, otp.length() / 2) + " " + otp.substring(otp.length() / 2)); } diff --git a/app/src/main/java/me/impy/aegis/ui/views/EntryListView.java b/app/src/main/java/me/impy/aegis/ui/views/EntryListView.java index 2531887e..e6523272 100644 --- a/app/src/main/java/me/impy/aegis/ui/views/EntryListView.java +++ b/app/src/main/java/me/impy/aegis/ui/views/EntryListView.java @@ -120,6 +120,11 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { _listener.onEntryDrop(entry); } + @Override + public void onEntryChange(DatabaseEntry entry) { + _listener.onEntryChange(entry); + } + public void setShowIssuer(boolean showIssuer) { _adapter.setShowIssuer(showIssuer); _adapter.notifyDataSetChanged(); @@ -149,5 +154,6 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { void onEntryClick(DatabaseEntry entry); void onEntryMove(DatabaseEntry entry1, DatabaseEntry entry2); void onEntryDrop(DatabaseEntry entry); + void onEntryChange(DatabaseEntry entry); } } diff --git a/app/src/main/res/drawable/ic_refresh_black_24dp.xml b/app/src/main/res/drawable/ic_refresh_black_24dp.xml new file mode 100644 index 00000000..5e434f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh_black_24dp.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/layout/card_entry.xml b/app/src/main/res/layout/card_entry.xml index 22b8c510..36de09c1 100644 --- a/app/src/main/res/layout/card_entry.xml +++ b/app/src/main/res/layout/card_entry.xml @@ -1,7 +1,5 @@ +