diff --git a/CHANGELOG b/CHANGELOG index 895fd483e..84afa80c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,7 @@ -KeepassDX (2.5.0.0beta11) +KeepassDX (2.5.0.0beta14) + * Optimize all the memory with parcelables / fix search + +KeepassDX (2.5.0.0beta13) * Fix memory issue with parcelable (crash in beta12 version) KeepassDX (2.5.0.0beta12) diff --git a/app/build.gradle b/app/build.gradle index 20cc7a46a..8d9385cdd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.kunzisoft.keepass" minSdkVersion 15 targetSdkVersion 27 - versionCode = 13 - versionName = "2.5.0.0beta13" + versionCode = 14 + versionName = "2.5.0.0beta14" multiDexEnabled true testApplicationId = "com.kunzisoft.keepass.tests" diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.java b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.java index 768bd34bd..08a8512b8 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.java +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.java @@ -178,7 +178,7 @@ public class EntryEditActivity extends LockingHideActivity PwDatabase pm = db.getPwDatabase(); if ( uuidBytes == null ) { - PwGroupId parentId = (PwGroupId) intent.getSerializableExtra(KEY_PARENT); + PwGroupId parentId = intent.getParcelableExtra(KEY_PARENT); PwGroup parent = pm.getGroupByGroupId(parentId); mEntry = db.createEntry(parent); mIsNew = true; @@ -548,7 +548,7 @@ public class EntryEditActivity extends LockingHideActivity if (mCallbackNewEntry != null) { Bundle bundle = new Bundle(); Intent intentEntry = new Intent(); - bundle.putSerializable(ADD_OR_UPDATE_ENTRY_KEY, mCallbackNewEntry); + bundle.putParcelable(ADD_OR_UPDATE_ENTRY_KEY, mCallbackNewEntry); intentEntry.putExtras(bundle); if (mIsNew) { setResult(ADD_ENTRY_RESULT_CODE, intentEntry); diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java index 1f67e4815..d90d8d8bf 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java +++ b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java @@ -70,8 +70,8 @@ import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment; import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment; import com.kunzisoft.keepass.dialogs.ReadOnlyDialog; import com.kunzisoft.keepass.icons.IconPackChooser; -import com.kunzisoft.keepass.selection.EntrySelectionHelper; import com.kunzisoft.keepass.search.SearchResultsActivity; +import com.kunzisoft.keepass.selection.EntrySelectionHelper; import com.kunzisoft.keepass.settings.PreferencesUtil; import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment; import com.kunzisoft.keepass.tasks.UIToastTask; @@ -205,14 +205,14 @@ public class GroupActivity extends ListNodesActivity if (savedInstanceState != null) { if (savedInstanceState.containsKey(OLD_GROUP_TO_UPDATE_KEY)) - oldGroupToUpdate = (PwGroup) savedInstanceState.getSerializable(OLD_GROUP_TO_UPDATE_KEY); + oldGroupToUpdate = savedInstanceState.getParcelable(OLD_GROUP_TO_UPDATE_KEY); if (savedInstanceState.containsKey(NODE_TO_COPY_KEY)) { - nodeToCopy = (PwNode) savedInstanceState.getSerializable(NODE_TO_COPY_KEY); + nodeToCopy = savedInstanceState.getParcelable(NODE_TO_COPY_KEY); toolbarPaste.setOnMenuItemClickListener(new OnCopyMenuItemClickListener()); } else if (savedInstanceState.containsKey(NODE_TO_MOVE_KEY)) { - nodeToMove = (PwNode) savedInstanceState.getSerializable(NODE_TO_MOVE_KEY); + nodeToMove = savedInstanceState.getParcelable(NODE_TO_MOVE_KEY); toolbarPaste.setOnMenuItemClickListener(new OnMoveMenuItemClickListener()); } } @@ -234,24 +234,24 @@ public class GroupActivity extends ListNodesActivity @Override protected void onSaveInstanceState(Bundle outState) { - outState.putSerializable(GROUP_ID_KEY, mCurrentGroup.getId()); - outState.putSerializable(OLD_GROUP_TO_UPDATE_KEY, oldGroupToUpdate); + outState.putParcelable(GROUP_ID_KEY, mCurrentGroup.getId()); + outState.putParcelable(OLD_GROUP_TO_UPDATE_KEY, oldGroupToUpdate); if (nodeToCopy != null) - outState.putSerializable(NODE_TO_COPY_KEY, nodeToCopy); + outState.putParcelable(NODE_TO_COPY_KEY, nodeToCopy); if (nodeToMove != null) - outState.putSerializable(NODE_TO_MOVE_KEY, nodeToMove); + outState.putParcelable(NODE_TO_MOVE_KEY, nodeToMove); super.onSaveInstanceState(outState); } protected PwGroup retrieveCurrentGroup(@Nullable Bundle savedInstanceState) { - PwGroupId pwGroupId = null; // TODO Parcelable + PwGroupId pwGroupId = null; if (savedInstanceState != null && savedInstanceState.containsKey(GROUP_ID_KEY)) { - pwGroupId = (PwGroupId) savedInstanceState.getSerializable(GROUP_ID_KEY); + pwGroupId = savedInstanceState.getParcelable(GROUP_ID_KEY); } else { if (getIntent() != null) - pwGroupId = (PwGroupId) getIntent().getSerializableExtra(GROUP_ID_KEY); + pwGroupId = getIntent().getParcelableExtra(GROUP_ID_KEY); } Database db = App.getDB(); @@ -671,12 +671,19 @@ public class GroupActivity extends ListNodesActivity // add query to the Intent Extras searchIntent.setAction(Intent.ACTION_SEARCH); searchIntent.putExtra(SearchManager.QUERY, query); + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && autofillHelper.getAssistStructure() != null ) { AutofillHelper.addAssistStructureExtraInIntent(searchIntent, autofillHelper.getAssistStructure()); startActivityForResult(searchIntent, AutofillHelper.AUTOFILL_RESPONSE_REQUEST_CODE); customSearchQueryExecuted = true; } + // To get the keyboard response, verify if the current intent contains the EntrySelection key + else if (EntrySelectionHelper.isIntentInEntrySelectionMode(getIntent())){ + EntrySelectionHelper.addEntrySelectionModeExtraInIntent(searchIntent); + startActivityForResult(searchIntent, EntrySelectionHelper.ENTRY_SELECTION_RESPONSE_REQUEST_CODE); + customSearchQueryExecuted = true; + } } if (!customSearchQueryExecuted) { diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/ListNodesFragment.java b/app/src/main/java/com/kunzisoft/keepass/activities/ListNodesFragment.java index 0dcbd3de1..149f0702a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/ListNodesFragment.java +++ b/app/src/main/java/com/kunzisoft/keepass/activities/ListNodesFragment.java @@ -35,6 +35,7 @@ public class ListNodesFragment extends StylishFragment implements private static final String TAG = ListNodesFragment.class.getName(); + private static final String GROUP_KEY = "GROUP_KEY"; private static final String GROUP_ID_KEY = "GROUP_ID_KEY"; private NodeAdapter.NodeClickCallback nodeClickCallback; @@ -48,10 +49,20 @@ public class ListNodesFragment extends StylishFragment implements // Preferences for sorting private SharedPreferences prefs; + public static ListNodesFragment newInstance(PwGroup group) { + Bundle bundle = new Bundle(); + if (group != null) { + bundle.putParcelable(GROUP_KEY, group); + } + ListNodesFragment listNodesFragment = new ListNodesFragment(); + listNodesFragment.setArguments(bundle); + return listNodesFragment; + } + public static ListNodesFragment newInstance(PwGroupId groupId) { Bundle bundle=new Bundle(); if (groupId != null) { - bundle.putSerializable(GROUP_ID_KEY, groupId); + bundle.putParcelable(GROUP_ID_KEY, groupId); } ListNodesFragment listNodesFragment = new ListNodesFragment(); listNodesFragment.setArguments(bundle); @@ -106,16 +117,20 @@ public class ListNodesFragment extends StylishFragment implements prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); } - protected PwGroup initCurrentGroup() { // TODO Change by parcelable + protected PwGroup initCurrentGroup() { Database db = App.getDB(); PwGroup root = db.getPwDatabase().getRootGroup(); PwGroup currentGroup = null; if (getArguments() != null) { + // Contains all the group in element + if (getArguments().containsKey(GROUP_KEY)) { + currentGroup = getArguments().getParcelable(GROUP_KEY); + } // Contains only the group id, so the group must be retrieve if (getArguments().containsKey(GROUP_ID_KEY)) { - PwGroupId pwGroupId = (PwGroupId) getArguments().getSerializable(GROUP_ID_KEY); + PwGroupId pwGroupId = getArguments().getParcelable(GROUP_ID_KEY); if ( pwGroupId != null ) currentGroup = db.getPwDatabase().getGroupByGroupId(pwGroupId); } @@ -234,7 +249,7 @@ public class ListNodesFragment extends StylishFragment implements case EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE: if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE || resultCode == EntryEditActivity.UPDATE_ENTRY_RESULT_CODE) { - PwNode newNode = (PwNode) data.getSerializableExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY); + PwNode newNode = data.getParcelableExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY); if (newNode != null) { if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE) mAdapter.addNode(newNode); diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java index 0ad180940..1c3b5fab7 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java @@ -26,6 +26,7 @@ import android.support.annotation.NonNull; import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.util.SortedListAdapterCallback; +import android.util.Log; import android.util.TypedValue; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -33,6 +34,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import com.kunzisoft.keepass.R; import com.kunzisoft.keepass.app.App; @@ -43,6 +45,7 @@ import com.kunzisoft.keepass.icons.IconPackChooser; import com.kunzisoft.keepass.settings.PreferencesUtil; public class NodeAdapter extends RecyclerView.Adapter { + private static final String TAG = NodeAdapter.class.getName(); private SortedList nodeSortedList; @@ -122,8 +125,12 @@ public class NodeAdapter extends RecyclerView.Adapter { public void rebuildList(PwGroup group) { this.nodeSortedList.clear(); assignPreferences(); - if (group != null) { + // TODO verify sort + try { this.nodeSortedList.addAll(group.getDirectChildren()); + } catch (Exception e) { + Log.e(TAG, "Can't add node elements to the list", e); + Toast.makeText(context, "Can't add node elements to the list : " + e.getMessage(), Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/AutoType.java b/app/src/main/java/com/kunzisoft/keepass/database/AutoType.java index dbdb97707..328ecba1d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/AutoType.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/AutoType.java @@ -19,20 +19,57 @@ */ package com.kunzisoft.keepass.database; -import java.io.Serializable; +import android.os.Parcel; +import android.os.Parcelable; + +import com.kunzisoft.keepass.utils.MemUtil; + import java.util.HashMap; import java.util.Map; import java.util.Set; -public class AutoType implements Cloneable, Serializable { +public class AutoType implements Cloneable, Parcelable { private static final long OBF_OPT_NONE = 0; public boolean enabled = true; public long obfuscationOptions = OBF_OPT_NONE; public String defaultSequence = ""; - private HashMap windowSeqPairs = new HashMap<>(); + public AutoType() {} + + public AutoType(Parcel in) { + enabled = in.readByte() != 0; + obfuscationOptions = in.readLong(); + defaultSequence = in.readString(); + windowSeqPairs = MemUtil.readStringParcelableMap(in); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (enabled ? 1 : 0)); + dest.writeLong(obfuscationOptions); + dest.writeString(defaultSequence); + MemUtil.writeStringParcelableMap(dest, windowSeqPairs); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public AutoType createFromParcel(Parcel in) { + return new AutoType(in); + } + + @Override + public AutoType[] newArray(int size) { + return new AutoType[size]; + } + }; + @SuppressWarnings("unchecked") public AutoType clone() { AutoType auto; diff --git a/app/src/main/java/com/kunzisoft/keepass/database/ExtraFields.java b/app/src/main/java/com/kunzisoft/keepass/database/ExtraFields.java index 40ec63fa3..77e637e25 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/ExtraFields.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/ExtraFields.java @@ -19,9 +19,12 @@ */ package com.kunzisoft.keepass.database; -import com.kunzisoft.keepass.database.security.ProtectedString; +import android.os.Parcel; +import android.os.Parcelable; + +import com.kunzisoft.keepass.database.security.ProtectedString; +import com.kunzisoft.keepass.utils.MemUtil; -import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -32,7 +35,7 @@ import static com.kunzisoft.keepass.database.PwEntryV4.STR_TITLE; import static com.kunzisoft.keepass.database.PwEntryV4.STR_URL; import static com.kunzisoft.keepass.database.PwEntryV4.STR_USERNAME; -public class ExtraFields implements Serializable, Cloneable { +public class ExtraFields implements Parcelable, Cloneable { private Map fields; @@ -40,6 +43,32 @@ public class ExtraFields implements Serializable, Cloneable { fields = new HashMap<>(); } + public ExtraFields(Parcel in) { + fields = MemUtil.readStringParcelableMap(in, ProtectedString.class); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + MemUtil.writeStringParcelableMap(dest, flags, fields); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public ExtraFields createFromParcel(Parcel in) { + return new ExtraFields(in); + } + + @Override + public ExtraFields[] newArray(int size) { + return new ExtraFields[size]; + } + }; + public boolean containsCustomFields() { return !getCustomProtectedFields().keySet().isEmpty(); } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwDate.java b/app/src/main/java/com/kunzisoft/keepass/database/PwDate.java index 06ad1aa40..c44c6b992 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwDate.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwDate.java @@ -19,10 +19,12 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; +import android.os.Parcelable; + import com.kunzisoft.keepass.app.App; import com.kunzisoft.keepass.utils.Types; -import java.io.Serializable; import java.util.Arrays; import java.util.Calendar; import java.util.Date; @@ -33,15 +35,14 @@ import java.util.Date; * @author bpellin * */ -public class PwDate implements Cloneable, Serializable { +public class PwDate implements Cloneable, Parcelable { private static final int DATE_SIZE = 5; - - private boolean cDateBuilt = false; + + private Date jDate; private boolean jDateBuilt = false; - - private Date jDate; private byte[] cDate; + private boolean cDateBuilt = false; public static final Date NEVER_EXPIRE = getNeverExpire(); public static final Date DEFAULT_DATE = getDefaultDate(); @@ -93,6 +94,38 @@ public class PwDate implements Cloneable, Serializable { jDate = new Date(); jDateBuilt = true; } + + protected PwDate(Parcel in) { + jDate = (Date) in.readSerializable(); + jDateBuilt = in.readByte() != 0; + in.readByteArray(cDate); + cDateBuilt = in.readByte() != 0; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeSerializable(jDate); + dest.writeByte((byte) (jDateBuilt ? 1 : 0)); + dest.writeByteArray(cDate); + dest.writeByte((byte) (cDateBuilt ? 1 : 0)); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwDate createFromParcel(Parcel in) { + return new PwDate(in); + } + + @Override + public PwDate[] newArray(int size) { + return new PwDate[size]; + } + }; @Override public PwDate clone() { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwEntry.java b/app/src/main/java/com/kunzisoft/keepass/database/PwEntry.java index f3b015f5b..fd25c2ec6 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwEntry.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwEntry.java @@ -19,6 +19,8 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + import com.kunzisoft.keepass.database.iterator.EntrySearchStringIterator; import com.kunzisoft.keepass.database.security.ProtectedString; @@ -30,6 +32,19 @@ public abstract class PwEntry extends PwNode { protected UUID uuid = PwDatabase.UUID_ZERO; + public PwEntry() {} + + public PwEntry(Parcel in) { + super(in); + uuid = (UUID) in.readSerializable(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeSerializable(uuid); + } + @Override protected void construct(Parent parent) { super.construct(parent); diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV3.java b/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV3.java index 1f7ce79a8..28051747d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV3.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV3.java @@ -42,6 +42,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA package com.kunzisoft.keepass.database; +import android.os.Parcel; + import java.io.UnsupportedEncodingException; import java.util.UUID; @@ -77,13 +79,11 @@ public class PwEntryV3 extends PwEntry { // TODO Parent ID to remove private int groupId; - private String title; private String username; private byte[] password; private String url; private String additional; - /** A string describing what is in pBinaryData */ private String binaryDesc; private byte[] binaryData; @@ -97,6 +97,43 @@ public class PwEntryV3 extends PwEntry { groupId = ((PwGroupIdV3) this.parent.getId()).getId(); // TODO remove } + public PwEntryV3(Parcel in) { + super(in); + groupId = in.readInt(); + title = in.readString(); + username = in.readString(); + in.readByteArray(password); + url = in.readString(); + additional = in.readString(); + binaryDesc = in.readString(); + in.readByteArray(binaryData); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(groupId); + dest.writeString(title); + dest.writeString(username); + dest.writeByteArray(password); + dest.writeString(url); + dest.writeString(additional); + dest.writeString(binaryDesc); + dest.writeByteArray(binaryData); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwEntryV3 createFromParcel(Parcel in) { + return new PwEntryV3(in); + } + + @Override + public PwEntryV3[] newArray(int size) { + return new PwEntryV3[size]; + } + }; + protected void updateWith(PwEntryV3 source) { super.assign(source); groupId = source.groupId; diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV4.java index 0c9df8767..3b9262c3e 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV4.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwEntryV4.java @@ -19,8 +19,11 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + import com.kunzisoft.keepass.database.security.ProtectedBinary; import com.kunzisoft.keepass.database.security.ProtectedString; +import com.kunzisoft.keepass.utils.MemUtil; import com.kunzisoft.keepass.utils.SprEngineV4; import java.util.ArrayList; @@ -37,7 +40,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger { public static final String STR_URL = "URL"; public static final String STR_NOTES = "Notes"; - // To decode each field not serializable + // To decode each field not parcelable private transient PwDatabaseV4 mDatabase = null; private transient boolean mDecodeRef = false; @@ -45,7 +48,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger { private long usageCount = 0; private PwDate parentGroupLastMod = new PwDate(); private Map customData = new HashMap<>(); - private ExtraFields fields = new ExtraFields(); private HashMap binaries = new HashMap<>(); private String foregroundColor = ""; @@ -53,7 +55,6 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger { private String overrideURL = ""; private AutoType autoType = new AutoType(); private ArrayList history = new ArrayList<>(); - private String url = ""; private String additional = ""; private String tags = ""; @@ -71,8 +72,8 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger { customIcon = source.customIcon; usageCount = source.usageCount; parentGroupLastMod = source.parentGroupLastMod; - // TODO customData - + customData.clear(); + customData.putAll(source.customData); // Add all custom elements in map fields = source.fields; binaries = source.binaries; foregroundColor = source.foregroundColor; @@ -80,12 +81,60 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger { overrideURL = source.overrideURL; autoType = source.autoType; history = source.history; - url = source.url; additional = source.additional; tags = source.tags; } + public PwEntryV4(Parcel in) { + super(in); + customIcon = in.readParcelable(PwIconCustom.class.getClassLoader()); + usageCount = in.readLong(); + parentGroupLastMod = in.readParcelable(PwDate.class.getClassLoader()); + customData = MemUtil.readStringParcelableMap(in); + fields = in.readParcelable(ExtraFields.class.getClassLoader()); + binaries = MemUtil.readStringParcelableMap(in, ProtectedBinary.class); + foregroundColor = in.readString(); + backgroupColor = in.readString(); + overrideURL = in.readString(); + autoType = in.readParcelable(AutoType.class.getClassLoader()); + history = in.readArrayList(PwEntryV4.class.getClassLoader()); // TODO verify + url = in.readString(); + additional = in.readString(); + tags = in.readString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeParcelable(customIcon, flags); + dest.writeLong(usageCount); + dest.writeParcelable(parentGroupLastMod, flags); + MemUtil.writeStringParcelableMap(dest, customData); + dest.writeParcelable(fields, flags); + MemUtil.writeStringParcelableMap(dest, flags, binaries); + dest.writeString(foregroundColor); + dest.writeString(backgroupColor); + dest.writeString(overrideURL); + dest.writeParcelable(autoType, flags); + dest.writeList(history); + dest.writeString(url); + dest.writeString(additional); + dest.writeString(tags); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwEntryV4 createFromParcel(Parcel in) { + return new PwEntryV4(in); + } + + @Override + public PwEntryV4[] newArray(int size) { + return new PwEntryV4[size]; + } + }; + @SuppressWarnings("unchecked") @Override public PwEntryV4 clone() { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java index 46731a015..95237eefd 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwGroup.java @@ -19,6 +19,8 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + import java.util.ArrayList; import java.util.List; @@ -27,8 +29,24 @@ public abstract class PwGroup childGroups = new ArrayList<>(); - protected List childEntries = new ArrayList<>(); + // TODO verify children not needed + transient protected List childGroups = new ArrayList<>(); + transient protected List childEntries = new ArrayList<>(); + + protected PwGroup() { + super(); + } + + protected PwGroup(Parcel in) { + super(in); + name = in.readString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeString(name); + } @Override public PwGroup clone() { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupId.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupId.java index 5e8f6013d..b5c261673 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupId.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupId.java @@ -19,8 +19,20 @@ */ package com.kunzisoft.keepass.database; -import java.io.Serializable; +import android.os.Parcel; +import android.os.Parcelable; -public abstract class PwGroupId implements Serializable { +public abstract class PwGroupId implements Parcelable { + public PwGroupId() {} + + public PwGroupId(Parcel in) {} + + @Override + public void writeToParcel(Parcel dest, int flags) {} + + @Override + public int describeContents() { + return 0; + } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java index 1a12baa46..24cb9126f 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV3.java @@ -19,13 +19,39 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + public class PwGroupIdV3 extends PwGroupId { private int id; - public PwGroupIdV3(int i) { - id = i; + public PwGroupIdV3(int groupId) { + super(); + this.id = groupId; } + + public PwGroupIdV3(Parcel in) { + super(in); + id = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(id); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwGroupIdV3 createFromParcel(Parcel in) { + return new PwGroupIdV3(in); + } + + @Override + public PwGroupIdV3[] newArray(int size) { + return new PwGroupIdV3[size]; + } + }; @Override public boolean equals(Object compare) { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java index abc158f56..0617e5dd8 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupIdV4.java @@ -19,15 +19,42 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + import java.util.UUID; public class PwGroupIdV4 extends PwGroupId { + private UUID uuid; - public PwGroupIdV4(UUID u) { - uuid = u; + public PwGroupIdV4(UUID uuid) { + super(); + this.uuid = uuid; } - + + public PwGroupIdV4(Parcel in) { + super(in); + uuid = (UUID) in.readSerializable(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeSerializable(uuid); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwGroupIdV4 createFromParcel(Parcel in) { + return new PwGroupIdV4(in); + } + + @Override + public PwGroupIdV4[] newArray(int size) { + return new PwGroupIdV4[size]; + } + }; + @Override public boolean equals(Object id) { if ( ! (id instanceof PwGroupIdV4) ) { @@ -36,12 +63,12 @@ public class PwGroupIdV4 extends PwGroupId { PwGroupIdV4 v4 = (PwGroupIdV4) id; return uuid.equals(v4.uuid); } - + @Override public int hashCode() { return uuid.hashCode(); } - + public UUID getId() { return uuid; } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java index 9f1161bc4..5b14cac7e 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV3.java @@ -20,19 +20,13 @@ package com.kunzisoft.keepass.database; -/** - * @author Brian Pellin - * @author Naomaru Itoi - * @author Bill Zwicky - * @author Dominik Reichl - */ +import android.os.Parcel; + public class PwGroupV3 extends PwGroup { // for tree traversing private int groupId; - private int level = 0; // short - /** Used by KeePass internally, don't use */ private int flags; @@ -40,6 +34,33 @@ public class PwGroupV3 extends PwGroup { super(); } + public PwGroupV3(Parcel in) { + super(in); + groupId = in.readInt(); + level = in.readInt(); + flags = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(groupId); + dest.writeInt(level); + dest.writeInt(flags); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwGroupV3 createFromParcel(Parcel in) { + return new PwGroupV3(in); + } + + @Override + public PwGroupV3[] newArray(int size) { + return new PwGroupV3[size]; + } + }; + public PwGroupV3(PwGroupV3 p) { construct(p); } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java index f339970f5..c65d88e8d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwGroupV4.java @@ -19,6 +19,10 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + +import com.kunzisoft.keepass.utils.MemUtil; + import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -32,9 +36,7 @@ public class PwGroupV4 extends PwGroup implemen private long usageCount = 0; private PwDate parentGroupLastMod = new PwDate(); private Map customData = new HashMap<>(); - private boolean expires = false; - private String notes = ""; private boolean isExpanded = true; private String defaultAutoTypeSequence = ""; @@ -57,6 +59,53 @@ public class PwGroupV4 extends PwGroup implemen this.icon = icon; } + public PwGroupV4(Parcel in) { + super(in); + uuid = (UUID) in.readSerializable(); + customIcon = in.readParcelable(PwIconCustom.class.getClassLoader()); + usageCount = in.readLong(); + parentGroupLastMod = in.readParcelable(PwDate.class.getClassLoader()); + customData = MemUtil.readStringParcelableMap(in); + expires = in.readByte() != 0; + notes = in.readString(); + isExpanded = in.readByte() != 0; + defaultAutoTypeSequence = in.readString(); + byte autoTypeByte = in.readByte(); + enableAutoType = (autoTypeByte == -1) ? null : autoTypeByte != 0; + byte enableSearchingByte = in.readByte(); + enableSearching = (enableSearchingByte == -1) ? null : enableSearchingByte != 0; + lastTopVisibleEntry = (UUID) in.readSerializable(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeSerializable(uuid); + dest.writeParcelable(customIcon, flags); + dest.writeLong(usageCount); + dest.writeParcelable(parentGroupLastMod, flags); + MemUtil.writeStringParcelableMap(dest, customData); + dest.writeByte((byte) (expires ? 1 : 0)); + dest.writeString(notes); + dest.writeByte((byte) (isExpanded ? 1 : 0)); + dest.writeString(defaultAutoTypeSequence); + dest.writeByte((byte) (enableAutoType == null ? -1 : (enableAutoType ? 1 : 0))); + dest.writeByte((byte) (enableAutoType == null ? -1 : (enableAutoType ? 1 : 0))); + dest.writeSerializable(lastTopVisibleEntry); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwGroupV4 createFromParcel(Parcel in) { + return new PwGroupV4(in); + } + + @Override + public PwGroupV4[] newArray(int size) { + return new PwGroupV4[size]; + } + }; + protected void updateWith(PwGroupV4 source) { super.assign(source); uuid = source.uuid; diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwIcon.java b/app/src/main/java/com/kunzisoft/keepass/database/PwIcon.java index 65beb86db..bd8f37a6b 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwIcon.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwIcon.java @@ -19,11 +19,21 @@ */ package com.kunzisoft.keepass.database; -import java.io.Serializable; +import android.os.Parcel; +import android.os.Parcelable; -public abstract class PwIcon implements Serializable { +public abstract class PwIcon implements Parcelable { public boolean isMetaStreamIcon() { return false; } + + protected PwIcon() {} + + protected PwIcon(Parcel in) {} + + @Override + public int describeContents() { + return 0; + } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java b/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java index cb1a8fb39..7299037d3 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwIconCustom.java @@ -19,6 +19,8 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + import java.util.UUID; public class PwIconCustom extends PwIcon { @@ -27,16 +29,42 @@ public class PwIconCustom extends PwIcon { public final UUID uuid; public byte[] imageData; - public PwIconCustom(UUID u, byte[] data) { - uuid = u; - imageData = data; + public PwIconCustom(UUID uuid, byte[] data) { + super(); + this.uuid = uuid; + this.imageData = data; } public PwIconCustom(PwIconCustom icon) { + super(); uuid = icon.uuid; imageData = icon.imageData; } + protected PwIconCustom(Parcel in) { + super(in); + uuid = (UUID) in.readSerializable(); + in.readByteArray(imageData); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeSerializable(uuid); + dest.writeByteArray(imageData); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwIconCustom createFromParcel(Parcel in) { + return new PwIconCustom(in); + } + + @Override + public PwIconCustom[] newArray(int size) { + return new PwIconCustom[size]; + } + }; + @Override public int hashCode() { final int prime = 31; @@ -55,10 +83,7 @@ public class PwIconCustom extends PwIcon { return false; PwIconCustom other = (PwIconCustom) obj; if (uuid == null) { - if (other.uuid != null) - return false; - } else if (!uuid.equals(other.uuid)) - return false; - return true; + return other.uuid == null; + } else return uuid.equals(other.uuid); } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java b/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java index a077a2e34..961eff1bb 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwIconStandard.java @@ -19,6 +19,8 @@ */ package com.kunzisoft.keepass.database; +import android.os.Parcel; + public class PwIconStandard extends PwIcon { public final int iconId; @@ -34,6 +36,28 @@ public class PwIconStandard extends PwIcon { this.iconId = icon.iconId; } + protected PwIconStandard(Parcel in) { + super(in); + iconId = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(iconId); + } + + public static final Creator CREATOR = new Creator() { + @Override + public PwIconStandard createFromParcel(Parcel in) { + return new PwIconStandard(in); + } + + @Override + public PwIconStandard[] newArray(int size) { + return new PwIconStandard[size]; + } + }; + @Override public boolean isMetaStreamIcon() { return iconId == 0; diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java b/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java index c2cd365ba..5080afcc1 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwNode.java @@ -20,33 +20,69 @@ */ package com.kunzisoft.keepass.database; -import org.joda.time.LocalDate; +import android.os.Parcel; +import android.os.Parcelable; -import java.io.Serializable; +import com.kunzisoft.keepass.app.App; + +import org.joda.time.LocalDate; /** * Abstract class who manage Groups and Entries */ -public abstract class PwNode implements ISmallTimeLogger, Serializable, Cloneable { +public abstract class PwNode implements ISmallTimeLogger, Parcelable, Cloneable { protected Parent parent = null; - protected PwIconStandard icon = new PwIconStandard(0); - protected PwDate creation = new PwDate(); protected PwDate lastMod = new PwDate(); protected PwDate lastAccess = new PwDate(); protected PwDate expireDate = PwDate.PW_NEVER_EXPIRE; + protected PwNode() {} + + protected PwNode(Parcel in) { + // TODO better technique ? + try { + PwGroupId pwGroupId = in.readParcelable(PwGroupId.class.getClassLoader()); + parent = (Parent) App.getDB().getPwDatabase().getGroupByGroupId(pwGroupId); + } catch (Exception e) { + e.printStackTrace(); + } + + icon = in.readParcelable(PwIconStandard.class.getClassLoader()); + creation = in.readParcelable(PwDate.class.getClassLoader()); + lastMod = in.readParcelable(PwDate.class.getClassLoader()); + lastAccess = in.readParcelable(PwDate.class.getClassLoader()); + expireDate = in.readParcelable(PwDate.class.getClassLoader()); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + PwGroupId parentId = null; + if (parent != null) + parentId = parent.getId(); + dest.writeParcelable(parentId, flags); + + dest.writeParcelable(icon, flags); + dest.writeParcelable(creation, flags); + dest.writeParcelable(lastMod, flags); + dest.writeParcelable(lastAccess, flags); + dest.writeParcelable(expireDate, flags); + } + + @Override + public int describeContents() { + return 0; + } + protected void construct(Parent parent) { this.parent = parent; } protected void assign(PwNode source) { this.parent = source.parent; - this.icon = source.icon; - this.creation = source.creation; this.lastMod = source.lastMod; this.lastAccess = source.lastAccess; @@ -59,9 +95,7 @@ public abstract class PwNode implements ISmallTimeLogger try { newNode = (PwNode) super.clone(); // newNode.parent stay the same in copy - newNode.icon = new PwIconStandard(this.icon); - newNode.creation = creation.clone(); newNode.lastMod = lastMod.clone(); newNode.lastAccess = lastAccess.clone(); diff --git a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java index f73024d92..463b7b604 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java @@ -19,15 +19,17 @@ */ package com.kunzisoft.keepass.database.security; -import java.io.Serializable; +import android.os.Parcel; +import android.os.Parcelable; + import java.util.Arrays; -public class ProtectedBinary implements Serializable { +public class ProtectedBinary implements Parcelable { public final static ProtectedBinary EMPTY = new ProtectedBinary(); - - private byte[] data; + private boolean protect; + private byte[] data; public boolean isProtected() { return protect; @@ -37,21 +39,22 @@ public class ProtectedBinary implements Serializable { if (data == null) { return 0; } - return data.length; } public ProtectedBinary() { this(false, new byte[0]); - } public ProtectedBinary(boolean enableProtection, byte[] data) { - protect = enableProtection; + this.protect = enableProtection; this.data = data; - } - + + public ProtectedBinary(Parcel in) { + protect = in.readByte() != 0; + in.readByteArray(data); + } // TODO: replace the byte[] with something like ByteBuffer to make the return // value immutable, so we don't have to worry about making deep copies @@ -63,4 +66,27 @@ public class ProtectedBinary implements Serializable { return (protect == rhs.protect) && Arrays.equals(data, rhs.data); } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (protect ? 1 : 0)); + dest.writeByteArray(data); + } + + public static final Creator CREATOR = new Creator() { + @Override + public ProtectedBinary createFromParcel(Parcel in) { + return new ProtectedBinary(in); + } + + @Override + public ProtectedBinary[] newArray(int size) { + return new ProtectedBinary[size]; + } + }; + } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedString.java b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedString.java index a5d925535..c0decee4a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedString.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedString.java @@ -19,38 +19,66 @@ */ package com.kunzisoft.keepass.database.security; -import java.io.Serializable; +import android.os.Parcel; +import android.os.Parcelable; + +public class ProtectedString implements Parcelable { -public class ProtectedString implements Serializable { - - private String string; private boolean protect; - - public boolean isProtected() { - return protect; - } - - public int length() { - if (string == null) { - return 0; - } - - return string.length(); - } + private String string; public ProtectedString() { this(false, ""); } public ProtectedString(ProtectedString toCopy) { - this.string = toCopy.string; this.protect = toCopy.protect; + this.string = toCopy.string; } public ProtectedString(boolean enableProtection, String string) { - protect = enableProtection; + this.protect = enableProtection; this.string = string; - + } + + public ProtectedString(Parcel in) { + protect = in.readByte() != 0; + string = in.readString(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeByte((byte) (protect ? 1 : 0)); + dest.writeString(string); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public ProtectedString createFromParcel(Parcel in) { + return new ProtectedString(in); + } + + @Override + public ProtectedString[] newArray(int size) { + return new ProtectedString[size]; + } + }; + + public boolean isProtected() { + return protect; + } + + public int length() { + if (string == null) { + return 0; + } + + return string.length(); } @Override diff --git a/app/src/main/java/com/kunzisoft/keepass/dialogs/GroupEditDialogFragment.java b/app/src/main/java/com/kunzisoft/keepass/dialogs/GroupEditDialogFragment.java index 39f3724d8..ac1bbbf6d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/dialogs/GroupEditDialogFragment.java +++ b/app/src/main/java/com/kunzisoft/keepass/dialogs/GroupEditDialogFragment.java @@ -79,7 +79,7 @@ public class GroupEditDialogFragment extends DialogFragment public static GroupEditDialogFragment build(PwNode group) { Bundle bundle = new Bundle(); bundle.putString(KEY_NAME, group.getDisplayTitle()); - bundle.putSerializable(KEY_ICON_ID, group.getIcon()); + bundle.putParcelable(KEY_ICON_ID, group.getIcon()); bundle.putInt(KEY_ACTION_ID, UPDATE.ordinal()); GroupEditDialogFragment fragment = new GroupEditDialogFragment(); fragment.setArguments(bundle); @@ -125,7 +125,7 @@ public class GroupEditDialogFragment extends DialogFragment && savedInstanceState.containsKey(KEY_ICON_ID)) { editGroupDialogAction = getActionFromOrdinal(savedInstanceState.getInt(KEY_ACTION_ID)); nameGroup = savedInstanceState.getString(KEY_NAME); - iconGroup = (PwIcon) savedInstanceState.getSerializable(KEY_ICON_ID); + iconGroup = savedInstanceState.getParcelable(KEY_ICON_ID); } else { @@ -137,7 +137,7 @@ public class GroupEditDialogFragment extends DialogFragment && getArguments().containsKey(KEY_NAME) && getArguments().containsKey(KEY_ICON_ID)) { nameGroup = getArguments().getString(KEY_NAME); - iconGroup = (PwIcon) getArguments().getSerializable(KEY_ICON_ID); + iconGroup = getArguments().getParcelable(KEY_ICON_ID); } } @@ -206,7 +206,7 @@ public class GroupEditDialogFragment extends DialogFragment public void onSaveInstanceState(Bundle outState) { outState.putInt(KEY_ACTION_ID, editGroupDialogAction.ordinal()); outState.putString(KEY_NAME, nameGroup); - outState.putSerializable(KEY_ICON_ID, iconGroup); + outState.putParcelable(KEY_ICON_ID, iconGroup); super.onSaveInstanceState(outState); } diff --git a/app/src/main/java/com/kunzisoft/keepass/search/SearchResultsActivity.java b/app/src/main/java/com/kunzisoft/keepass/search/SearchResultsActivity.java index 4d081f474..c70e04ef1 100644 --- a/app/src/main/java/com/kunzisoft/keepass/search/SearchResultsActivity.java +++ b/app/src/main/java/com/kunzisoft/keepass/search/SearchResultsActivity.java @@ -30,6 +30,7 @@ import android.view.View; import com.kunzisoft.keepass.R; import com.kunzisoft.keepass.activities.ListNodesActivity; +import com.kunzisoft.keepass.activities.ListNodesFragment; import com.kunzisoft.keepass.app.App; import com.kunzisoft.keepass.database.Database; import com.kunzisoft.keepass.database.PwGroup; @@ -67,6 +68,15 @@ public class SearchResultsActivity extends ListNodesActivity { } } + @Override + protected void initializeListNodesFragment(PwGroup currentGroup) { + listNodesFragment = (ListNodesFragment) getSupportFragmentManager() + .findFragmentByTag(LIST_NODES_FRAGMENT_TAG); + // Directly get group and not id + if (listNodesFragment == null) + listNodesFragment = ListNodesFragment.newInstance(currentGroup); + } + @Override protected PwGroup retrieveCurrentGroup(@Nullable Bundle savedInstanceState) { Database mDb = App.getDB(); diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java b/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java index c39c2885d..92e516e86 100644 --- a/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java +++ b/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java @@ -19,9 +19,14 @@ */ package com.kunzisoft.keepass.utils; +import android.os.Parcel; +import android.os.Parcelable; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -47,4 +52,68 @@ public class MemUtil { return baos.toByteArray(); } + // For writing to a Parcel + public static void writeParcelableMap( + Parcel parcel, int flags, Map map) { + parcel.writeInt(map.size()); + for(Map.Entry e : map.entrySet()){ + parcel.writeParcelable(e.getKey(), flags); + parcel.writeParcelable(e.getValue(), flags); + } + } + + // For reading from a Parcel + public static Map readParcelableMap( + Parcel parcel, Class kClass, Class vClass) { + int size = parcel.readInt(); + Map map = new HashMap(size); + for(int i = 0; i < size; i++){ + map.put(kClass.cast(parcel.readParcelable(kClass.getClassLoader())), + vClass.cast(parcel.readParcelable(vClass.getClassLoader()))); + } + return map; + } + + // For writing map with string key to a Parcel + public static void writeStringParcelableMap( + Parcel parcel, int flags, Map map) { + parcel.writeInt(map.size()); + for(Map.Entry e : map.entrySet()){ + parcel.writeString(e.getKey()); + parcel.writeParcelable(e.getValue(), flags); + } + } + + // For reading map with string key from a Parcel + public static HashMap readStringParcelableMap( + Parcel parcel, Class vClass) { + int size = parcel.readInt(); + HashMap map = new HashMap<>(size); + for(int i = 0; i < size; i++){ + map.put(parcel.readString(), + vClass.cast(parcel.readParcelable(vClass.getClassLoader()))); + } + return map; + } + + + // For writing map with string key and string value to a Parcel + public static void writeStringParcelableMap(Parcel dest, Map map) { + dest.writeInt(map.size()); + for(Map.Entry e : map.entrySet()){ + dest.writeString(e.getKey()); + dest.writeString(e.getValue()); + } + } + + // For reading map with string key and string value from a Parcel + public static HashMap readStringParcelableMap(Parcel in) { + int size = in.readInt(); + HashMap map = new HashMap<>(size); + for(int i = 0; i < size; i++){ + map.put(in.readString(), + in.readString()); + } + return map; + } } diff --git a/fastlane/metadata/android/en-US/changelogs/14.txt b/fastlane/metadata/android/en-US/changelogs/14.txt new file mode 100644 index 000000000..fc926781c --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/14.txt @@ -0,0 +1,7 @@ + * Added the Magikeyboard to fill the forms + * Added move and copy for groups and entries + * New navigation in a single screen / new animations between activities + * New icons for the material pack + * New adaptive launcher icon + * Added a setting to disable the open button / the education screens / the copy of protected custom fields + * Fix the fingerprint recognition / crash / search / parcelables \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/changelogs/14.txt b/fastlane/metadata/android/fr-FR/changelogs/14.txt new file mode 100644 index 000000000..c79222a18 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/14.txt @@ -0,0 +1,7 @@ + * Ajout du Magikeyboard pour remplir les formulaires + * Déplacer et copier ajoutés pour les groupes et les entrées + * Nouvelle navigation dans un seul écran / nouvelles animations entre activités + * Nouveaux icones pour le pack material + * Nouvel icone de lancement adaptatif + * Ajout d'un paramètre pour désactiver le bouton d'ouverture / les écrans d'éducation / la copie des champs customisés protégés + * Correction de la reconnaissance des empreintes digitales / crash / recherche / parcelables \ No newline at end of file diff --git a/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java b/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java index 18c3eb59f..8ae649b93 100644 --- a/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java +++ b/magikeyboard/src/main/java/com/kunzisoft/magikeyboard/MagikIME.java @@ -98,10 +98,14 @@ public class MagikIME extends InputMethodService } private void assignKeyboardView() { - if (entryKey != null) { - keyboardView.setKeyboard(keyboard_entry); - } else { - keyboardView.setKeyboard(keyboard); + if (keyboardView != null) { + if (entryKey != null) { + if (keyboard_entry != null) + keyboardView.setKeyboard(keyboard_entry); + } else { + if (keyboard != null) + keyboardView.setKeyboard(keyboard); + } } }