From 33e3aadcc49d83a399f6c7cc2092c0326a70f15b Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Sun, 24 Mar 2019 16:58:12 +0400 Subject: [PATCH] Now chats are correctly creating and not recreating when deleted. --- .../influence/helpers/NetworkHandler.java | 46 ++++++++----------- .../influence/helpers/P2PUtils.java | 34 ++++++++++++++ .../influence/helpers/StorageMVStore.java | 3 +- .../influence/helpers/actions/UIActions.java | 3 +- .../influence/logic/StartChatLogic.java | 19 ++++---- .../models/NewChatRequestMessage.java | 8 +--- .../presenters/StartChatPresenter.java | 9 +--- .../views/fragments/StartChatFragment.java | 14 ++++-- 8 files changed, 78 insertions(+), 58 deletions(-) create mode 100644 app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java b/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java index 8ef2684..ca6001b 100644 --- a/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/NetworkHandler.java @@ -8,6 +8,7 @@ import com.google.gson.JsonParser; import net.tomp2p.dht.FutureGet; import net.tomp2p.dht.FuturePut; +import net.tomp2p.dht.FutureRemove; import net.tomp2p.dht.PeerDHT; import net.tomp2p.futures.FuturePing; import net.tomp2p.peers.Number160; @@ -18,7 +19,6 @@ import net.tomp2p.storage.Data; import java.io.IOException; import java.util.List; import java.util.Map; -import java.util.UUID; import io.github.chronosx88.influence.contracts.observer.NetworkObserver; import io.github.chronosx88.influence.helpers.actions.NetworkActions; @@ -44,32 +44,26 @@ public class NetworkHandler implements NetworkObserver { NewChatRequestMessage newChatRequestMessage = gson.fromJson((String) object, NewChatRequestMessage.class); createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress()); handleIncomingChatRequest(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderPeerAddress()); - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("action", UIActions.NEW_CHAT); - AppHelper.getObservable().notifyUIObservers(jsonObject); + ObservableUtils.notifyUI(UIActions.NEW_CHAT); break; } case NetworkActions.SUCCESSFULL_CREATE_CHAT: { NewChatRequestMessage newChatRequestMessage = gson.fromJson((String) object, NewChatRequestMessage.class); createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress()); - ObservableUtils.notifyUI(UIActions.SUCCESSFULL_CREATE_CHAT); - peerDHT.remove(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingChats")) - .contentKey(Number160.createHash(newChatRequestMessage.getChatID())) - .start() - .awaitUninterruptibly(); + ObservableUtils.notifyUI(UIActions.SUCCESSFUL_CREATE_CHAT); break; } } }).start(); } - private int getMessageAction(String json) { + public static int getMessageAction(String json) { JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject(); return jsonObject.get("action").getAsInt(); } - private static void createChatEntry(String chatID, String name, PeerAddress peerAddress) { + public static void createChatEntry(String chatID, String name, PeerAddress peerAddress) { List chatEntities = AppHelper.getChatDB().chatDao().getChatByChatID(chatID); if (chatEntities.size() > 0) { Log.e(LOG_TAG, "Failed to create chat " + chatID + " because chat exists!"); @@ -79,8 +73,7 @@ public class NetworkHandler implements NetworkObserver { } private void handleIncomingChatRequest(String chatID, PeerAddress chatStarterAddress) { - NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress()); - newChatRequestMessage.setChatID(chatID); + NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(chatID, AppHelper.getPeerID(), peerDHT.peerAddress()); newChatRequestMessage.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT); AppHelper.getPeerDHT().peer().sendDirect(chatStarterAddress).object(gson.toJson(newChatRequestMessage)).start().awaitUninterruptibly(); } @@ -108,15 +101,9 @@ public class NetworkHandler implements NetworkObserver { newChatRequestMessage.getSenderPeerAddress() ); - FuturePing ping = peerDHT - .peer() - .ping() - .peerAddress(newChatRequestMessage.getSenderPeerAddress()) - .start() - .awaitUninterruptibly(); - NewChatRequestMessage newChatRequestReply = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress()); + NewChatRequestMessage newChatRequestReply = new NewChatRequestMessage(newChatRequestMessage.getChatID(), AppHelper.getPeerID(), peerDHT.peerAddress()); newChatRequestReply.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT); - if(ping.isSuccess()) { + if(P2PUtils.ping(newChatRequestMessage.getSenderPeerAddress())) { peerDHT .peer() .sendDirect(newChatRequestMessage.getSenderPeerAddress()) @@ -126,8 +113,7 @@ public class NetworkHandler implements NetworkObserver { } else { try { FuturePut put = peerDHT.put(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingAcceptedChats")) - .data(Number160.createHash(UUID.randomUUID().toString()), new Data(gson.toJson(newChatRequestReply)) - .protectEntry(keyPairManager.openMainKeyPair())) + .data(Number160.createHash(newChatRequestReply.getChatID()), new Data(gson.toJson(newChatRequestReply))) .start() .awaitUninterruptibly(); if(put.isSuccess()) { @@ -138,6 +124,10 @@ public class NetworkHandler implements NetworkObserver { } catch (IOException e) { e.printStackTrace(); } + peerDHT.remove(Number160.createHash(AppHelper.getPeerID() + "_pendingChats")) + .contentKey(Number160.createHash(newChatRequestMessage.getChatID())) + .start() + .awaitUninterruptibly(); } ObservableUtils.notifyUI(UIActions.NEW_CHAT); @@ -162,16 +152,18 @@ public class NetworkHandler implements NetworkObserver { } catch (IOException e) { e.printStackTrace(); } - peerDHT.remove(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingChats")) - .contentKey(Number160.createHash(newChatRequestMessage.getChatID())) - .start() - .awaitUninterruptibly(); createChatEntry( newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress() ); + + FutureRemove remove = peerDHT.remove(Number160.createHash(AppHelper.getPeerID() + "_pendingAcceptedChats")) + .contentKey(Number160.createHash(newChatRequestMessage.getChatID())) + .start() + .awaitUninterruptibly(); + ObservableUtils.notifyUI(UIActions.NEW_CHAT); } } diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java b/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java new file mode 100644 index 0000000..c0b2c36 --- /dev/null +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/P2PUtils.java @@ -0,0 +1,34 @@ +package io.github.chronosx88.influence.helpers; + +import com.google.gson.Gson; + +import net.tomp2p.dht.PeerDHT; +import net.tomp2p.futures.FuturePing; +import net.tomp2p.peers.PeerAddress; + +public class P2PUtils { + private static Gson gson = new Gson(); + private static PeerDHT peerDHT = AppHelper.getPeerDHT(); + + public static boolean ping(PeerAddress recipientPeerAddress) { + // For connection opening + for (int i = 0; i < 2; i++) { + peerDHT + .peer() + .ping() + .tcpPing(true) + .peerAddress(recipientPeerAddress) + .start() + .awaitUninterruptibly(); + } + + FuturePing ping = peerDHT + .peer() + .ping() + .tcpPing(true) + .peerAddress(recipientPeerAddress) + .start() + .awaitUninterruptibly(); + return ping.isSuccess(); + } +} diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/StorageMVStore.java b/app/src/main/java/io/github/chronosx88/influence/helpers/StorageMVStore.java index b16bd27..0599150 100644 --- a/app/src/main/java/io/github/chronosx88/influence/helpers/StorageMVStore.java +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/StorageMVStore.java @@ -325,9 +325,8 @@ public class StorageMVStore implements Storage { private byte[] serializeData(Data data) { - KeyPair mainKeyPair = keyPairManager.openMainKeyPair(); KeyPair forSigningKP = keyPairManager.getKeyPair("mainSigningKeyPair"); - data.sign(forSigningKP).protectEntry(mainKeyPair); + data.sign(forSigningKP); ByteArrayOutputStream out = new ByteArrayOutputStream(); AlternativeCompositeByteBuf acb = AlternativeCompositeByteBuf.compBuffer(AlternativeCompositeByteBuf.UNPOOLED_HEAP); try { diff --git a/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java b/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java index 357e479..459b8ed 100644 --- a/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java +++ b/app/src/main/java/io/github/chronosx88/influence/helpers/actions/UIActions.java @@ -9,6 +9,5 @@ public class UIActions { public static final int BOOTSTRAP_ERROR = 0x5; public static final int NEW_CHAT = 0x6; public static final int PEER_NOT_EXIST = 0x7; - public static final int SUCCESSFULL_CREATE_CHAT = 0x8; - public static final int SUCCESSFULL_CREATE_OFFLINE_CHAT = 0x9; + public static final int SUCCESSFUL_CREATE_CHAT = 0x8; } diff --git a/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java b/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java index b09b801..5ed80f3 100644 --- a/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java +++ b/app/src/main/java/io/github/chronosx88/influence/logic/StartChatLogic.java @@ -19,7 +19,9 @@ import java.util.UUID; import io.github.chronosx88.influence.contracts.startchat.StartChatLogicContract; import io.github.chronosx88.influence.helpers.AppHelper; import io.github.chronosx88.influence.helpers.KeyPairManager; +import io.github.chronosx88.influence.helpers.NetworkHandler; import io.github.chronosx88.influence.helpers.ObservableUtils; +import io.github.chronosx88.influence.helpers.P2PUtils; import io.github.chronosx88.influence.helpers.actions.UIActions; import io.github.chronosx88.influence.models.NewChatRequestMessage; import io.github.chronosx88.influence.models.PublicUserProfile; @@ -41,23 +43,19 @@ public class StartChatLogic implements StartChatLogicContract { new Thread(() -> { PublicUserProfile recipientPublicProfile = getPublicProfile(peerID); if(recipientPublicProfile == null) { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("action", UIActions.PEER_NOT_EXIST); - AppHelper.getObservable().notifyUIObservers(jsonObject); + ObservableUtils.notifyUI(UIActions.PEER_NOT_EXIST); return; } PeerAddress recipientPeerAddress = getPublicProfile(peerID).getPeerAddress(); - FuturePing ping = peerDHT.peer().ping().peerAddress(recipientPeerAddress).start().awaitUninterruptibly(); - if(ping.isSuccess()) { - peerDHT.peer().sendDirect(recipientPeerAddress).object(gson.toJson(new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress()))).start(); + NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(UUID.randomUUID().toString(), AppHelper.getPeerID(), peerDHT.peerAddress()); + if(P2PUtils.ping(recipientPeerAddress)) { + peerDHT.peer().sendDirect(recipientPeerAddress).object(gson.toJson(newChatRequestMessage)).start().awaitUninterruptibly(); } else { try { - NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress()); FuturePut futurePut = peerDHT .put(Number160.createHash(peerID + "_pendingChats")) - .data(Number160.createHash(newChatRequestMessage.getChatID()), new Data(gson.toJson(newChatRequestMessage)) - .protectEntry(keyPairManager.openMainKeyPair())) + .data(Number160.createHash(newChatRequestMessage.getChatID()), new Data(gson.toJson(newChatRequestMessage))) .start() .awaitUninterruptibly(); if(futurePut.isSuccess()) { @@ -65,11 +63,12 @@ public class StartChatLogic implements StartChatLogicContract { } else { Log.e(LOG_TAG, "# Failed to create chat: " + futurePut.failedReason()); } - ObservableUtils.notifyUI(UIActions.SUCCESSFULL_CREATE_OFFLINE_CHAT); } catch (IOException e) { e.printStackTrace(); } } + NetworkHandler.createChatEntry(newChatRequestMessage.getChatID(), peerID, recipientPeerAddress); + ObservableUtils.notifyUI(UIActions.NEW_CHAT); }).start(); } diff --git a/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java b/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java index beb4f55..4440fd2 100644 --- a/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java +++ b/app/src/main/java/io/github/chronosx88/influence/models/NewChatRequestMessage.java @@ -10,16 +10,12 @@ import io.github.chronosx88.influence.helpers.actions.NetworkActions; public class NewChatRequestMessage extends BasicNetworkMessage implements Serializable { private String chatID; - public NewChatRequestMessage(String senderID, PeerAddress senderPeerAddress) { + public NewChatRequestMessage(String chatID, String senderID, PeerAddress senderPeerAddress) { super(NetworkActions.CREATE_CHAT, senderID, senderPeerAddress); - this.chatID = UUID.randomUUID().toString(); + this.chatID = chatID; } public String getChatID() { return chatID; } - - public void setChatID(String chatID) { - this.chatID = chatID; - } } diff --git a/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java b/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java index 14169af..2269214 100644 --- a/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java +++ b/app/src/main/java/io/github/chronosx88/influence/presenters/StartChatPresenter.java @@ -35,14 +35,9 @@ public class StartChatPresenter implements StartChatPresenterContract, Observer break; } - case UIActions.SUCCESSFULL_CREATE_CHAT: { + case UIActions.NEW_CHAT: { view.showProgressDialog(false); - view.showMessage("Чат успешно создан"); - break; - } - case UIActions.SUCCESSFULL_CREATE_OFFLINE_CHAT: { - view.showProgressDialog(false); - view.showMessage("В сеть отправлен запрос на создание чата, так как получатель не в сети."); + view.showMessage("Чат успешно создан!"); break; } } diff --git a/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java b/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java index 27a9e5c..0c74ab8 100644 --- a/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java +++ b/app/src/main/java/io/github/chronosx88/influence/views/fragments/StartChatFragment.java @@ -2,6 +2,8 @@ package io.github.chronosx88.influence.views.fragments; import android.app.ProgressDialog; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,6 +14,7 @@ import com.google.android.material.textfield.TextInputLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.fragment.app.Fragment; import io.github.chronosx88.influence.R; import io.github.chronosx88.influence.contracts.startchat.StartChatViewContract; @@ -22,6 +25,8 @@ public class StartChatFragment extends Fragment implements StartChatViewContract private ProgressDialog progressDialog; private Button createChatButton; private StartChatPresenter presenter; + private Handler mainThreadHandler; + private CoordinatorLayout coordinatorLayout; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -41,19 +46,20 @@ public class StartChatFragment extends Fragment implements StartChatViewContract createChatButton.setOnClickListener((v) -> { presenter.startChatWithPeer(textInputPeerID.getEditText().getText().toString()); }); + mainThreadHandler = new Handler(getContext().getMainLooper()); + coordinatorLayout = getView().findViewById(R.id.start_chat_coordinator); } @Override public void showMessage(String message) { - requireActivity().runOnUiThread(() -> { - Snackbar.make(getView().findViewById(R.id.start_chat_coordinator), message, Snackbar.LENGTH_SHORT).show(); + mainThreadHandler.post(() -> { + Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_SHORT).show(); }); } @Override public void showProgressDialog(boolean enabled) { - // TODO: make run on mainHandlerThread - requireActivity().runOnUiThread(() -> { + mainThreadHandler.post(() -> { if(enabled) { progressDialog.show(); } else {