Add parcelables

This commit is contained in:
J-Jamet
2018-07-15 10:24:30 +02:00
parent 0ade035f43
commit 2ab81ed77c
23 changed files with 679 additions and 110 deletions

View File

@@ -178,7 +178,7 @@ public class EntryEditActivity extends LockingHideActivity
PwDatabase pm = db.getPwDatabase(); PwDatabase pm = db.getPwDatabase();
if ( uuidBytes == null ) { if ( uuidBytes == null ) {
PwGroupId parentId = (PwGroupId) intent.getSerializableExtra(KEY_PARENT); PwGroupId parentId = intent.getParcelableExtra(KEY_PARENT);
PwGroup parent = pm.getGroupByGroupId(parentId); PwGroup parent = pm.getGroupByGroupId(parentId);
mEntry = db.createEntry(parent); mEntry = db.createEntry(parent);
mIsNew = true; mIsNew = true;
@@ -548,7 +548,7 @@ public class EntryEditActivity extends LockingHideActivity
if (mCallbackNewEntry != null) { if (mCallbackNewEntry != null) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
Intent intentEntry = new Intent(); Intent intentEntry = new Intent();
bundle.putSerializable(ADD_OR_UPDATE_ENTRY_KEY, mCallbackNewEntry); bundle.putParcelable(ADD_OR_UPDATE_ENTRY_KEY, mCallbackNewEntry);
intentEntry.putExtras(bundle); intentEntry.putExtras(bundle);
if (mIsNew) { if (mIsNew) {
setResult(ADD_ENTRY_RESULT_CODE, intentEntry); setResult(ADD_ENTRY_RESULT_CODE, intentEntry);

View File

@@ -205,14 +205,14 @@ public class GroupActivity extends ListNodesActivity
if (savedInstanceState != null) { if (savedInstanceState != null) {
if (savedInstanceState.containsKey(OLD_GROUP_TO_UPDATE_KEY)) 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)) { 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()); toolbarPaste.setOnMenuItemClickListener(new OnCopyMenuItemClickListener());
} }
else if (savedInstanceState.containsKey(NODE_TO_MOVE_KEY)) { 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()); toolbarPaste.setOnMenuItemClickListener(new OnMoveMenuItemClickListener());
} }
} }
@@ -234,24 +234,24 @@ public class GroupActivity extends ListNodesActivity
@Override @Override
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable(GROUP_ID_KEY, mCurrentGroup.getId()); outState.putParcelable(GROUP_ID_KEY, mCurrentGroup.getId());
outState.putSerializable(OLD_GROUP_TO_UPDATE_KEY, oldGroupToUpdate); outState.putParcelable(OLD_GROUP_TO_UPDATE_KEY, oldGroupToUpdate);
if (nodeToCopy != null) if (nodeToCopy != null)
outState.putSerializable(NODE_TO_COPY_KEY, nodeToCopy); outState.putParcelable(NODE_TO_COPY_KEY, nodeToCopy);
if (nodeToMove != null) if (nodeToMove != null)
outState.putSerializable(NODE_TO_MOVE_KEY, nodeToMove); outState.putParcelable(NODE_TO_MOVE_KEY, nodeToMove);
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
} }
protected PwGroup retrieveCurrentGroup(@Nullable Bundle savedInstanceState) { protected PwGroup retrieveCurrentGroup(@Nullable Bundle savedInstanceState) {
PwGroupId pwGroupId = null; // TODO Parcelable PwGroupId pwGroupId = null;
if (savedInstanceState != null if (savedInstanceState != null
&& savedInstanceState.containsKey(GROUP_ID_KEY)) { && savedInstanceState.containsKey(GROUP_ID_KEY)) {
pwGroupId = (PwGroupId) savedInstanceState.getSerializable(GROUP_ID_KEY); pwGroupId = savedInstanceState.getParcelable(GROUP_ID_KEY);
} else { } else {
if (getIntent() != null) if (getIntent() != null)
pwGroupId = (PwGroupId) getIntent().getSerializableExtra(GROUP_ID_KEY); pwGroupId = getIntent().getParcelableExtra(GROUP_ID_KEY);
} }
Database db = App.getDB(); Database db = App.getDB();

View File

@@ -52,7 +52,7 @@ public class ListNodesFragment extends StylishFragment implements
public static ListNodesFragment newInstance(PwGroup group) { public static ListNodesFragment newInstance(PwGroup group) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
if (group != null) { if (group != null) {
bundle.putSerializable(GROUP_KEY, group); bundle.putParcelable(GROUP_KEY, group);
} }
ListNodesFragment listNodesFragment = new ListNodesFragment(); ListNodesFragment listNodesFragment = new ListNodesFragment();
listNodesFragment.setArguments(bundle); listNodesFragment.setArguments(bundle);
@@ -62,7 +62,7 @@ public class ListNodesFragment extends StylishFragment implements
public static ListNodesFragment newInstance(PwGroupId groupId) { public static ListNodesFragment newInstance(PwGroupId groupId) {
Bundle bundle=new Bundle(); Bundle bundle=new Bundle();
if (groupId != null) { if (groupId != null) {
bundle.putSerializable(GROUP_ID_KEY, groupId); bundle.putParcelable(GROUP_ID_KEY, groupId);
} }
ListNodesFragment listNodesFragment = new ListNodesFragment(); ListNodesFragment listNodesFragment = new ListNodesFragment();
listNodesFragment.setArguments(bundle); listNodesFragment.setArguments(bundle);
@@ -117,7 +117,7 @@ public class ListNodesFragment extends StylishFragment implements
prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
} }
protected PwGroup initCurrentGroup() { // TODO Change by parcelable protected PwGroup initCurrentGroup() {
Database db = App.getDB(); Database db = App.getDB();
PwGroup root = db.getPwDatabase().getRootGroup(); PwGroup root = db.getPwDatabase().getRootGroup();
@@ -126,11 +126,11 @@ public class ListNodesFragment extends StylishFragment implements
if (getArguments() != null) { if (getArguments() != null) {
// Contains all the group in element // Contains all the group in element
if (getArguments().containsKey(GROUP_KEY)) { if (getArguments().containsKey(GROUP_KEY)) {
currentGroup = (PwGroup) getArguments().getSerializable(GROUP_KEY); currentGroup = getArguments().getParcelable(GROUP_KEY);
} }
// Contains only the group id, so the group must be retrieve // Contains only the group id, so the group must be retrieve
if (getArguments().containsKey(GROUP_ID_KEY)) { if (getArguments().containsKey(GROUP_ID_KEY)) {
PwGroupId pwGroupId = (PwGroupId) getArguments().getSerializable(GROUP_ID_KEY); PwGroupId pwGroupId = getArguments().getParcelable(GROUP_ID_KEY);
if ( pwGroupId != null ) if ( pwGroupId != null )
currentGroup = db.getPwDatabase().getGroupByGroupId(pwGroupId); currentGroup = db.getPwDatabase().getGroupByGroupId(pwGroupId);
} }
@@ -249,7 +249,7 @@ public class ListNodesFragment extends StylishFragment implements
case EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE: case EntryEditActivity.ADD_OR_UPDATE_ENTRY_REQUEST_CODE:
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE || if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE ||
resultCode == EntryEditActivity.UPDATE_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 (newNode != null) {
if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE) if (resultCode == EntryEditActivity.ADD_ENTRY_RESULT_CODE)
mAdapter.addNode(newNode); mAdapter.addNode(newNode);

View File

@@ -19,20 +19,57 @@
*/ */
package com.kunzisoft.keepass.database; 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.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class AutoType implements Cloneable, Serializable { public class AutoType implements Cloneable, Parcelable {
private static final long OBF_OPT_NONE = 0; private static final long OBF_OPT_NONE = 0;
public boolean enabled = true; public boolean enabled = true;
public long obfuscationOptions = OBF_OPT_NONE; public long obfuscationOptions = OBF_OPT_NONE;
public String defaultSequence = ""; public String defaultSequence = "";
private HashMap<String, String> windowSeqPairs = new HashMap<>(); private HashMap<String, String> 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<AutoType> CREATOR = new Parcelable.Creator<AutoType>() {
@Override
public AutoType createFromParcel(Parcel in) {
return new AutoType(in);
}
@Override
public AutoType[] newArray(int size) {
return new AutoType[size];
}
};
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public AutoType clone() { public AutoType clone() {
AutoType auto; AutoType auto;

View File

@@ -19,9 +19,12 @@
*/ */
package com.kunzisoft.keepass.database; 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.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; 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_URL;
import static com.kunzisoft.keepass.database.PwEntryV4.STR_USERNAME; import static com.kunzisoft.keepass.database.PwEntryV4.STR_USERNAME;
public class ExtraFields implements Serializable, Cloneable { public class ExtraFields implements Parcelable, Cloneable {
private Map<String, ProtectedString> fields; private Map<String, ProtectedString> fields;
@@ -40,6 +43,32 @@ public class ExtraFields implements Serializable, Cloneable {
fields = new HashMap<>(); 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<ExtraFields> CREATOR = new Parcelable.Creator<ExtraFields>() {
@Override
public ExtraFields createFromParcel(Parcel in) {
return new ExtraFields(in);
}
@Override
public ExtraFields[] newArray(int size) {
return new ExtraFields[size];
}
};
public boolean containsCustomFields() { public boolean containsCustomFields() {
return !getCustomProtectedFields().keySet().isEmpty(); return !getCustomProtectedFields().keySet().isEmpty();
} }

View File

@@ -19,10 +19,12 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import android.os.Parcelable;
import com.kunzisoft.keepass.app.App; import com.kunzisoft.keepass.app.App;
import com.kunzisoft.keepass.utils.Types; import com.kunzisoft.keepass.utils.Types;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@@ -33,15 +35,14 @@ import java.util.Date;
* @author bpellin * @author bpellin
* *
*/ */
public class PwDate implements Cloneable, Serializable { public class PwDate implements Cloneable, Parcelable {
private static final int DATE_SIZE = 5; private static final int DATE_SIZE = 5;
private boolean cDateBuilt = false; private Date jDate;
private boolean jDateBuilt = false; private boolean jDateBuilt = false;
private Date jDate;
private byte[] cDate; private byte[] cDate;
private boolean cDateBuilt = false;
public static final Date NEVER_EXPIRE = getNeverExpire(); public static final Date NEVER_EXPIRE = getNeverExpire();
public static final Date DEFAULT_DATE = getDefaultDate(); public static final Date DEFAULT_DATE = getDefaultDate();
@@ -93,6 +94,38 @@ public class PwDate implements Cloneable, Serializable {
jDate = new Date(); jDate = new Date();
jDateBuilt = true; 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<PwDate> CREATOR = new Creator<PwDate>() {
@Override
public PwDate createFromParcel(Parcel in) {
return new PwDate(in);
}
@Override
public PwDate[] newArray(int size) {
return new PwDate[size];
}
};
@Override @Override
public PwDate clone() { public PwDate clone() {

View File

@@ -19,6 +19,8 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import com.kunzisoft.keepass.database.iterator.EntrySearchStringIterator; import com.kunzisoft.keepass.database.iterator.EntrySearchStringIterator;
import com.kunzisoft.keepass.database.security.ProtectedString; import com.kunzisoft.keepass.database.security.ProtectedString;
@@ -30,6 +32,19 @@ public abstract class PwEntry<Parent extends PwGroup> extends PwNode<Parent> {
protected UUID uuid = PwDatabase.UUID_ZERO; 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 @Override
protected void construct(Parent parent) { protected void construct(Parent parent) {
super.construct(parent); super.construct(parent);

View File

@@ -42,6 +42,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.UUID; import java.util.UUID;
@@ -77,13 +79,11 @@ public class PwEntryV3 extends PwEntry<PwGroupV3> {
// TODO Parent ID to remove // TODO Parent ID to remove
private int groupId; private int groupId;
private String title; private String title;
private String username; private String username;
private byte[] password; private byte[] password;
private String url; private String url;
private String additional; private String additional;
/** A string describing what is in pBinaryData */ /** A string describing what is in pBinaryData */
private String binaryDesc; private String binaryDesc;
private byte[] binaryData; private byte[] binaryData;
@@ -97,6 +97,43 @@ public class PwEntryV3 extends PwEntry<PwGroupV3> {
groupId = ((PwGroupIdV3) this.parent.getId()).getId(); // TODO remove 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<PwEntryV3> CREATOR = new Creator<PwEntryV3>() {
@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) { protected void updateWith(PwEntryV3 source) {
super.assign(source); super.assign(source);
groupId = source.groupId; groupId = source.groupId;

View File

@@ -19,8 +19,11 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import com.kunzisoft.keepass.database.security.ProtectedBinary; import com.kunzisoft.keepass.database.security.ProtectedBinary;
import com.kunzisoft.keepass.database.security.ProtectedString; import com.kunzisoft.keepass.database.security.ProtectedString;
import com.kunzisoft.keepass.utils.MemUtil;
import com.kunzisoft.keepass.utils.SprEngineV4; import com.kunzisoft.keepass.utils.SprEngineV4;
import java.util.ArrayList; import java.util.ArrayList;
@@ -37,7 +40,7 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
public static final String STR_URL = "URL"; public static final String STR_URL = "URL";
public static final String STR_NOTES = "Notes"; 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 PwDatabaseV4 mDatabase = null;
private transient boolean mDecodeRef = false; private transient boolean mDecodeRef = false;
@@ -45,7 +48,6 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
private long usageCount = 0; private long usageCount = 0;
private PwDate parentGroupLastMod = new PwDate(); private PwDate parentGroupLastMod = new PwDate();
private Map<String, String> customData = new HashMap<>(); private Map<String, String> customData = new HashMap<>();
private ExtraFields fields = new ExtraFields(); private ExtraFields fields = new ExtraFields();
private HashMap<String, ProtectedBinary> binaries = new HashMap<>(); private HashMap<String, ProtectedBinary> binaries = new HashMap<>();
private String foregroundColor = ""; private String foregroundColor = "";
@@ -53,7 +55,6 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
private String overrideURL = ""; private String overrideURL = "";
private AutoType autoType = new AutoType(); private AutoType autoType = new AutoType();
private ArrayList<PwEntryV4> history = new ArrayList<>(); private ArrayList<PwEntryV4> history = new ArrayList<>();
private String url = ""; private String url = "";
private String additional = ""; private String additional = "";
private String tags = ""; private String tags = "";
@@ -71,8 +72,8 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
customIcon = source.customIcon; customIcon = source.customIcon;
usageCount = source.usageCount; usageCount = source.usageCount;
parentGroupLastMod = source.parentGroupLastMod; parentGroupLastMod = source.parentGroupLastMod;
// TODO customData customData.clear();
customData.putAll(source.customData); // Add all custom elements in map
fields = source.fields; fields = source.fields;
binaries = source.binaries; binaries = source.binaries;
foregroundColor = source.foregroundColor; foregroundColor = source.foregroundColor;
@@ -80,12 +81,60 @@ public class PwEntryV4 extends PwEntry<PwGroupV4> implements ITimeLogger {
overrideURL = source.overrideURL; overrideURL = source.overrideURL;
autoType = source.autoType; autoType = source.autoType;
history = source.history; history = source.history;
url = source.url; url = source.url;
additional = source.additional; additional = source.additional;
tags = source.tags; 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<PwEntryV4> CREATOR = new Creator<PwEntryV4>() {
@Override
public PwEntryV4 createFromParcel(Parcel in) {
return new PwEntryV4(in);
}
@Override
public PwEntryV4[] newArray(int size) {
return new PwEntryV4[size];
}
};
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public PwEntryV4 clone() { public PwEntryV4 clone() {

View File

@@ -19,6 +19,8 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -27,8 +29,24 @@ public abstract class PwGroup<Parent extends PwGroup, ChildGroup extends PwGroup
protected String name = ""; protected String name = "";
protected List<ChildGroup> childGroups = new ArrayList<>(); // TODO verify children not needed
protected List<ChildEntry> childEntries = new ArrayList<>(); transient protected List<ChildGroup> childGroups = new ArrayList<>();
transient protected List<ChildEntry> 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 @Override
public PwGroup clone() { public PwGroup clone() {

View File

@@ -19,8 +19,20 @@
*/ */
package com.kunzisoft.keepass.database; 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;
}
} }

View File

@@ -19,13 +19,39 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
public class PwGroupIdV3 extends PwGroupId { public class PwGroupIdV3 extends PwGroupId {
private int id; private int id;
public PwGroupIdV3(int i) { public PwGroupIdV3(int groupId) {
id = i; 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<PwGroupIdV3> CREATOR = new Creator<PwGroupIdV3>() {
@Override
public PwGroupIdV3 createFromParcel(Parcel in) {
return new PwGroupIdV3(in);
}
@Override
public PwGroupIdV3[] newArray(int size) {
return new PwGroupIdV3[size];
}
};
@Override @Override
public boolean equals(Object compare) { public boolean equals(Object compare) {

View File

@@ -19,15 +19,42 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import java.util.UUID; import java.util.UUID;
public class PwGroupIdV4 extends PwGroupId { public class PwGroupIdV4 extends PwGroupId {
private UUID uuid; private UUID uuid;
public PwGroupIdV4(UUID u) { public PwGroupIdV4(UUID uuid) {
uuid = u; 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<PwGroupIdV4> CREATOR = new Creator<PwGroupIdV4>() {
@Override
public PwGroupIdV4 createFromParcel(Parcel in) {
return new PwGroupIdV4(in);
}
@Override
public PwGroupIdV4[] newArray(int size) {
return new PwGroupIdV4[size];
}
};
@Override @Override
public boolean equals(Object id) { public boolean equals(Object id) {
if ( ! (id instanceof PwGroupIdV4) ) { if ( ! (id instanceof PwGroupIdV4) ) {
@@ -36,12 +63,12 @@ public class PwGroupIdV4 extends PwGroupId {
PwGroupIdV4 v4 = (PwGroupIdV4) id; PwGroupIdV4 v4 = (PwGroupIdV4) id;
return uuid.equals(v4.uuid); return uuid.equals(v4.uuid);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return uuid.hashCode(); return uuid.hashCode();
} }
public UUID getId() { public UUID getId() {
return uuid; return uuid;
} }

View File

@@ -20,19 +20,13 @@
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
/** import android.os.Parcel;
* @author Brian Pellin <bpellin@gmail.com>
* @author Naomaru Itoi <nao@phoneid.org>
* @author Bill Zwicky <wrzwicky@pobox.com>
* @author Dominik Reichl <dominik.reichl@t-online.de>
*/
public class PwGroupV3 extends PwGroup<PwGroupV3, PwGroupV3, PwEntryV3> { public class PwGroupV3 extends PwGroup<PwGroupV3, PwGroupV3, PwEntryV3> {
// for tree traversing // for tree traversing
private int groupId; private int groupId;
private int level = 0; // short private int level = 0; // short
/** Used by KeePass internally, don't use */ /** Used by KeePass internally, don't use */
private int flags; private int flags;
@@ -40,6 +34,33 @@ public class PwGroupV3 extends PwGroup<PwGroupV3, PwGroupV3, PwEntryV3> {
super(); 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<PwGroupV3> CREATOR = new Creator<PwGroupV3>() {
@Override
public PwGroupV3 createFromParcel(Parcel in) {
return new PwGroupV3(in);
}
@Override
public PwGroupV3[] newArray(int size) {
return new PwGroupV3[size];
}
};
public PwGroupV3(PwGroupV3 p) { public PwGroupV3(PwGroupV3 p) {
construct(p); construct(p);
} }

View File

@@ -19,6 +19,10 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import com.kunzisoft.keepass.utils.MemUtil;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@@ -32,9 +36,7 @@ public class PwGroupV4 extends PwGroup<PwGroupV4, PwGroupV4, PwEntryV4> implemen
private long usageCount = 0; private long usageCount = 0;
private PwDate parentGroupLastMod = new PwDate(); private PwDate parentGroupLastMod = new PwDate();
private Map<String, String> customData = new HashMap<>(); private Map<String, String> customData = new HashMap<>();
private boolean expires = false; private boolean expires = false;
private String notes = ""; private String notes = "";
private boolean isExpanded = true; private boolean isExpanded = true;
private String defaultAutoTypeSequence = ""; private String defaultAutoTypeSequence = "";
@@ -57,6 +59,53 @@ public class PwGroupV4 extends PwGroup<PwGroupV4, PwGroupV4, PwEntryV4> implemen
this.icon = icon; 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<PwGroupV4> CREATOR = new Creator<PwGroupV4>() {
@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) { protected void updateWith(PwGroupV4 source) {
super.assign(source); super.assign(source);
uuid = source.uuid; uuid = source.uuid;

View File

@@ -19,11 +19,21 @@
*/ */
package com.kunzisoft.keepass.database; 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() { public boolean isMetaStreamIcon() {
return false; return false;
} }
protected PwIcon() {}
protected PwIcon(Parcel in) {}
@Override
public int describeContents() {
return 0;
}
} }

View File

@@ -19,6 +19,8 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
import java.util.UUID; import java.util.UUID;
public class PwIconCustom extends PwIcon { public class PwIconCustom extends PwIcon {
@@ -27,16 +29,42 @@ public class PwIconCustom extends PwIcon {
public final UUID uuid; public final UUID uuid;
public byte[] imageData; public byte[] imageData;
public PwIconCustom(UUID u, byte[] data) { public PwIconCustom(UUID uuid, byte[] data) {
uuid = u; super();
imageData = data; this.uuid = uuid;
this.imageData = data;
} }
public PwIconCustom(PwIconCustom icon) { public PwIconCustom(PwIconCustom icon) {
super();
uuid = icon.uuid; uuid = icon.uuid;
imageData = icon.imageData; 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<PwIconCustom> CREATOR = new Creator<PwIconCustom>() {
@Override
public PwIconCustom createFromParcel(Parcel in) {
return new PwIconCustom(in);
}
@Override
public PwIconCustom[] newArray(int size) {
return new PwIconCustom[size];
}
};
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@@ -55,10 +83,7 @@ public class PwIconCustom extends PwIcon {
return false; return false;
PwIconCustom other = (PwIconCustom) obj; PwIconCustom other = (PwIconCustom) obj;
if (uuid == null) { if (uuid == null) {
if (other.uuid != null) return other.uuid == null;
return false; } else return uuid.equals(other.uuid);
} else if (!uuid.equals(other.uuid))
return false;
return true;
} }
} }

View File

@@ -19,6 +19,8 @@
*/ */
package com.kunzisoft.keepass.database; package com.kunzisoft.keepass.database;
import android.os.Parcel;
public class PwIconStandard extends PwIcon { public class PwIconStandard extends PwIcon {
public final int iconId; public final int iconId;
@@ -34,6 +36,28 @@ public class PwIconStandard extends PwIcon {
this.iconId = icon.iconId; 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<PwIconStandard> CREATOR = new Creator<PwIconStandard>() {
@Override
public PwIconStandard createFromParcel(Parcel in) {
return new PwIconStandard(in);
}
@Override
public PwIconStandard[] newArray(int size) {
return new PwIconStandard[size];
}
};
@Override @Override
public boolean isMetaStreamIcon() { public boolean isMetaStreamIcon() {
return iconId == 0; return iconId == 0;

View File

@@ -20,33 +20,69 @@
*/ */
package com.kunzisoft.keepass.database; 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 * Abstract class who manage Groups and Entries
*/ */
public abstract class PwNode<Parent extends PwGroup> implements ISmallTimeLogger, Serializable, Cloneable { public abstract class PwNode<Parent extends PwGroup> implements ISmallTimeLogger, Parcelable, Cloneable {
protected Parent parent = null; protected Parent parent = null;
protected PwIconStandard icon = new PwIconStandard(0); protected PwIconStandard icon = new PwIconStandard(0);
protected PwDate creation = new PwDate(); protected PwDate creation = new PwDate();
protected PwDate lastMod = new PwDate(); protected PwDate lastMod = new PwDate();
protected PwDate lastAccess = new PwDate(); protected PwDate lastAccess = new PwDate();
protected PwDate expireDate = PwDate.PW_NEVER_EXPIRE; 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) { protected void construct(Parent parent) {
this.parent = parent; this.parent = parent;
} }
protected void assign(PwNode<Parent> source) { protected void assign(PwNode<Parent> source) {
this.parent = source.parent; this.parent = source.parent;
this.icon = source.icon; this.icon = source.icon;
this.creation = source.creation; this.creation = source.creation;
this.lastMod = source.lastMod; this.lastMod = source.lastMod;
this.lastAccess = source.lastAccess; this.lastAccess = source.lastAccess;
@@ -59,9 +95,7 @@ public abstract class PwNode<Parent extends PwGroup> implements ISmallTimeLogger
try { try {
newNode = (PwNode) super.clone(); newNode = (PwNode) super.clone();
// newNode.parent stay the same in copy // newNode.parent stay the same in copy
newNode.icon = new PwIconStandard(this.icon); newNode.icon = new PwIconStandard(this.icon);
newNode.creation = creation.clone(); newNode.creation = creation.clone();
newNode.lastMod = lastMod.clone(); newNode.lastMod = lastMod.clone();
newNode.lastAccess = lastAccess.clone(); newNode.lastAccess = lastAccess.clone();

View File

@@ -19,15 +19,17 @@
*/ */
package com.kunzisoft.keepass.database.security; package com.kunzisoft.keepass.database.security;
import java.io.Serializable; import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays; import java.util.Arrays;
public class ProtectedBinary implements Serializable { public class ProtectedBinary implements Parcelable {
public final static ProtectedBinary EMPTY = new ProtectedBinary(); public final static ProtectedBinary EMPTY = new ProtectedBinary();
private byte[] data;
private boolean protect; private boolean protect;
private byte[] data;
public boolean isProtected() { public boolean isProtected() {
return protect; return protect;
@@ -37,21 +39,22 @@ public class ProtectedBinary implements Serializable {
if (data == null) { if (data == null) {
return 0; return 0;
} }
return data.length; return data.length;
} }
public ProtectedBinary() { public ProtectedBinary() {
this(false, new byte[0]); this(false, new byte[0]);
} }
public ProtectedBinary(boolean enableProtection, byte[] data) { public ProtectedBinary(boolean enableProtection, byte[] data) {
protect = enableProtection; this.protect = enableProtection;
this.data = data; 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 // 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 // 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); 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<ProtectedBinary> CREATOR = new Creator<ProtectedBinary>() {
@Override
public ProtectedBinary createFromParcel(Parcel in) {
return new ProtectedBinary(in);
}
@Override
public ProtectedBinary[] newArray(int size) {
return new ProtectedBinary[size];
}
};
} }

View File

@@ -19,38 +19,66 @@
*/ */
package com.kunzisoft.keepass.database.security; 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; private boolean protect;
private String string;
public boolean isProtected() {
return protect;
}
public int length() {
if (string == null) {
return 0;
}
return string.length();
}
public ProtectedString() { public ProtectedString() {
this(false, ""); this(false, "");
} }
public ProtectedString(ProtectedString toCopy) { public ProtectedString(ProtectedString toCopy) {
this.string = toCopy.string;
this.protect = toCopy.protect; this.protect = toCopy.protect;
this.string = toCopy.string;
} }
public ProtectedString(boolean enableProtection, String string) { public ProtectedString(boolean enableProtection, String string) {
protect = enableProtection; this.protect = enableProtection;
this.string = string; 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<ProtectedString> CREATOR = new Parcelable.Creator<ProtectedString>() {
@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 @Override

View File

@@ -79,7 +79,7 @@ public class GroupEditDialogFragment extends DialogFragment
public static GroupEditDialogFragment build(PwNode group) { public static GroupEditDialogFragment build(PwNode group) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString(KEY_NAME, group.getDisplayTitle()); 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()); bundle.putInt(KEY_ACTION_ID, UPDATE.ordinal());
GroupEditDialogFragment fragment = new GroupEditDialogFragment(); GroupEditDialogFragment fragment = new GroupEditDialogFragment();
fragment.setArguments(bundle); fragment.setArguments(bundle);
@@ -125,7 +125,7 @@ public class GroupEditDialogFragment extends DialogFragment
&& savedInstanceState.containsKey(KEY_ICON_ID)) { && savedInstanceState.containsKey(KEY_ICON_ID)) {
editGroupDialogAction = getActionFromOrdinal(savedInstanceState.getInt(KEY_ACTION_ID)); editGroupDialogAction = getActionFromOrdinal(savedInstanceState.getInt(KEY_ACTION_ID));
nameGroup = savedInstanceState.getString(KEY_NAME); nameGroup = savedInstanceState.getString(KEY_NAME);
iconGroup = (PwIcon) savedInstanceState.getSerializable(KEY_ICON_ID); iconGroup = savedInstanceState.getParcelable(KEY_ICON_ID);
} else { } else {
@@ -137,7 +137,7 @@ public class GroupEditDialogFragment extends DialogFragment
&& getArguments().containsKey(KEY_NAME) && getArguments().containsKey(KEY_NAME)
&& getArguments().containsKey(KEY_ICON_ID)) { && getArguments().containsKey(KEY_ICON_ID)) {
nameGroup = getArguments().getString(KEY_NAME); 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) { public void onSaveInstanceState(Bundle outState) {
outState.putInt(KEY_ACTION_ID, editGroupDialogAction.ordinal()); outState.putInt(KEY_ACTION_ID, editGroupDialogAction.ordinal());
outState.putString(KEY_NAME, nameGroup); outState.putString(KEY_NAME, nameGroup);
outState.putSerializable(KEY_ICON_ID, iconGroup); outState.putParcelable(KEY_ICON_ID, iconGroup);
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
} }

View File

@@ -19,9 +19,14 @@
*/ */
package com.kunzisoft.keepass.utils; package com.kunzisoft.keepass.utils;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
@@ -47,4 +52,68 @@ public class MemUtil {
return baos.toByteArray(); return baos.toByteArray();
} }
// For writing to a Parcel
public static <K extends Parcelable,V extends Parcelable> void writeParcelableMap(
Parcel parcel, int flags, Map<K, V > map) {
parcel.writeInt(map.size());
for(Map.Entry<K, V> e : map.entrySet()){
parcel.writeParcelable(e.getKey(), flags);
parcel.writeParcelable(e.getValue(), flags);
}
}
// For reading from a Parcel
public static <K extends Parcelable,V extends Parcelable> Map<K,V> readParcelableMap(
Parcel parcel, Class<K> kClass, Class<V> vClass) {
int size = parcel.readInt();
Map<K, V> map = new HashMap<K, V>(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 <V extends Parcelable> void writeStringParcelableMap(
Parcel parcel, int flags, Map<String, V> map) {
parcel.writeInt(map.size());
for(Map.Entry<String, V> e : map.entrySet()){
parcel.writeString(e.getKey());
parcel.writeParcelable(e.getValue(), flags);
}
}
// For reading map with string key from a Parcel
public static <V extends Parcelable> HashMap<String,V> readStringParcelableMap(
Parcel parcel, Class<V> vClass) {
int size = parcel.readInt();
HashMap<String, V> 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<String, String> map) {
dest.writeInt(map.size());
for(Map.Entry<String, String> 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<String, String> readStringParcelableMap(Parcel in) {
int size = in.readInt();
HashMap<String, String> map = new HashMap<>(size);
for(int i = 0; i < size; i++){
map.put(in.readString(),
in.readString());
}
return map;
}
} }