diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5fc7589d..34ac790f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -54,5 +54,10 @@
android:label="Manage key slots"
android:theme="@style/AppTheme.TransparentActionBar">
+
+
diff --git a/app/src/main/java/me/impy/aegis/db/DatabaseManager.java b/app/src/main/java/me/impy/aegis/db/DatabaseManager.java
index 8699dbe1..eb7bc900 100644
--- a/app/src/main/java/me/impy/aegis/db/DatabaseManager.java
+++ b/app/src/main/java/me/impy/aegis/db/DatabaseManager.java
@@ -172,6 +172,17 @@ public class DatabaseManager {
return groups;
}
+ public void removeGroup(String groupName) {
+ TreeSet groups = new TreeSet<>(Collator.getInstance());
+ for (DatabaseEntry entry : getEntries()) {
+ String group = entry.getGroup();
+ if (group != null && group.equals(groupName)) {
+ entry.setGroup(null);
+ _db.replaceEntry(entry);
+ }
+ }
+ }
+
public DatabaseFileCredentials getCredentials() {
assertState(false, true);
return _creds;
diff --git a/app/src/main/java/me/impy/aegis/ui/GroupManagerActivity.java b/app/src/main/java/me/impy/aegis/ui/GroupManagerActivity.java
new file mode 100644
index 00000000..56fe99c0
--- /dev/null
+++ b/app/src/main/java/me/impy/aegis/ui/GroupManagerActivity.java
@@ -0,0 +1,58 @@
+package me.impy.aegis.ui;
+
+import android.os.Bundle;
+
+import java.util.TreeSet;
+
+import androidx.appcompat.app.ActionBar;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import me.impy.aegis.AegisApplication;
+import me.impy.aegis.R;
+import me.impy.aegis.db.DatabaseFileCredentials;
+import me.impy.aegis.db.DatabaseManager;
+import me.impy.aegis.db.slots.Slot;
+import me.impy.aegis.ui.views.GroupAdapter;
+import me.impy.aegis.ui.views.SlotAdapter;
+
+public class GroupManagerActivity extends AegisActivity implements GroupAdapter.Listener {
+ private AegisApplication _app;
+ private DatabaseManager _db;
+ private GroupAdapter _adapter;
+
+ TreeSet groups;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_groups);
+
+ _app = (AegisApplication) getApplication();
+ _db = _app.getDatabaseManager();
+
+ groups = _db.getGroups();
+
+ ActionBar bar = getSupportActionBar();
+ bar.setHomeAsUpIndicator(R.drawable.ic_close);
+ bar.setDisplayHomeAsUpEnabled(true);
+
+ // set up the recycler view
+ _adapter = new GroupAdapter(this);
+ RecyclerView slotsView = findViewById(R.id.list_slots);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+ slotsView.setLayoutManager(layoutManager);
+ slotsView.setAdapter(_adapter);
+ slotsView.setNestedScrollingEnabled(false);
+
+ // load the slots and masterKey
+ for (String group : groups) {
+ _adapter.addGroup(group);
+ }
+ }
+
+ @Override
+ public void onRemoveGroup(String group) {
+ _db.removeGroup(group);
+ groups.remove(group);
+ }
+}
diff --git a/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java b/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java
index 1141cc5d..9190c95b 100644
--- a/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java
+++ b/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java
@@ -67,6 +67,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
private SwitchPreference _fingerprintPreference;
private Preference _setPasswordPreference;
private Preference _slotsPreference;
+ private Preference _groupsPreference;
@Override
public void onCreatePreferencesFix(Bundle savedInstanceState, String rootKey) {
@@ -208,6 +209,15 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
}
});
+ _groupsPreference = findPreference("pref_groups");
+ _groupsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(getActivity(), GroupManagerActivity.class);
+ startActivity(intent);
+ return true;
+ }
+ });
updateEncryptionPreferences();
}
diff --git a/app/src/main/java/me/impy/aegis/ui/views/GroupAdapter.java b/app/src/main/java/me/impy/aegis/ui/views/GroupAdapter.java
new file mode 100644
index 00000000..460f231b
--- /dev/null
+++ b/app/src/main/java/me/impy/aegis/ui/views/GroupAdapter.java
@@ -0,0 +1,62 @@
+package me.impy.aegis.ui.views;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+import androidx.recyclerview.widget.RecyclerView;
+import me.impy.aegis.R;
+import me.impy.aegis.db.slots.Slot;
+
+public class GroupAdapter extends RecyclerView.Adapter {
+ private GroupAdapter.Listener _listener;
+ private ArrayList _groups;
+
+ public GroupAdapter(GroupAdapter.Listener listener) {
+ _listener = listener;
+ _groups = new ArrayList<>();
+ }
+
+ public void addGroup(String group) {
+ _groups.add(group);
+
+ int position = getItemCount() - 1;
+ if (position == 0) {
+ notifyDataSetChanged();
+ } else {
+ notifyItemInserted(position);
+ }
+ }
+
+ public void removeGroup(String group) {
+ int position = _groups.indexOf(group);
+ _groups.remove(position);
+ notifyItemRemoved(position);
+ }
+
+ @Override
+ public GroupHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_slot, parent, false);
+ return new GroupHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(GroupHolder holder, int position) {
+ holder.setData(_groups.get(position));
+ holder.setOnDeleteClickListener(v -> {
+ int position12 = holder.getAdapterPosition();
+ _listener.onRemoveGroup(_groups.get(position12));
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return _groups.size();
+ }
+
+ public interface Listener {
+ void onRemoveGroup(String group);
+ }
+}
diff --git a/app/src/main/java/me/impy/aegis/ui/views/GroupHolder.java b/app/src/main/java/me/impy/aegis/ui/views/GroupHolder.java
new file mode 100644
index 00000000..175897ec
--- /dev/null
+++ b/app/src/main/java/me/impy/aegis/ui/views/GroupHolder.java
@@ -0,0 +1,35 @@
+package me.impy.aegis.ui.views;
+
+import androidx.recyclerview.widget.RecyclerView;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import me.impy.aegis.R;
+import me.impy.aegis.crypto.KeyStoreHandle;
+import me.impy.aegis.crypto.KeyStoreHandleException;
+import me.impy.aegis.db.slots.FingerprintSlot;
+import me.impy.aegis.db.slots.PasswordSlot;
+import me.impy.aegis.db.slots.RawSlot;
+import me.impy.aegis.db.slots.Slot;
+import me.impy.aegis.helpers.FingerprintHelper;
+
+public class GroupHolder extends RecyclerView.ViewHolder {
+ private TextView _slotName;
+ private ImageView _buttonDelete;
+
+ public GroupHolder(final View view) {
+ super(view);
+ _slotName = view.findViewById(R.id.text_slot_name);
+ _buttonDelete = view.findViewById(R.id.button_delete);
+ }
+
+ public void setData(String groupName) {
+ _slotName.setText(groupName);
+ }
+
+ public void setOnDeleteClickListener(View.OnClickListener listener) {
+ _buttonDelete.setOnClickListener(listener);
+ }
+}
diff --git a/app/src/main/res/layout/activity_groups.xml b/app/src/main/res/layout/activity_groups.xml
new file mode 100644
index 00000000..862af3ab
--- /dev/null
+++ b/app/src/main/res/layout/activity_groups.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/card_group.xml b/app/src/main/res/layout/card_group.xml
new file mode 100644
index 00000000..f44fb884
--- /dev/null
+++ b/app/src/main/res/layout/card_group.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 47f46827..0143797b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -142,4 +142,6 @@
New group...
Enter a group name
Group name
+ Edit groups
+ Manage and delete your groups here
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index cd846caf..92cc1a04 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -20,6 +20,12 @@
android:title="@string/pref_account_name_title"
android:summary="@string/pref_account_name_summary"
app:iconSpaceReserved="false"/>
+
+