Now chats are correctly creating and not recreating when deleted.

This commit is contained in:
ChronosX88 2019-03-24 16:58:12 +04:00
parent 0bca327949
commit 33e3aadcc4
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
8 changed files with 78 additions and 58 deletions

View File

@ -8,6 +8,7 @@ import com.google.gson.JsonParser;
import net.tomp2p.dht.FutureGet; import net.tomp2p.dht.FutureGet;
import net.tomp2p.dht.FuturePut; import net.tomp2p.dht.FuturePut;
import net.tomp2p.dht.FutureRemove;
import net.tomp2p.dht.PeerDHT; import net.tomp2p.dht.PeerDHT;
import net.tomp2p.futures.FuturePing; import net.tomp2p.futures.FuturePing;
import net.tomp2p.peers.Number160; import net.tomp2p.peers.Number160;
@ -18,7 +19,6 @@ import net.tomp2p.storage.Data;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import io.github.chronosx88.influence.contracts.observer.NetworkObserver; import io.github.chronosx88.influence.contracts.observer.NetworkObserver;
import io.github.chronosx88.influence.helpers.actions.NetworkActions; 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); NewChatRequestMessage newChatRequestMessage = gson.fromJson((String) object, NewChatRequestMessage.class);
createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress()); createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress());
handleIncomingChatRequest(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderPeerAddress()); handleIncomingChatRequest(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderPeerAddress());
JsonObject jsonObject = new JsonObject(); ObservableUtils.notifyUI(UIActions.NEW_CHAT);
jsonObject.addProperty("action", UIActions.NEW_CHAT);
AppHelper.getObservable().notifyUIObservers(jsonObject);
break; break;
} }
case NetworkActions.SUCCESSFULL_CREATE_CHAT: { case NetworkActions.SUCCESSFULL_CREATE_CHAT: {
NewChatRequestMessage newChatRequestMessage = gson.fromJson((String) object, NewChatRequestMessage.class); NewChatRequestMessage newChatRequestMessage = gson.fromJson((String) object, NewChatRequestMessage.class);
createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress()); createChatEntry(newChatRequestMessage.getChatID(), newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderPeerAddress());
ObservableUtils.notifyUI(UIActions.SUCCESSFULL_CREATE_CHAT); ObservableUtils.notifyUI(UIActions.SUCCESSFUL_CREATE_CHAT);
peerDHT.remove(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingChats"))
.contentKey(Number160.createHash(newChatRequestMessage.getChatID()))
.start()
.awaitUninterruptibly();
break; break;
} }
} }
}).start(); }).start();
} }
private int getMessageAction(String json) { public static int getMessageAction(String json) {
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject(); JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
return jsonObject.get("action").getAsInt(); 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<ChatEntity> chatEntities = AppHelper.getChatDB().chatDao().getChatByChatID(chatID); List<ChatEntity> chatEntities = AppHelper.getChatDB().chatDao().getChatByChatID(chatID);
if (chatEntities.size() > 0) { if (chatEntities.size() > 0) {
Log.e(LOG_TAG, "Failed to create chat " + chatID + " because chat exists!"); 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) { private void handleIncomingChatRequest(String chatID, PeerAddress chatStarterAddress) {
NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress()); NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(chatID, AppHelper.getPeerID(), peerDHT.peerAddress());
newChatRequestMessage.setChatID(chatID);
newChatRequestMessage.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT); newChatRequestMessage.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT);
AppHelper.getPeerDHT().peer().sendDirect(chatStarterAddress).object(gson.toJson(newChatRequestMessage)).start().awaitUninterruptibly(); AppHelper.getPeerDHT().peer().sendDirect(chatStarterAddress).object(gson.toJson(newChatRequestMessage)).start().awaitUninterruptibly();
} }
@ -108,15 +101,9 @@ public class NetworkHandler implements NetworkObserver {
newChatRequestMessage.getSenderPeerAddress() newChatRequestMessage.getSenderPeerAddress()
); );
FuturePing ping = peerDHT NewChatRequestMessage newChatRequestReply = new NewChatRequestMessage(newChatRequestMessage.getChatID(), AppHelper.getPeerID(), peerDHT.peerAddress());
.peer()
.ping()
.peerAddress(newChatRequestMessage.getSenderPeerAddress())
.start()
.awaitUninterruptibly();
NewChatRequestMessage newChatRequestReply = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress());
newChatRequestReply.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT); newChatRequestReply.setAction(NetworkActions.SUCCESSFULL_CREATE_CHAT);
if(ping.isSuccess()) { if(P2PUtils.ping(newChatRequestMessage.getSenderPeerAddress())) {
peerDHT peerDHT
.peer() .peer()
.sendDirect(newChatRequestMessage.getSenderPeerAddress()) .sendDirect(newChatRequestMessage.getSenderPeerAddress())
@ -126,8 +113,7 @@ public class NetworkHandler implements NetworkObserver {
} else { } else {
try { try {
FuturePut put = peerDHT.put(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingAcceptedChats")) FuturePut put = peerDHT.put(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingAcceptedChats"))
.data(Number160.createHash(UUID.randomUUID().toString()), new Data(gson.toJson(newChatRequestReply)) .data(Number160.createHash(newChatRequestReply.getChatID()), new Data(gson.toJson(newChatRequestReply)))
.protectEntry(keyPairManager.openMainKeyPair()))
.start() .start()
.awaitUninterruptibly(); .awaitUninterruptibly();
if(put.isSuccess()) { if(put.isSuccess()) {
@ -138,6 +124,10 @@ public class NetworkHandler implements NetworkObserver {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
peerDHT.remove(Number160.createHash(AppHelper.getPeerID() + "_pendingChats"))
.contentKey(Number160.createHash(newChatRequestMessage.getChatID()))
.start()
.awaitUninterruptibly();
} }
ObservableUtils.notifyUI(UIActions.NEW_CHAT); ObservableUtils.notifyUI(UIActions.NEW_CHAT);
@ -162,16 +152,18 @@ public class NetworkHandler implements NetworkObserver {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
peerDHT.remove(Number160.createHash(newChatRequestMessage.getSenderID() + "_pendingChats"))
.contentKey(Number160.createHash(newChatRequestMessage.getChatID()))
.start()
.awaitUninterruptibly();
createChatEntry( createChatEntry(
newChatRequestMessage.getChatID(), newChatRequestMessage.getChatID(),
newChatRequestMessage.getSenderID(), newChatRequestMessage.getSenderID(),
newChatRequestMessage.getSenderPeerAddress() newChatRequestMessage.getSenderPeerAddress()
); );
FutureRemove remove = peerDHT.remove(Number160.createHash(AppHelper.getPeerID() + "_pendingAcceptedChats"))
.contentKey(Number160.createHash(newChatRequestMessage.getChatID()))
.start()
.awaitUninterruptibly();
ObservableUtils.notifyUI(UIActions.NEW_CHAT); ObservableUtils.notifyUI(UIActions.NEW_CHAT);
} }
} }

View File

@ -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();
}
}

