diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java index b83f0e226..13783569b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java @@ -22,6 +22,7 @@ import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStream; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.Socket; @@ -53,9 +54,11 @@ import org.sufficientlysecure.keychain.util.Log; @RequiresApi(api = VERSION_CODES.LOLLIPOP) public class KeyTransferInteractor { - private static final int SHOW_CONNECTION_DETAILS = 1; + private static final int CONNECTION_LISTENING = 1; private static final int CONNECTION_ESTABLISHED = 2; - private static final int CONNECTION_LOST = 3; + private static final int CONNECTION_SEND_OK = 3; + private static final int CONNECTION_RECEIVE_OK = 4; + private static final int CONNECTION_LOST = 5; private TransferThread transferThread; @@ -121,7 +124,7 @@ public class KeyTransferInteractor { String presharedKeyEncoded = Base64.encodeToString(presharedKey, Base64.URL_SAFE | Base64.NO_PADDING); String qrCodeData = presharedKeyEncoded + "@" + getIPAddress(true) + ":" + port; - invokeListener(SHOW_CONNECTION_DETAILS, qrCodeData); + invokeListener(CONNECTION_LISTENING, qrCodeData); socket = serverSocket.accept(); invokeListener(CONNECTION_ESTABLISHED, socket.getInetAddress().toString()); @@ -131,6 +134,7 @@ public class KeyTransferInteractor { } handleOpenConnection(socket); + Log.d(Constants.TAG, "connection closed ok!"); } catch (IOException e) { Log.e(Constants.TAG, "error!", e); } finally { @@ -164,33 +168,70 @@ public class KeyTransferInteractor { } private void handleOpenConnection(Socket socket) throws IOException { - socket.setSoTimeout(500); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + socket.setSoTimeout(500); while (!isInterrupted() && socket.isConnected()) { - if (dataToSend != null) { - BufferedOutputStream bufferedOutputStream = - new BufferedOutputStream(socket.getOutputStream()); - bufferedOutputStream.write(dataToSend); - bufferedOutputStream.close(); - dataToSend = null; - break; + if (sendDataIfAvailable(socket)) { + return; } - try { - String line = bufferedReader.readLine(); - if (line == null) { - Log.d(Constants.TAG, "eof"); - break; - } - Log.d(Constants.TAG, "got line: " + line); - } catch (SocketTimeoutException e) { - // ignore + + if (receiveDataIfAvailable(socket, bufferedReader)) { + return; } } Log.d(Constants.TAG, "disconnected"); invokeListener(CONNECTION_LOST, null); } + private boolean receiveDataIfAvailable(Socket socket, BufferedReader bufferedReader) throws IOException { + String firstLine; + try { + firstLine = bufferedReader.readLine(); + } catch (SocketTimeoutException e) { + return false; + } + + if (firstLine == null) { + invokeListener(CONNECTION_LOST, null); + return true; + } + + socket.setSoTimeout(2000); + String receivedData = receiveAfterFirstLineAndClose(bufferedReader, firstLine); + invokeListener(CONNECTION_RECEIVE_OK, receivedData); + return true; + } + + private boolean sendDataIfAvailable(Socket socket) throws IOException { + if (dataToSend != null) { + byte[] data = dataToSend; + dataToSend = null; + + socket.setSoTimeout(2000); + sendDataAndClose(socket.getOutputStream(), data); + invokeListener(CONNECTION_SEND_OK, null); + return true; + } + return false; + } + + private String receiveAfterFirstLineAndClose(BufferedReader bufferedReader, String line) throws IOException { + StringBuilder builder = new StringBuilder(); + do { + builder.append(line); + line = bufferedReader.readLine(); + } while (line != null); + + return builder.toString(); + } + + private void sendDataAndClose(OutputStream outputStream, byte[] data) throws IOException { + BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); + bufferedOutputStream.write(data); + bufferedOutputStream.close(); + } + private void invokeListener(final int method, final String arg) { if (handler == null) { return; @@ -203,12 +244,18 @@ public class KeyTransferInteractor { return; } switch (method) { - case SHOW_CONNECTION_DETAILS: + case CONNECTION_LISTENING: callback.onServerStarted(arg); break; case CONNECTION_ESTABLISHED: callback.onConnectionEstablished(arg); break; + case CONNECTION_RECEIVE_OK: + callback.onDataReceivedOk(arg); + break; + case CONNECTION_SEND_OK: + callback.onDataSentOk(arg); + break; case CONNECTION_LOST: callback.onConnectionLost(); } @@ -218,7 +265,7 @@ public class KeyTransferInteractor { handler.post(runnable); } - public synchronized void sendDataAndClose(byte[] dataToSend) { + synchronized void sendDataAndClose(byte[] dataToSend) { this.dataToSend = dataToSend; } @@ -258,6 +305,9 @@ public class KeyTransferInteractor { void onServerStarted(String qrCodeData); void onConnectionEstablished(String otherName); void onConnectionLost(); + + void onDataReceivedOk(String receivedData); + void onDataSentOk(String arg); } /** @@ -293,7 +343,8 @@ public class KeyTransferInteractor { } } } catch (Exception ex) { - } // for now eat exceptions + // ignore + } return ""; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/presenter/TransferPresenter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/presenter/TransferPresenter.java index 9e0d049de..b0e307217 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/presenter/TransferPresenter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/presenter/TransferPresenter.java @@ -33,6 +33,7 @@ import android.support.v4.content.Loader; import android.support.v7.widget.RecyclerView.Adapter; import android.view.LayoutInflater; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.network.KeyTransferInteractor; import org.sufficientlysecure.keychain.network.KeyTransferInteractor.KeyTransferCallback; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; @@ -42,6 +43,7 @@ import org.sufficientlysecure.keychain.ui.transfer.loader.SecretKeyLoader.Secret import org.sufficientlysecure.keychain.ui.transfer.view.TransferSecretKeyList.OnClickTransferKeyListener; import org.sufficientlysecure.keychain.ui.transfer.view.TransferSecretKeyList.TransferKeyAdapter; import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; +import org.sufficientlysecure.keychain.util.Log; @RequiresApi(api = VERSION_CODES.LOLLIPOP) @@ -66,43 +68,45 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks> onCreateLoader(int id, Bundle args) { return secretKeyAdapter.createLoader(context); @@ -135,20 +186,6 @@ public class TransferPresenter implements KeyTransferCallback, LoaderCallbacks 100) { + cancel(); + progressDialogFragment.dismissAllowingStateLoss(); + handler.post(new Runnable() { + @Override + public void run() { + presenter.onUiFakeProgressFinished(); + } + }); + return; + } + progressDialogFragment.setProgress(fakeProgress, 100); + } + }, 0, 100); + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CODE_SCAN: if (resultCode == Activity.RESULT_OK) { String qrCodeData = data.getStringExtra(Intents.Scan.RESULT); - presenter.onQrCodeScanned(qrCodeData); + presenter.onUiQrCodeScanned(qrCodeData); } break; default: diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferSecretKeyList.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferSecretKeyList.java index 46b86be67..3ad384b53 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferSecretKeyList.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferSecretKeyList.java @@ -129,7 +129,7 @@ public class TransferSecretKeyList extends RecyclerView { vSendButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - onClickTransferKeyListener.onClickTransferKey(item.masterKeyId); + onClickTransferKeyListener.onUiClickTransferKey(item.masterKeyId); } }); } else { @@ -139,6 +139,6 @@ public class TransferSecretKeyList extends RecyclerView { } public interface OnClickTransferKeyListener { - void onClickTransferKey(long masterKeyId); + void onUiClickTransferKey(long masterKeyId); } } diff --git a/OpenKeychain/src/main/res/layout/transfer_fragment.xml b/OpenKeychain/src/main/res/layout/transfer_fragment.xml index 6e19a1373..789600b42 100644 --- a/OpenKeychain/src/main/res/layout/transfer_fragment.xml +++ b/OpenKeychain/src/main/res/layout/transfer_fragment.xml @@ -1,80 +1,80 @@ - + android:id="@+id/transfer_animator" + android:inAnimation="@anim/fade_in_delayed" + android:outAnimation="@anim/fade_out" + custom:initialView="0"> - + android:layout_height="match_parent" + android:gravity="center_vertical" + android:orientation="vertical" + android:padding="16dp"> - + +