diff --git a/briar-android/res/layout/list_item_contact.xml b/briar-android/res/layout/list_item_contact.xml index 78f0681bdd2397f0326262a28ab718ea322031f4..8f879c90a041b99df3882897e259ba47db12e6b0 100644 --- a/briar-android/res/layout/list_item_contact.xml +++ b/briar-android/res/layout/list_item_contact.xml @@ -80,6 +80,6 @@ </RelativeLayout> - <View style="@style/Divider.ContactListDevider"/> + <View style="@style/Divider.ContactList"/> </LinearLayout> \ No newline at end of file diff --git a/briar-android/res/layout/list_item_introduction_in.xml b/briar-android/res/layout/list_item_introduction_in.xml index 08da32d7784cefedac3c3d9aa00eca01fb6e47ba..5daea060852a74a324f23c79cd851ad1fee3ea7a 100644 --- a/briar-android/res/layout/list_item_introduction_in.xml +++ b/briar-android/res/layout/list_item_introduction_in.xml @@ -34,8 +34,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/message_bubble_timestamp_margin" - android:layout_alignEnd="@+id/acceptButton" - android:layout_alignRight="@+id/acceptButton" + android:layout_alignEnd="@+id/introductionText" + android:layout_alignRight="@+id/introductionText" android:layout_below="@+id/acceptButton" android:textColor="@color/private_message_date" android:textSize="@dimen/text_size_tiny" diff --git a/briar-android/res/layout/list_item_introduction_out.xml b/briar-android/res/layout/list_item_introduction_out.xml index d3e1a85aa633167d6e235d72199b87998524d0ce..88070ea669ea57ab6402247f6c18cebae68eecb9 100644 --- a/briar-android/res/layout/list_item_introduction_out.xml +++ b/briar-android/res/layout/list_item_introduction_out.xml @@ -23,7 +23,6 @@ android:id="@+id/introductionText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:minWidth="175dp" android:textIsSelectable="true" android:textSize="@dimen/text_size_medium" android:textStyle="italic" diff --git a/briar-android/res/layout/list_item_notice_in.xml b/briar-android/res/layout/list_item_notice_in.xml index e7c912f9151ee2b45ef0520d8ca51cd415744e08..8f0daa0267b56790c8e1e9d4397ad01ae9819f13 100644 --- a/briar-android/res/layout/list_item_notice_in.xml +++ b/briar-android/res/layout/list_item_notice_in.xml @@ -14,7 +14,6 @@ android:id="@+id/noticeText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:minWidth="80dp" android:textIsSelectable="true" android:textSize="@dimen/text_size_medium" android:textStyle="italic" diff --git a/briar-android/res/menu/conversation_actions.xml b/briar-android/res/menu/conversation_actions.xml index 01090aaec6156de99a48133f0bac428ed52f1e9a..0128ee56f42686c6db67bb3934aab796cb06ecb0 100644 --- a/briar-android/res/menu/conversation_actions.xml +++ b/briar-android/res/menu/conversation_actions.xml @@ -6,7 +6,7 @@ <item android:id="@+id/action_introduction" android:icon="@drawable/introduction_white" - android:title="@string/make_introduction" + android:title="@string/introduction_button" app:showAsAction="never"/> <item diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index c37fa7ea6b8fbedab751f4180dccd69b6a902fea..b47ee68b8d478ef34ca59df1107eb881abcf119f 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -141,8 +141,9 @@ <string name="transport_lan">Wi-Fi</string> <string name="no_data">No data</string> <string name="unknown_app">an unknown app</string> - <string name="make_introduction">Make Introduction</string> - <string name="introduction_activity_title">Select contact</string> + + <!-- Introduction Client --> + <string name="introduction_activity_title">Select Contact</string> <string name="introduction_message_title">Introduce Contacts</string> <string name="introduction_message_text">You can compose a message that will be sent to %1$s and %2$s along with your introduction:</string> <string name="introduction_message_hint">Type message (optional)</string> @@ -151,10 +152,10 @@ <string name="introduction_response_error">Error when responding to introduction</string> <string name="introduction_warn_different_identities_title">Warning: Different Identities</string> <string name="introduction_warn_different_identities_text">You are trying to introduce two contacts that you have added with different identities. This might reveal that both identities are yours.</string> - <string name="introduction_request_sent">You have introduced %1$s to %2$s.</string> + <string name="introduction_request_sent">You have asked to introduce %1$s to %2$s.</string> <string name="introduction_request_received">%1$s introduced you to %2$s. Do you want to add %2$s to your contact list?</string> <string name="introduction_request_exists_received">%1$s introduced you to %2$s, but %2$s is already in your contact list. Since %1$s might not know that, you can still respond:</string> - <string name="introduction_request_answered_received">%1$s introduced you to %2$s.</string> + <string name="introduction_request_answered_received">%1$s has asked to introduce you to %2$s.</string> <string name="introduction_response_accepted_sent">You accepted the introduction to %1$s.</string> <string name="introduction_response_declined_sent">You declined the introduction to %1$s.</string> <string name="introduction_response_accepted_received">%1$s accepted to be introduced to %2$s.</string> diff --git a/briar-android/res/values/styles.xml b/briar-android/res/values/styles.xml index 9b4ebbf6cae735fdd84b5c244fced4020f4ff8cc..12c1c35971598950fed3e2c806f81038895ae49d 100644 --- a/briar-android/res/values/styles.xml +++ b/briar-android/res/values/styles.xml @@ -99,7 +99,7 @@ <item name="android:layout_height">1px</item> </style> - <style name="Divider.ContactListDevider" parent="Divider"> + <style name="Divider.ContactList" parent="Divider"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">2dp</item> <item name="android:layout_marginLeft">@dimen/margin_large</item> diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index d10a3d31cc0631683cc96e0c52bdc9958ada49fd..2d006e681bea924952b921038a3a5d23a16fdfc9 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -661,11 +661,13 @@ public class ConversationActivity extends BriarActivity runOnDbThread(new Runnable() { @Override public void run() { + long timestamp = System.currentTimeMillis(); + timestamp = Math.max(timestamp, getMinTimestampForNewMessage()); try { if (accept) { - introductionManager.acceptIntroduction(contactId, sessionId); + introductionManager.acceptIntroduction(contactId, sessionId, timestamp); } else { - introductionManager.declineIntroduction(contactId, sessionId); + introductionManager.declineIntroduction(contactId, sessionId, timestamp); } loadMessages(); } catch (DbException e) { diff --git a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java index 7b06c9bd7cb77488039849e7295c1b270bb5a0f7..7646e0cf4e8710952f3650d5dfb94e7c65147efa 100644 --- a/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java +++ b/briar-android/src/org/briarproject/android/introduction/IntroductionMessageFragment.java @@ -180,7 +180,8 @@ public class IntroductionMessageFragment extends BaseFragment { // actually make the introduction try { - introductionManager.makeIntroduction(c1, c2, msg); + long timestamp = System.currentTimeMillis(); + introductionManager.makeIntroduction(c1, c2, msg, timestamp); introductionWasMade = true; postIntroduction(false); } catch (DbException e) { diff --git a/briar-api/src/org/briarproject/api/introduction/IntroductionManager.java b/briar-api/src/org/briarproject/api/introduction/IntroductionManager.java index f83581ed7bab584dc006f85218197a233347ab94..18c5da1c691ef626deb5634194cde763a1730b1f 100644 --- a/briar-api/src/org/briarproject/api/introduction/IntroductionManager.java +++ b/briar-api/src/org/briarproject/api/introduction/IntroductionManager.java @@ -21,20 +21,23 @@ public interface IntroductionManager { /** * sends two initial introduction messages */ - void makeIntroduction(Contact c1, Contact c2, String msg) + void makeIntroduction(Contact c1, Contact c2, String msg, + final long timestamp) throws DbException, FormatException; /** * Accept an introduction that had been made */ void acceptIntroduction(final ContactId contactId, - final SessionId sessionId) throws DbException, FormatException; + final SessionId sessionId, final long timestamp) + throws DbException, FormatException; /** * Decline an introduction that had been made */ void declineIntroduction(final ContactId contactId, - final SessionId sessionId) throws DbException, FormatException; + final SessionId sessionId, final long timestamp) + throws DbException, FormatException; /** * Get all introduction messages for the contact with this contactId diff --git a/briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java b/briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java index 8b63ae612bc4705e779b44e503e57e810fed4ccf..38fedd9fb76d9c19083296134fb391ef2f90e86e 100644 --- a/briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java +++ b/briar-api/src/org/briarproject/api/properties/TransportPropertyManager.java @@ -20,6 +20,14 @@ public interface TransportPropertyManager { Map<TransportId, TransportProperties> getLocalProperties() throws DbException; + /** + * Returns the local transport properties for all transports. + * <br/> + * Read-Only + * */ + Map<TransportId, TransportProperties> getLocalProperties(Transaction txn) + throws DbException; + /** Returns the local transport properties for the given transport. */ TransportProperties getLocalProperties(TransportId t) throws DbException; diff --git a/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java b/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java index 6f76540d081a4ef7baf314ead7d9709eccb4c664..bc1e3d5f95c9f4b4431d0aa6fedeea318d84c7ba 100644 --- a/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java +++ b/briar-core/src/org/briarproject/introduction/IntroduceeEngine.java @@ -109,6 +109,7 @@ public class IntroduceeEngine msg.put(E_PUBLIC_KEY, localState.getRaw(OUR_PUBLIC_KEY)); msg.put(TRANSPORT, localAction.getDictionary(TRANSPORT)); } + msg.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME)); messages.add(msg); logAction(currentState, localState, msg); diff --git a/briar-core/src/org/briarproject/introduction/IntroduceeManager.java b/briar-core/src/org/briarproject/introduction/IntroduceeManager.java index 174d2af21ab841f577b689eec6a83680100d52b4..64af33b44d59cd2f8ff89d194cefb9fb7e97ae7d 100644 --- a/briar-core/src/org/briarproject/introduction/IntroduceeManager.java +++ b/briar-core/src/org/briarproject/introduction/IntroduceeManager.java @@ -52,6 +52,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.E_PUBLIC_K import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID; import static org.briarproject.api.introduction.IntroductionConstants.INTRODUCER; import static org.briarproject.api.introduction.IntroductionConstants.LOCAL_AUTHOR_ID; +import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.NAME; import static org.briarproject.api.introduction.IntroductionConstants.NOT_OUR_RESPONSE; import static org.briarproject.api.introduction.IntroductionConstants.OUR_PRIVATE_KEY; @@ -159,9 +160,10 @@ class IntroduceeManager { } public void acceptIntroduction(Transaction txn, final ContactId contactId, - final SessionId sessionId) throws DbException, FormatException { + final SessionId sessionId, final long timestamp) + throws DbException, FormatException { - Contact c = contactManager.getContact(contactId); + Contact c = db.getContact(txn, contactId); Group g = introductionManager.getIntroductionGroup(c); BdfDictionary state = introductionManager @@ -173,7 +175,7 @@ class IntroduceeManager { byte[] publicKey = keyPair.getPublic().getEncoded(); byte[] privateKey = keyPair.getPrivate().getEncoded(); Map<TransportId, TransportProperties> transportProperties = - transportPropertyManager.getLocalProperties(); + transportPropertyManager.getLocalProperties(txn); // update session state for later state.put(ACCEPT, true); @@ -186,6 +188,7 @@ class IntroduceeManager { localAction.put(TYPE, TYPE_RESPONSE); localAction.put(TRANSPORT, encodeTransportProperties(transportProperties)); + localAction.put(MESSAGE_TIME, timestamp); // start engine and process its state update IntroduceeEngine engine = new IntroduceeEngine(); @@ -193,9 +196,10 @@ class IntroduceeManager { } public void declineIntroduction(Transaction txn, final ContactId contactId, - final SessionId sessionId) throws DbException, FormatException { + final SessionId sessionId, final long timestamp) + throws DbException, FormatException { - Contact c = contactManager.getContact(contactId); + Contact c = db.getContact(txn, contactId); Group g = introductionManager.getIntroductionGroup(c); BdfDictionary state = introductionManager @@ -207,6 +211,7 @@ class IntroduceeManager { // define action BdfDictionary localAction = new BdfDictionary(); localAction.put(TYPE, TYPE_RESPONSE); + localAction.put(MESSAGE_TIME, timestamp); // start engine and process its state update IntroduceeEngine engine = new IntroduceeEngine(); diff --git a/briar-core/src/org/briarproject/introduction/IntroducerEngine.java b/briar-core/src/org/briarproject/introduction/IntroducerEngine.java index fb88c28df61de2cb1d8bb1a1eedbd0e2cf62a14e..796d528f1d09b5fb9b49963fef8a732efbcb25de 100644 --- a/briar-core/src/org/briarproject/introduction/IntroducerEngine.java +++ b/briar-core/src/org/briarproject/introduction/IntroducerEngine.java @@ -56,6 +56,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.RESPONSE_1 import static org.briarproject.api.introduction.IntroductionConstants.RESPONSE_2; import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID; import static org.briarproject.api.introduction.IntroductionConstants.STATE; +import static org.briarproject.api.introduction.IntroductionConstants.TIME; import static org.briarproject.api.introduction.IntroductionConstants.TYPE; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ACK; @@ -104,6 +105,7 @@ public class IntroducerEngine if (localAction.containsKey(MSG)) { msg1.put(MSG, localAction.getString(MSG)); } + msg1.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME)); messages.add(msg1); logLocalAction(currentState, localState, msg1); BdfDictionary msg2 = new BdfDictionary(); @@ -115,6 +117,7 @@ public class IntroducerEngine if (localAction.containsKey(MSG)) { msg2.put(MSG, localAction.getString(MSG)); } + msg2.put(MESSAGE_TIME, localAction.getLong(MESSAGE_TIME)); messages.add(msg2); logLocalAction(currentState, localState, msg2); diff --git a/briar-core/src/org/briarproject/introduction/IntroducerManager.java b/briar-core/src/org/briarproject/introduction/IntroducerManager.java index 3cc906aedf32c085c132acd818a1152a773f19e2..93481367df01a89508d541d4ca6be4b21072288d 100644 --- a/briar-core/src/org/briarproject/introduction/IntroducerManager.java +++ b/briar-core/src/org/briarproject/introduction/IntroducerManager.java @@ -30,6 +30,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID import static org.briarproject.api.introduction.IntroductionConstants.CONTACT_ID_2; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_1; import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID_2; +import static org.briarproject.api.introduction.IntroductionConstants.MESSAGE_TIME; import static org.briarproject.api.introduction.IntroductionConstants.MSG; import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY1; import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY2; @@ -38,6 +39,7 @@ import static org.briarproject.api.introduction.IntroductionConstants.ROLE_INTRO import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID; import static org.briarproject.api.introduction.IntroductionConstants.STATE; import static org.briarproject.api.introduction.IntroductionConstants.STORAGE_ID; +import static org.briarproject.api.introduction.IntroductionConstants.TIME; import static org.briarproject.api.introduction.IntroductionConstants.TYPE; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_ABORT; import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST; @@ -99,7 +101,7 @@ class IntroducerManager { } public void makeIntroduction(Transaction txn, Contact c1, Contact c2, - String msg) throws DbException, FormatException { + String msg, long timestamp) throws DbException, FormatException { // TODO check for existing session with those contacts? // deny new introduction under which conditions? @@ -115,6 +117,7 @@ class IntroducerManager { } localAction.put(PUBLIC_KEY1, c1.getAuthor().getPublicKey()); localAction.put(PUBLIC_KEY2, c2.getAuthor().getPublicKey()); + localAction.put(MESSAGE_TIME, timestamp); // start engine and process its state update IntroducerEngine engine = new IntroducerEngine(); diff --git a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java index 30cfe7083f8375c59fed663539a27d3658bb8c32..dbdc0091c4dccbfc0cb5656d0c03bd62296c5e04 100644 --- a/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java +++ b/briar-core/src/org/briarproject/introduction/IntroductionManagerImpl.java @@ -44,7 +44,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; @@ -268,12 +267,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook } @Override - public void makeIntroduction(Contact c1, Contact c2, String msg) + public void makeIntroduction(Contact c1, Contact c2, String msg, + final long timestamp) throws DbException, FormatException { Transaction txn = db.startTransaction(false); try { - introducerManager.makeIntroduction(txn, c1, c2, msg); + introducerManager.makeIntroduction(txn, c1, c2, msg, timestamp); txn.setComplete(); } finally { db.endTransaction(txn); @@ -282,11 +282,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook @Override public void acceptIntroduction(final ContactId contactId, - final SessionId sessionId) throws DbException, FormatException { + final SessionId sessionId, final long timestamp) + throws DbException, FormatException { Transaction txn = db.startTransaction(false); try { - introduceeManager.acceptIntroduction(txn, contactId, sessionId); + introduceeManager + .acceptIntroduction(txn, contactId, sessionId, timestamp); txn.setComplete(); } finally { db.endTransaction(txn); @@ -295,11 +297,13 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook @Override public void declineIntroduction(final ContactId contactId, - final SessionId sessionId) throws DbException, FormatException { + final SessionId sessionId, final long timestamp) + throws DbException, FormatException { Transaction txn = db.startTransaction(false); try { - introduceeManager.declineIntroduction(txn, contactId, sessionId); + introduceeManager + .declineIntroduction(txn, contactId, sessionId, timestamp); txn.setComplete(); } finally { db.endTransaction(txn); @@ -501,9 +505,10 @@ class IntroductionManagerImpl extends BdfIncomingMessageHook byte[] body = clientHelper.toByteArray(bdfList); GroupId groupId = new GroupId(message.getRaw(GROUP_ID)); Group group = db.getGroup(txn, groupId); - long timestamp = System.currentTimeMillis(); - + long timestamp = + message.getLong(MESSAGE_TIME, System.currentTimeMillis()); message.put(MESSAGE_TIME, timestamp); + Metadata metadata = metadataEncoder.encode(message); messageQueueManager diff --git a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java index 5663b6151a823399eaf800f8031bdf2dfd281ea8..71c93b4fd23a84588f59afc557bfec1d0915336a 100644 --- a/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java +++ b/briar-core/src/org/briarproject/properties/TransportPropertyManagerImpl.java @@ -108,6 +108,27 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, return Collections.unmodifiableMap(local); } + @Override + public Map<TransportId, TransportProperties> getLocalProperties( + Transaction txn) throws DbException { + try { + Map<TransportId, TransportProperties> local = + new HashMap<TransportId, TransportProperties>(); + // Find the latest local update for each transport + Map<TransportId, LatestUpdate> latest = findLatest(txn, + localGroup.getId(), true); + // Retrieve and parse the latest local properties + for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) { + BdfList message = clientHelper.getMessageAsList(txn, + e.getValue().messageId); + local.put(e.getKey(), parseProperties(message)); + } + return local; + } catch (FormatException e) { + throw new DbException(e); + } + } + @Override public TransportProperties getLocalProperties(TransportId t) throws DbException { @@ -212,26 +233,6 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, return privateGroupFactory.createPrivateGroup(CLIENT_ID, c); } - private Map<TransportId, TransportProperties> getLocalProperties( - Transaction txn) throws DbException { - try { - Map<TransportId, TransportProperties> local = - new HashMap<TransportId, TransportProperties>(); - // Find the latest local update for each transport - Map<TransportId, LatestUpdate> latest = findLatest(txn, - localGroup.getId(), true); - // Retrieve and parse the latest local properties - for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) { - BdfList message = clientHelper.getMessageAsList(txn, - e.getValue().messageId); - local.put(e.getKey(), parseProperties(message)); - } - return local; - } catch (FormatException e) { - throw new DbException(e); - } - } - private void storeMessage(Transaction txn, GroupId g, TransportId t, TransportProperties p, long version, boolean local, boolean shared) throws DbException {