View File

@ -325,9 +325,8 @@ public class StorageMVStore implements Storage {
private byte[] serializeData(Data data) { private byte[] serializeData(Data data) {
KeyPair mainKeyPair = keyPairManager.openMainKeyPair();
KeyPair forSigningKP = keyPairManager.getKeyPair("mainSigningKeyPair"); KeyPair forSigningKP = keyPairManager.getKeyPair("mainSigningKeyPair");
data.sign(forSigningKP).protectEntry(mainKeyPair); data.sign(forSigningKP);
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
AlternativeCompositeByteBuf acb = AlternativeCompositeByteBuf.compBuffer(AlternativeCompositeByteBuf.UNPOOLED_HEAP); AlternativeCompositeByteBuf acb = AlternativeCompositeByteBuf.compBuffer(AlternativeCompositeByteBuf.UNPOOLED_HEAP);
try { try {

View File

@ -9,6 +9,5 @@ public class UIActions {
public static final int BOOTSTRAP_ERROR = 0x5; public static final int BOOTSTRAP_ERROR = 0x5;
public static final int NEW_CHAT = 0x6; public static final int NEW_CHAT = 0x6;
public static final int PEER_NOT_EXIST = 0x7; public static final int PEER_NOT_EXIST = 0x7;
public static final int SUCCESSFULL_CREATE_CHAT = 0x8; public static final int SUCCESSFUL_CREATE_CHAT = 0x8;
public static final int SUCCESSFULL_CREATE_OFFLINE_CHAT = 0x9;
} }

View File

@ -19,7 +19,9 @@ import java.util.UUID;
import io.github.chronosx88.influence.contracts.startchat.StartChatLogicContract; import io.github.chronosx88.influence.contracts.startchat.StartChatLogicContract;
import io.github.chronosx88.influence.helpers.AppHelper; import io.github.chronosx88.influence.helpers.AppHelper;
import io.github.chronosx88.influence.helpers.KeyPairManager; 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.ObservableUtils;
import io.github.chronosx88.influence.helpers.P2PUtils;
import io.github.chronosx88.influence.helpers.actions.UIActions; import io.github.chronosx88.influence.helpers.actions.UIActions;
import io.github.chronosx88.influence.models.NewChatRequestMessage; import io.github.chronosx88.influence.models.NewChatRequestMessage;
import io.github.chronosx88.influence.models.PublicUserProfile; import io.github.chronosx88.influence.models.PublicUserProfile;
@ -41,23 +43,19 @@ public class StartChatLogic implements StartChatLogicContract {
new Thread(() -> { new Thread(() -> {
PublicUserProfile recipientPublicProfile = getPublicProfile(peerID); PublicUserProfile recipientPublicProfile = getPublicProfile(peerID);
if(recipientPublicProfile == null) { if(recipientPublicProfile == null) {
JsonObject jsonObject = new JsonObject(); ObservableUtils.notifyUI(UIActions.PEER_NOT_EXIST);
jsonObject.addProperty("action", UIActions.PEER_NOT_EXIST);
AppHelper.getObservable().notifyUIObservers(jsonObject);
return; return;
} }
PeerAddress recipientPeerAddress = getPublicProfile(peerID).getPeerAddress(); PeerAddress recipientPeerAddress = getPublicProfile(peerID).getPeerAddress();
FuturePing ping = peerDHT.peer().ping().peerAddress(recipientPeerAddress).start().awaitUninterruptibly(); NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(UUID.randomUUID().toString(), AppHelper.getPeerID(), peerDHT.peerAddress());
if(ping.isSuccess()) { if(P2PUtils.ping(recipientPeerAddress)) {
peerDHT.peer().sendDirect(recipientPeerAddress).object(gson.toJson(new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress()))).start(); peerDHT.peer().sendDirect(recipientPeerAddress).object(gson.toJson(newChatRequestMessage)).start().awaitUninterruptibly();
} else { } else {
try { try {
NewChatRequestMessage newChatRequestMessage = new NewChatRequestMessage(AppHelper.getPeerID(), peerDHT.peerAddress());
FuturePut futurePut = peerDHT FuturePut futurePut = peerDHT
.put(Number160.createHash(peerID + "_pendingChats")) .put(Number160.createHash(peerID + "_pendingChats"))
.data(Number160.createHash(newChatRequestMessage.getChatID()), new Data(gson.toJson(newChatRequestMessage)) .data(Number160.createHash(newChatRequestMessage.getChatID()), new Data(gson.toJson(newChatRequestMessage)))
.protectEntry(keyPairManager.openMainKeyPair()))
.start() .start()
.awaitUninterruptibly(); .awaitUninterruptibly();
if(futurePut.isSuccess()) { if(futurePut.isSuccess()) {
@ -65,11 +63,12 @@ public class StartChatLogic implements StartChatLogicContract {
} else { } else {
Log.e(LOG_TAG, "# Failed to create chat: " + futurePut.failedReason()); Log.e(LOG_TAG, "# Failed to create chat: " + futurePut.failedReason());
} }
ObservableUtils.notifyUI(UIActions.SUCCESSFULL_CREATE_OFFLINE_CHAT);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
NetworkHandler.createChatEntry(newChatRequestMessage.getChatID(), peerID, recipientPeerAddress);
ObservableUtils.notifyUI(UIActions.NEW_CHAT);
}).start(); }).start();
} }

View File

@ -10,16 +10,12 @@ import io.github.chronosx88.influence.helpers.actions.NetworkActions;
public class NewChatRequestMessage extends BasicNetworkMessage implements Serializable { public class NewChatRequestMessage extends BasicNetworkMessage implements Serializable {
private String chatID; private String chatID;
public NewChatRequestMessage(String senderID, PeerAddress senderPeerAddress) { public NewChatRequestMessage(String chatID, String senderID, PeerAddress senderPeerAddress) {
super(NetworkActions.CREATE_CHAT, senderID, senderPeerAddress); super(NetworkActions.CREATE_CHAT, senderID, senderPeerAddress);
this.chatID = UUID.randomUUID().toString(); this.chatID = chatID;
} }
public String getChatID() { public String getChatID() {
return chatID; return chatID;
} }
public void setChatID(String chatID) {
this.chatID = chatID;
}
} }

View File

@ -35,14 +35,9 @@ public class StartChatPresenter implements StartChatPresenterContract, Observer
break; break;
} }
case UIActions.SUCCESSFULL_CREATE_CHAT: { case UIActions.NEW_CHAT: {
view.showProgressDialog(false); view.showProgressDialog(false);
view.showMessage("Чат успешно создан"); view.showMessage("Чат успешно создан!");
break;
}
case UIActions.SUCCESSFULL_CREATE_OFFLINE_CHAT: {
view.showProgressDialog(false);
view.showMessage("В сеть отправлен запрос на создание чата, так как получатель не в сети.");
break; break;
} }
} }

View File

@ -2,6 +2,8 @@ package io.github.chronosx88.influence.views.fragments;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -12,6 +14,7 @@ import com.google.android.material.textfield.TextInputLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import io.github.chronosx88.influence.R; import io.github.chronosx88.influence.R;
import io.github.chronosx88.influence.contracts.startchat.StartChatViewContract; import io.github.chronosx88.influence.contracts.startchat.StartChatViewContract;
@ -22,6 +25,8 @@ public class StartChatFragment extends Fragment implements StartChatViewContract
private ProgressDialog progressDialog; private ProgressDialog progressDialog;
private Button createChatButton; private Button createChatButton;
private StartChatPresenter presenter; private StartChatPresenter presenter;
private Handler mainThreadHandler;
private CoordinatorLayout coordinatorLayout;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -41,19 +46,20 @@ public class StartChatFragment extends Fragment implements StartChatViewContract
createChatButton.setOnClickListener((v) -> { createChatButton.setOnClickListener((v) -> {
presenter.startChatWithPeer(textInputPeerID.getEditText().getText().toString()); presenter.startChatWithPeer(textInputPeerID.getEditText().getText().toString());
}); });
mainThreadHandler = new Handler(getContext().getMainLooper());
coordinatorLayout = getView().findViewById(R.id.start_chat_coordinator);
} }
@Override @Override
public void showMessage(String message) { public void showMessage(String message) {
requireActivity().runOnUiThread(() -> { mainThreadHandler.post(() -> {
Snackbar.make(getView().findViewById(R.id.start_chat_coordinator), message, Snackbar.LENGTH_SHORT).show(); Snackbar.make(coordinatorLayout, message, Snackbar.LENGTH_SHORT).show();
}); });
} }
@Override @Override
public void showProgressDialog(boolean enabled) { public void showProgressDialog(boolean enabled) {
// TODO: make run on mainHandlerThread mainThreadHandler.post(() -> {
requireActivity().runOnUiThread(() -> {
if(enabled) { if(enabled) {
progressDialog.show(); progressDialog.show();
} else { } else {