diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java
deleted file mode 100644
index 0ba4c9d96..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/KeyTransferInteractor.java
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.network;
-
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.NoRouteToHostException;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-import java.net.URISyntaxException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import android.os.Build.VERSION_CODES;
-import android.os.Handler;
-import android.os.Looper;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSocket;
-import timber.log.Timber;
-
-
-@RequiresApi(api = VERSION_CODES.LOLLIPOP)
-public class KeyTransferInteractor {
- private static final String[] ALLOWED_CIPHERSUITES = new String[] {
- // only allow ephemeral diffie-hellman based PSK ciphers!
- "TLS_DHE_PSK_WITH_AES_128_CBC_SHA",
- "TLS_DHE_PSK_WITH_AES_256_CBC_SHA",
- "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256"
- };
-
- private static final int CONNECTION_LISTENING = 1;
- private static final int CONNECTION_ESTABLISHED = 2;
- private static final int CONNECTION_SEND_OK = 3;
- private static final int CONNECTION_RECEIVE_OK = 4;
- private static final int CONNECTION_LOST = 5;
- private static final int CONNECTION_ERROR_NO_ROUTE_TO_HOST = 6;
- private static final int CONNECTION_ERROR_CONNECT = 7;
- private static final int CONNECTION_ERROR_WHILE_CONNECTED = 8;
- private static final int CONNECTION_ERROR_LISTEN = 0;
-
- private static final int TIMEOUT_CONNECTING = 1500;
- private static final int TIMEOUT_RECEIVING = 2000;
- private static final int TIMEOUT_WAITING = 500;
- private static final int PSK_BYTE_LENGTH = 16;
-
-
- private final String delimiterStart;
- private final String delimiterEnd;
-
- private TransferThread transferThread;
-
-
- public KeyTransferInteractor(String delimiterStart, String delimiterEnd) {
- this.delimiterStart = delimiterStart;
- this.delimiterEnd = delimiterEnd;
- }
-
- public void connectToServer(String qrCodeContent, KeyTransferCallback callback) throws URISyntaxException {
- SktUri sktUri = SktUri.parse(qrCodeContent);
-
- transferThread = TransferThread.createClientTransferThread(delimiterStart, delimiterEnd, callback,
- sktUri.getPresharedKey(), sktUri.getHost(), sktUri.getPort(), sktUri.getWifiSsid());
- transferThread.start();
- }
-
- public void startServer(KeyTransferCallback callback, String wifiSsid) {
- byte[] presharedKey = generatePresharedKey();
-
- transferThread = TransferThread.createServerTransferThread(delimiterStart, delimiterEnd, callback, presharedKey, wifiSsid);
- transferThread.start();
- }
-
- private static class TransferThread extends Thread {
- private final String delimiterStart;
- private final String delimiterEnd;
-
- private final Handler handler;
- private final byte[] presharedKey;
- private final boolean isServer;
- private final String clientHost;
- private final Integer clientPort;
- private final String wifiSsid;
-
- private KeyTransferCallback callback;
- private SSLServerSocket serverSocket;
- private byte[] dataToSend;
- private String sendPassthrough;
-
- static TransferThread createClientTransferThread(String delimiterStart, String delimiterEnd,
- KeyTransferCallback callback, byte[] presharedKey, String host, int port, String wifiSsid) {
- return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, false, host, port, wifiSsid);
- }
-
- static TransferThread createServerTransferThread(String delimiterStart, String delimiterEnd,
- KeyTransferCallback callback, byte[] presharedKey, String wifiSsid) {
- return new TransferThread(delimiterStart, delimiterEnd, callback, presharedKey, true, null, null, wifiSsid);
- }
-
- private TransferThread(String delimiterStart, String delimiterEnd,
- KeyTransferCallback callback, byte[] presharedKey, boolean isServer,
- String clientHost, Integer clientPort, String wifiSsid) {
- super("TLS-PSK Key Transfer Thread");
-
- this.delimiterStart = delimiterStart;
- this.delimiterEnd = delimiterEnd;
-
- this.callback = callback;
- this.presharedKey = presharedKey;
- this.clientHost = clientHost;
- this.clientPort = clientPort;
- this.wifiSsid = wifiSsid;
- this.isServer = isServer;
-
- handler = new Handler(Looper.getMainLooper());
- }
-
- @Override
- public void run() {
- SSLContext sslContext = TlsPskCompat.createTlsPskSslContext(presharedKey);
-
- Socket socket = null;
- try {
- socket = getSocketListenOrConnect(sslContext);
- if (socket == null) {
- return;
- }
-
- try {
- handleOpenConnection(socket);
- Timber.d("connection closed ok!");
- } catch (SSLHandshakeException e) {
- Timber.d(e, "ssl handshake error!");
- invokeListener(CONNECTION_ERROR_CONNECT, null);
- } catch (IOException e) {
- Timber.e(e, "communication error!");
- invokeListener(CONNECTION_ERROR_WHILE_CONNECTED, e.getLocalizedMessage());
- }
- } finally {
- closeQuietly(socket);
- closeQuietly(serverSocket);
- }
- }
-
- @Nullable
- private Socket getSocketListenOrConnect(SSLContext sslContext) {
- Socket socket;
- if (isServer) {
- try {
- serverSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(0);
- String[] supportedCipherSuites = serverSocket.getSupportedCipherSuites();
- String[] enabledCipherSuites = intersectArrays(supportedCipherSuites, ALLOWED_CIPHERSUITES);
- serverSocket.setEnabledCipherSuites(enabledCipherSuites);
-
- SktUri sktUri = SktUri.create(getIPAddress(true), serverSocket.getLocalPort(), presharedKey, wifiSsid);
- invokeListener(CONNECTION_LISTENING, sktUri.toUriString());
-
- socket = serverSocket.accept();
- } catch (IOException e) {
- Timber.e(e, "error while listening!");
- invokeListener(CONNECTION_ERROR_LISTEN, null);
- return null;
- }
- } else {
- try {
- SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
- String[] supportedCipherSuites = sslSocket.getSupportedCipherSuites();
- String[] enabledCipherSuites = intersectArrays(supportedCipherSuites, ALLOWED_CIPHERSUITES);
- sslSocket.setEnabledCipherSuites(enabledCipherSuites);
-
- socket = sslSocket;
- socket.connect(new InetSocketAddress(InetAddress.getByName(clientHost), clientPort), TIMEOUT_CONNECTING);
- } catch (IOException e) {
- Timber.e(e, "error while connecting!");
- if (e instanceof NoRouteToHostException) {
- invokeListener(CONNECTION_ERROR_NO_ROUTE_TO_HOST, wifiSsid);
- } else {
- invokeListener(CONNECTION_ERROR_CONNECT, null);
- }
- return null;
- }
- }
- return socket;
- }
-
- private void handleOpenConnection(Socket socket) throws IOException {
- BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- OutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
-
- invokeListener(CONNECTION_ESTABLISHED, socket.getInetAddress().toString());
-
- socket.setSoTimeout(TIMEOUT_WAITING);
- while (!isInterrupted() && socket.isConnected() && !socket.isClosed()) {
- sendDataIfAvailable(socket, outputStream);
- boolean connectionTerminated = receiveDataIfAvailable(socket, bufferedReader);
- if (connectionTerminated) {
- break;
- }
- }
- Timber.d("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) {
- return true;
- }
-
- boolean lineIsDelimiter = delimiterStart.equals(firstLine);
- if (!lineIsDelimiter) {
- Timber.d("bad beginning of key block?");
- return false;
- }
-
- socket.setSoTimeout(TIMEOUT_RECEIVING);
- String receivedData = receiveLinesUntilEndDelimiter(bufferedReader, firstLine);
- socket.setSoTimeout(TIMEOUT_WAITING);
-
- invokeListener(CONNECTION_RECEIVE_OK, receivedData);
- return false;
- }
-
- private boolean sendDataIfAvailable(Socket socket, OutputStream outputStream) throws IOException {
- if (dataToSend != null) {
- byte[] data = dataToSend;
- dataToSend = null;
-
- socket.setSoTimeout(TIMEOUT_RECEIVING);
- outputStream.write(data);
- outputStream.flush();
- socket.setSoTimeout(TIMEOUT_WAITING);
-
- invokeListener(CONNECTION_SEND_OK, sendPassthrough);
- sendPassthrough = null;
- return true;
- }
- return false;
- }
-
- private String receiveLinesUntilEndDelimiter(BufferedReader bufferedReader, String line) throws IOException {
- StringBuilder builder = new StringBuilder();
- do {
- boolean lineIsDelimiter = delimiterEnd.equals(line);
- if (lineIsDelimiter) {
- break;
- }
-
- builder.append(line).append('\n');
-
- line = bufferedReader.readLine();
- } while (line != null);
-
- return builder.toString();
- }
-
- private void invokeListener(final int method, final String arg) {
- if (handler == null) {
- return;
- }
-
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- if (callback == null) {
- return;
- }
- switch (method) {
- 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();
- break;
- case CONNECTION_ERROR_WHILE_CONNECTED:
- callback.onConnectionError(arg);
- break;
- case CONNECTION_ERROR_NO_ROUTE_TO_HOST:
- callback.onConnectionErrorNoRouteToHost(wifiSsid);
- break;
- case CONNECTION_ERROR_CONNECT:
- callback.onConnectionErrorConnect();
- break;
- case CONNECTION_ERROR_LISTEN:
- callback.onConnectionErrorListen();
- break;
- }
- }
- };
-
- handler.post(runnable);
- }
-
- synchronized void sendData(byte[] dataToSend, String passthrough) {
- this.dataToSend = dataToSend;
- this.sendPassthrough = passthrough;
- }
-
- @Override
- public void interrupt() {
- callback = null;
- super.interrupt();
- closeQuietly(serverSocket);
- }
- }
-
- private static byte[] generatePresharedKey() {
- byte[] presharedKey = new byte[PSK_BYTE_LENGTH];
- new SecureRandom().nextBytes(presharedKey);
- return presharedKey;
- }
-
- public void closeConnection() {
- if (transferThread != null) {
- transferThread.interrupt();
- }
-
- transferThread = null;
- }
-
- public void sendData(byte[] dataToSend, String passthrough) {
- transferThread.sendData(dataToSend, passthrough);
- }
-
- public interface KeyTransferCallback {
- void onServerStarted(String qrCodeData);
- void onConnectionEstablished(String otherName);
- void onConnectionLost();
-
- void onDataReceivedOk(String receivedData);
- void onDataSentOk(String passthrough);
-
- void onConnectionErrorConnect();
- void onConnectionErrorNoRouteToHost(String wifiSsid);
- void onConnectionErrorListen();
- void onConnectionError(String arg);
- }
-
- /**
- * from: http://stackoverflow.com/a/13007325
- *
- * Get IP address from first non-localhost interface
- *
- * @param useIPv4 true=return ipv4, false=return ipv6
- * @return address or empty string
- */
- private static String getIPAddress(boolean useIPv4) {
- try {
- List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
- for (NetworkInterface intf : interfaces) {
- List addrs = Collections.list(intf.getInetAddresses());
- for (InetAddress addr : addrs) {
- if (addr.isLoopbackAddress()) {
- continue;
- }
- String sAddr = addr.getHostAddress();
- boolean isIPv4 = sAddr.indexOf(':') < 0;
- if (useIPv4) {
- if (isIPv4) {
- return sAddr;
- }
- } else {
- int delimIndex = sAddr.indexOf('%'); // drop ip6 zone suffix
- if (delimIndex >= 0) {
- sAddr = sAddr.substring(0, delimIndex);
- }
- return sAddr.toUpperCase();
- }
- }
- }
- } catch (Exception ex) {
- // ignore
- }
- return "";
- }
-
- private static void closeQuietly(Closeable closeable) {
- try {
- if (closeable != null) {
- closeable.close();
- }
- } catch (IOException e) {
- // ignore
- }
- }
-
- private static String[] intersectArrays(String[] array1, String[] array2) {
- Set s1 = new HashSet<>(Arrays.asList(array1));
- Set s2 = new HashSet<>(Arrays.asList(array2));
- s1.retainAll(s2);
-
- return s1.toArray(new String[0]);
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/SktUri.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/SktUri.java
deleted file mode 100644
index 7186c8237..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/SktUri.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.network;
-
-import java.net.URISyntaxException;
-import java.nio.charset.Charset;
-
-import android.annotation.SuppressLint;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.auto.value.AutoValue;
-import org.bouncycastle.util.encoders.DecoderException;
-import org.bouncycastle.util.encoders.Hex;
-import org.sufficientlysecure.keychain.Constants;
-import timber.log.Timber;
-
-
-@AutoValue
-abstract class SktUri {
- private static final String QRCODE_URI_FORMAT = Constants.SKT_SCHEME + ":%s/%d/%s";
- private static final String QRCODE_URI_FORMAT_SSID = Constants.SKT_SCHEME + ":%s/%d/%s/SSID:%s";
-
-
- public abstract String getHost();
- public abstract int getPort();
- @SuppressWarnings("mutable")
- public abstract byte[] getPresharedKey();
-
- @Nullable
- public abstract String getWifiSsid();
-
- @NonNull
- public static SktUri parse(String input) throws URISyntaxException {
- if (!input.startsWith(Constants.SKT_SCHEME + ":")) {
- throw new URISyntaxException(input, "invalid scheme");
- }
-
- String[] pieces = input.substring(input.indexOf(":") +1).split("/");
- if (pieces.length < 3) {
- throw new URISyntaxException(input, "invalid syntax");
- }
-
- String address = pieces[0];
- int port;
- try {
- port = Integer.parseInt(pieces[1]);
- } catch (NumberFormatException e) {
- throw new URISyntaxException(input, "error parsing port");
- }
- byte[] psk;
- try {
- psk = Hex.decode(pieces[2]);
- } catch (DecoderException e) {
- throw new URISyntaxException(input, "error parsing hex psk");
- }
-
- String wifiSsid = null;
- for (int i = 3; i < pieces.length; i++) {
- String[] optarg = pieces[i].split(":", 2);
- if (optarg.length == 2 && "SSID".equals(optarg[0])) {
- try {
- wifiSsid = new String(Hex.decode(optarg[1]));
- } catch (DecoderException e) {
- Timber.d("error parsing ssid in skt uri, ignoring: " + input);
- }
- }
- }
-
- return new AutoValue_SktUri(address, port, psk, wifiSsid);
- }
-
- @SuppressLint("DefaultLocale")
- String toUriString() {
- String sktHex = Hex.toHexString(getPresharedKey());
- String wifiSsid = getWifiSsid();
-
- String result;
- if (wifiSsid != null) {
- String encodedWifiSsid = Hex.toHexString(getWifiSsid().getBytes(Charset.defaultCharset()));
- result = String.format(QRCODE_URI_FORMAT_SSID, getHost(), getPort(), sktHex, encodedWifiSsid);
- } else {
- result = String.format(QRCODE_URI_FORMAT, getHost(), getPort(), sktHex);
- }
-
- return result.toUpperCase();
- }
-
- static SktUri create(String host, int port, byte[] presharedKey, @Nullable String wifiSsid) {
- return new AutoValue_SktUri(host, port, presharedKey, wifiSsid);
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/TlsPskCompat.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/TlsPskCompat.java
deleted file mode 100644
index 24886557a..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/network/TlsPskCompat.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.sufficientlysecure.keychain.network;
-
-
-import java.net.Socket;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-
-import android.os.Build.VERSION_CODES;
-import androidx.annotation.RequiresApi;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.TrustManager;
-
-
-@RequiresApi(api = VERSION_CODES.LOLLIPOP)
-class TlsPskCompat {
-
- static SSLContext createTlsPskSslContext(byte[] presharedKey) {
- try {
- PresharedKeyManager pskKeyManager = new PresharedKeyManager(presharedKey);
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(new KeyManager[] { pskKeyManager }, new TrustManager[0], null);
-
- return sslContext;
- } catch (KeyManagementException | NoSuchAlgorithmException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @SuppressWarnings("unused")
- /* This class is a KeyManager that is compatible to TlsPskManager.
- *
- * Due to the way conscrypt works internally, this class will be internally duck typed to
- * PSKKeyManager. This is quite a hack, and relies on conscrypt internals to work - but it
- * works.
- *
- * see also:
- * https://github.com/google/conscrypt/blob/b23e9353ed4e3256379d660cb09491a69b21affb/common/src/main/java/org/conscrypt/SSLParametersImpl.java#L494
- * https://github.com/google/conscrypt/blob/29916ef38dc9cb4e4c6e3fdb87d4e921546d3ef4/common/src/main/java/org/conscrypt/DuckTypedPSKKeyManager.java#L51
- *
- */
- private static class PresharedKeyManager implements KeyManager {
- byte[] presharedKey;
-
- private PresharedKeyManager(byte[] presharedKey) {
- this.presharedKey = presharedKey;
- }
-
- public String chooseServerKeyIdentityHint(Socket socket) {
- return null;
- }
-
- public String chooseServerKeyIdentityHint(SSLEngine engine) {
- return null;
- }
-
- public String chooseClientKeyIdentity(String identityHint, Socket socket) {
- return identityHint;
- }
-
- public String chooseClientKeyIdentity(String identityHint, SSLEngine engine) {
- return identityHint;
- }
-
- public SecretKey getKey(String identityHint, String identity, Socket socket) {
- return new SecretKeySpec(presharedKey, "AES");
- }
-
- public SecretKey getKey(String identityHint, String identity, SSLEngine engine) {
- return new SecretKeySpec(presharedKey, "AES");
- }
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java
index e24dce606..be9049a9b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java
@@ -21,19 +21,16 @@ package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
-import org.sufficientlysecure.keychain.ui.transfer.view.TransferFragment;
import org.sufficientlysecure.keychain.util.Preferences;
import timber.log.Timber;
@@ -48,7 +45,6 @@ public class CreateKeyStartFragment extends Fragment {
View mImportKey;
View mSecurityToken;
TextView mSkipOrCancel;
- View mSecureDeviceSetup;
/**
@@ -72,7 +68,6 @@ public class CreateKeyStartFragment extends Fragment {
mImportKey = view.findViewById(R.id.create_key_import_button);
mSecurityToken = view.findViewById(R.id.create_key_security_token_button);
mSkipOrCancel = view.findViewById(R.id.create_key_cancel);
- mSecureDeviceSetup = view.findViewById(R.id.create_key_secure_device_setup);
if (mCreateKeyActivity.mFirstTime) {
mSkipOrCancel.setText(R.string.first_time_skip);
@@ -96,15 +91,6 @@ public class CreateKeyStartFragment extends Fragment {
startActivityForResult(intent, REQUEST_CODE_IMPORT_KEY);
});
- if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
- mSecureDeviceSetup.setOnClickListener(v -> {
- TransferFragment frag = new TransferFragment();
- mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT);
- });
- } else {
- mSecureDeviceSetup.setVisibility(View.GONE);
- }
-
mSkipOrCancel.setOnClickListener(v -> {
if (!mCreateKeyActivity.mFirstTime) {
mCreateKeyActivity.setResult(Activity.RESULT_CANCELED);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java
index f69a465af..565ebb5cc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java
@@ -40,7 +40,6 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogTyp
import org.sufficientlysecure.keychain.operations.results.SingletonResult;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
-import org.sufficientlysecure.keychain.ui.transfer.view.TransferFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
@@ -155,17 +154,6 @@ public class ImportKeysProxyActivity extends FragmentActivity
Timber.d("scanned: " + uri);
- // example: pgp+transfer:
- if (uri != null && uri.getScheme() != null && uri.getScheme().equalsIgnoreCase(Constants.SKT_SCHEME)) {
- Intent intent = new Intent(this, MainActivity.class);
- intent.putExtra(MainActivity.EXTRA_INIT_FRAG, MainActivity.ID_TRANSFER);
- intent.putExtra(TransferFragment.EXTRA_OPENPGP_SKT_INFO, uri);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- finish();
- return;
- }
-
// example: openpgp4fpr:73EE2314F65FA92EC2390D3A718C070100012282
if (uri == null || uri.getScheme() == null ||
!uri.getScheme().toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
index 35dfd4670..ce26e88e0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java
@@ -19,9 +19,6 @@ package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
-import android.graphics.Typeface;
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.view.View;
@@ -41,8 +38,6 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.remote.ui.AppsListFragment;
import org.sufficientlysecure.keychain.ui.base.BaseSecurityTokenActivity;
-import org.sufficientlysecure.keychain.ui.transfer.view.TransferFragment;
-import org.sufficientlysecure.keychain.ui.transfer.view.TransferNotAvailableFragment;
import org.sufficientlysecure.keychain.util.FabContainer;
import org.sufficientlysecure.keychain.util.Preferences;
@@ -52,7 +47,6 @@ public class MainActivity extends BaseSecurityTokenActivity implements FabContai
static final int ID_ENCRYPT_DECRYPT = 2;
static final int ID_APPS = 3;
static final int ID_BACKUP = 4;
- public static final int ID_TRANSFER = 5;
static final int ID_SETTINGS = 6;
static final int ID_HELP = 7;
@@ -85,11 +79,6 @@ public class MainActivity extends BaseSecurityTokenActivity implements FabContai
.withIdentifier(ID_APPS).withSelectable(false),
new PrimaryDrawerItem().withName(R.string.nav_backup).withIcon(CommunityMaterial.Icon.cmd_backup_restore)
.withIdentifier(ID_BACKUP).withSelectable(false),
- new PrimaryDrawerItem().withName(R.string.nav_transfer)
- .withIcon(R.drawable.ic_wifi_lock_24dp)
- .withIconColorRes(R.color.md_grey_600)
- .withIconTintingEnabled(true)
- .withIdentifier(ID_TRANSFER).withSelectable(false),
new DividerDrawerItem(),
new PrimaryDrawerItem().withName(R.string.menu_preferences).withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(ID_SETTINGS).withSelectable(false),
new PrimaryDrawerItem().withName(R.string.menu_help).withIcon(CommunityMaterial.Icon.cmd_help_circle).withIdentifier(ID_HELP).withSelectable(false)
@@ -113,9 +102,6 @@ public class MainActivity extends BaseSecurityTokenActivity implements FabContai
case ID_BACKUP:
onBackupSelected();
break;
- case ID_TRANSFER:
- onTransferSelected();
- break;
case ID_SETTINGS:
intent = new Intent(MainActivity.this, SettingsActivity.class);
break;
@@ -168,9 +154,6 @@ public class MainActivity extends BaseSecurityTokenActivity implements FabContai
case ID_APPS:
onAppsSelected();
break;
- case ID_TRANSFER:
- onTransferSelected();
- break;
}
}
@@ -190,9 +173,6 @@ public class MainActivity extends BaseSecurityTokenActivity implements FabContai
case ID_APPS:
onAppsSelected();
break;
- case ID_TRANSFER:
- onTransferSelected();
- break;
}
}
}
@@ -234,18 +214,6 @@ public class MainActivity extends BaseSecurityTokenActivity implements FabContai
setFragment(frag);
}
- private void onTransferSelected() {
- mToolbar.setTitle(R.string.nav_transfer);
- mDrawer.setSelection(ID_TRANSFER, false);
- if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
- Fragment frag = new TransferNotAvailableFragment();
- setFragment(frag);
- } else {
- Fragment frag = new TransferFragment();
- setFragment(frag);
- }
- }
-
@Override
protected void onSaveInstanceState(Bundle outState) {
// add the values which need to be saved from the drawer to the bundle
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java
index b3193de09..2a6e507d4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java
@@ -299,13 +299,6 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity {
startPassphraseActivity(REQUEST_BACKUP);
return true;
}
- case R.id.menu_key_view_skt: {
- Intent intent = new Intent(this, MainActivity.class);
- intent.putExtra(MainActivity.EXTRA_INIT_FRAG, MainActivity.ID_TRANSFER);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
- return true;
- }
case R.id.menu_key_view_delete: {
deleteKey();
return true;
@@ -335,7 +328,6 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity {
}
MenuItem backupKey = menu.findItem(R.id.menu_key_view_backup);
backupKey.setVisible(unifiedKeyInfo.has_any_secret());
- menu.findItem(R.id.menu_key_view_skt).setVisible(unifiedKeyInfo.has_any_secret());
MenuItem changePassword = menu.findItem(R.id.menu_key_change_password);
changePassword.setVisible(unifiedKeyInfo.has_any_secret());
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
deleted file mode 100644
index ff76d29db..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/presenter/TransferPresenter.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.ui.transfer.presenter;
-
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.List;
-
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.LiveData;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Build.VERSION_CODES;
-import android.os.Handler;
-import android.os.Parcelable;
-import androidx.annotation.RequiresApi;
-import androidx.recyclerview.widget.RecyclerView.Adapter;
-import android.view.LayoutInflater;
-
-import org.openintents.openpgp.util.OpenPgpUtils;
-import org.openintents.openpgp.util.OpenPgpUtils.UserId;
-import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
-import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
-import org.sufficientlysecure.keychain.network.KeyTransferInteractor;
-import org.sufficientlysecure.keychain.network.KeyTransferInteractor.KeyTransferCallback;
-import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
-import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
-import org.sufficientlysecure.keychain.daos.KeyRepository;
-import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException;
-import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
-import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
-import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.Callback;
-import org.sufficientlysecure.keychain.ui.keyview.GenericViewModel;
-import org.sufficientlysecure.keychain.ui.transfer.view.ReceivedSecretKeyList.OnClickImportKeyListener;
-import org.sufficientlysecure.keychain.ui.transfer.view.ReceivedSecretKeyList.ReceivedKeyAdapter;
-import org.sufficientlysecure.keychain.ui.transfer.view.ReceivedSecretKeyList.ReceivedKeyItem;
-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 timber.log.Timber;
-
-
-@RequiresApi(api = VERSION_CODES.LOLLIPOP)
-public class TransferPresenter implements KeyTransferCallback, OnClickTransferKeyListener, OnClickImportKeyListener {
- private static final String DELIMITER_START = "-----BEGIN PGP PRIVATE KEY BLOCK-----";
- private static final String DELIMITER_END = "-----END PGP PRIVATE KEY BLOCK-----";
- private static final String BACKSTACK_TAG_TRANSFER = "transfer";
-
- private final Context context;
- private final TransferMvpView view;
- private final KeyRepository keyRepository;
-
- private final TransferKeyAdapter secretKeyAdapter;
- private final ReceivedKeyAdapter receivedKeyAdapter;
- private final LifecycleOwner lifecycleOwner;
- private final GenericViewModel viewModel;
-
-
- private KeyTransferInteractor keyTransferClientInteractor;
- private KeyTransferInteractor keyTransferServerInteractor;
-
- private boolean wasConnected = false;
- private boolean sentData = false;
- private boolean waitingForWifi = false;
- private Long confirmingMasterKeyId;
-
-
- public TransferPresenter(Context context, LifecycleOwner lifecycleOwner,
- GenericViewModel viewModel, TransferMvpView view) {
- this.context = context;
- this.view = view;
- this.lifecycleOwner = lifecycleOwner;
- this.viewModel = viewModel;
- this.keyRepository = KeyRepository.create(context);
-
- secretKeyAdapter = new TransferKeyAdapter(context, LayoutInflater.from(context), this);
- view.setSecretKeyAdapter(secretKeyAdapter);
-
- receivedKeyAdapter = new ReceivedKeyAdapter(context, LayoutInflater.from(context), this);
- view.setReceivedKeyAdapter(receivedKeyAdapter);
- }
-
-
- public void onUiInitFromIntentUri(final Uri initUri) {
- connectionStartConnect(initUri.toString());
- }
-
- public void onUiStart() {
- LiveData> liveData =
- viewModel.getGenericLiveData(context, keyRepository::getAllUnifiedKeyInfoWithSecret);
- liveData.observe(lifecycleOwner, this::onLoadSecretUnifiedKeyInfo);
-
- if (keyTransferServerInteractor == null && keyTransferClientInteractor == null && !wasConnected) {
- checkWifiResetAndStartListen();
- }
- }
-
- private void onLoadSecretUnifiedKeyInfo(List data) {
- secretKeyAdapter.setData(data);
- view.setShowSecretKeyEmptyView(data.isEmpty());
- }
-
- public void onUiStop() {
- connectionClear();
-
- if (wasConnected) {
- view.showViewDisconnected();
- view.dismissConfirmationIfExists();
- secretKeyAdapter.setAllDisabled(true);
- }
- }
-
- public void onUiClickScan() {
- connectionClear();
-
- view.scanQrCode();
- }
-
- public void onUiClickScanAgain() {
- onUiClickScan();
- }
-
- public void onUiClickDone() {
- view.finishFragmentOrActivity();
- }
-
- public void onUiQrCodeScanned(String qrCodeContent) {
- connectionStartConnect(qrCodeContent);
- }
-
- public void onUiBackStackPop() {
- if (wasConnected) {
- checkWifiResetAndStartListen();
- }
- }
-
- @Override
- public void onUiClickTransferKey(long masterKeyId) {
- if (sentData) {
- prepareAndSendKey(masterKeyId);
- } else {
- confirmingMasterKeyId = masterKeyId;
- view.showConfirmSendDialog();
- }
- }
-
- public void onUiClickConfirmSend() {
- if (confirmingMasterKeyId == null) {
- return;
- }
- long masterKeyId = confirmingMasterKeyId;
- confirmingMasterKeyId = null;
-
- prepareAndSendKey(masterKeyId);
- }
-
- @Override
- public void onUiClickImportKey(final long masterKeyId, String keyData) {
- receivedKeyAdapter.focusItem(masterKeyId);
-
- final ImportKeyringParcel importKeyringParcel = ImportKeyringParcel.createImportKeyringParcel(
- ParcelableKeyRing.createFromEncodedBytes(keyData.getBytes()));
-
- CryptoOperationHelper op =
- view.createCryptoOperationHelper(new Callback() {
- @Override
- public ImportKeyringParcel createOperationInput() {
- return importKeyringParcel;
- }
-
- @Override
- public void onCryptoOperationSuccess(ImportKeyResult result) {
- receivedKeyAdapter.focusItem(null);
- receivedKeyAdapter.addToFinishedItems(masterKeyId);
- view.releaseCryptoOperationHelper();
- view.showResultNotification(result);
- }
-
- @Override
- public void onCryptoOperationCancelled() {
- view.releaseCryptoOperationHelper();
- receivedKeyAdapter.focusItem(null);
- }
-
- @Override
- public void onCryptoOperationError(ImportKeyResult result) {
- receivedKeyAdapter.focusItem(null);
- view.releaseCryptoOperationHelper();
- view.showResultNotification(result);
- }
-
- @Override
- public boolean onCryptoSetProgress(String msg, int progress, int max) {
- return false;
- }
- });
-
- op.cryptoOperation();
- }
-
- public void onWifiConnected() {
- if (waitingForWifi) {
- resetAndStartListen();
- }
- }
-
- @Override
- public void onServerStarted(String qrCodeData) {
- Bitmap qrCodeBitmap = QrCodeUtils.getQRCodeBitmap(Uri.parse(qrCodeData));
- view.setQrImage(qrCodeBitmap);
- }
-
- @Override
- public void onConnectionEstablished(String otherName) {
- wasConnected = true;
-
- secretKeyAdapter.clearFinishedItems();
- secretKeyAdapter.focusItem(null);
- secretKeyAdapter.setAllDisabled(false);
- receivedKeyAdapter.clear();
-
- view.showConnectionEstablished(otherName);
- view.setShowDoneIcon(true);
- view.addFakeBackStackItem(BACKSTACK_TAG_TRANSFER);
- }
-
- @Override
- public void onConnectionLost() {
- if (!wasConnected) {
- checkWifiResetAndStartListen();
-
- view.showErrorConnectionFailed();
- } else {
- connectionClear();
-
- view.dismissConfirmationIfExists();
- view.showViewDisconnected();
- secretKeyAdapter.setAllDisabled(true);
- }
- }
-
- @Override
- public void onDataReceivedOk(String receivedData) {
- if (sentData) {
- Timber.d("received data, but we already sent a key! race condition, or other side misbehaving?");
- return;
- }
-
- Timber.d("received data");
- UncachedKeyRing uncachedKeyRing;
- try {
- uncachedKeyRing = UncachedKeyRing.decodeFromData(receivedData.getBytes());
- } catch (PgpGeneralException | IOException | RuntimeException e) {
- Timber.e(e, "error parsing incoming key");
- view.showErrorBadKey();
- return;
- }
-
- String primaryUserId = uncachedKeyRing.getPublicKey().getPrimaryUserIdWithFallback();
- UserId userId = OpenPgpUtils.splitUserId(primaryUserId);
-
- ReceivedKeyItem receivedKeyItem = new ReceivedKeyItem(receivedData, uncachedKeyRing.getMasterKeyId(),
- uncachedKeyRing.getCreationTime(), userId.name, userId.email);
- receivedKeyAdapter.addItem(receivedKeyItem);
-
- view.showReceivingKeys();
- }
-
- @Override
- public void onDataSentOk(String passthrough) {
- Timber.d("data sent ok!");
- final long masterKeyId = Long.parseLong(passthrough);
-
- new Handler().postDelayed(() -> {
- secretKeyAdapter.focusItem(null);
- secretKeyAdapter.addToFinishedItems(masterKeyId);
- }, 750);
- }
-
- @Override
- public void onConnectionErrorConnect() {
- view.showWaitingForConnection();
- view.showErrorConnectionFailed();
-
- resetAndStartListen();
- }
-
- @Override
- public void onConnectionErrorNoRouteToHost(String wifiSsid) {
- connectionClear();
-
- String ownWifiSsid = getConnectedWifiSsid();
- if (!wifiSsid.equalsIgnoreCase(ownWifiSsid)) {
- view.showWifiError(wifiSsid);
- } else {
- view.showWaitingForConnection();
- view.showErrorConnectionFailed();
-
- resetAndStartListen();
- }
- }
-
- @Override
- public void onConnectionErrorListen() {
- view.showErrorListenFailed();
- }
-
- @Override
- public void onConnectionError(String errorMessage) {
- view.showErrorConnectionError(errorMessage);
-
- connectionClear();
- if (wasConnected) {
- view.showViewDisconnected();
- secretKeyAdapter.setAllDisabled(true);
- }
- }
-
- private void connectionStartConnect(String qrCodeContent) {
- connectionClear();
-
- view.showEstablishingConnection();
-
- keyTransferClientInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
- try {
- keyTransferClientInteractor.connectToServer(qrCodeContent, TransferPresenter.this);
- } catch (URISyntaxException e) {
- view.showErrorConnectionFailed();
- }
- }
-
- private void checkWifiResetAndStartListen() {
- if (!isWifiConnected()) {
- waitingForWifi = true;
- view.showNotOnWifi();
- return;
- }
-
- resetAndStartListen();
- }
-
- private void resetAndStartListen() {
- waitingForWifi = false;
- wasConnected = false;
- sentData = false;
- connectionClear();
-
- String wifiSsid = getConnectedWifiSsid();
-
- keyTransferServerInteractor = new KeyTransferInteractor(DELIMITER_START, DELIMITER_END);
- keyTransferServerInteractor.startServer(this, wifiSsid);
-
- view.showWaitingForConnection();
- view.setShowDoneIcon(false);
- }
-
- private boolean isWifiConnected() {
- ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- if (connManager == null) {
- return false;
- }
-
- NetworkInfo wifiNetwork = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-
- return wifiNetwork.isConnected();
- }
-
- private String getConnectedWifiSsid() {
- WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- if (wifiManager == null) {
- return null;
- }
- WifiInfo info = wifiManager.getConnectionInfo();
- if (info == null) {
- return null;
- }
- // getSSID will return the ssid in quotes if it is valid utf-8. we only return it in that case.
- String ssid = info.getSSID();
- if (ssid.charAt(0) != '"') {
- return null;
- }
- return ssid.substring(1, ssid.length() -1);
- }
-
- private void connectionClear() {
- if (keyTransferServerInteractor != null) {
- keyTransferServerInteractor.closeConnection();
- keyTransferServerInteractor = null;
- }
- if (keyTransferClientInteractor != null) {
- keyTransferClientInteractor.closeConnection();
- keyTransferClientInteractor = null;
- }
- }
-
- private void prepareAndSendKey(long masterKeyId) {
- try {
- byte[] armoredSecretKey = keyRepository.getSecretKeyRingAsArmoredData(masterKeyId);
- secretKeyAdapter.focusItem(masterKeyId);
- connectionSend(armoredSecretKey, Long.toString(masterKeyId));
- } catch (IOException | NotFoundException e) {
- // TODO
- e.printStackTrace();
- }
- }
-
- private void connectionSend(byte[] armoredSecretKey, String passthrough) {
- sentData = true;
- if (keyTransferClientInteractor != null) {
- keyTransferClientInteractor.sendData(armoredSecretKey, passthrough);
- } else if (keyTransferServerInteractor != null) {
- keyTransferServerInteractor.sendData(armoredSecretKey, passthrough);
- }
- }
-
- public interface TransferMvpView {
- void showNotOnWifi();
- void showWaitingForConnection();
- void showEstablishingConnection();
- void showConnectionEstablished(String hostname);
-
- void showWifiError(String wifiSsid);
-
- void showReceivingKeys();
-
- void showViewDisconnected();
-
- void scanQrCode();
- void setQrImage(Bitmap qrCode);
-
- void releaseCryptoOperationHelper();
-
- void showErrorBadKey();
- void showErrorConnectionFailed();
- void showErrorListenFailed();
- void showErrorConnectionError(String errorMessage);
- void showResultNotification(ImportKeyResult result);
-
- void setShowDoneIcon(boolean showDoneIcon);
-
- void setSecretKeyAdapter(Adapter adapter);
- void setShowSecretKeyEmptyView(boolean isEmpty);
- void setReceivedKeyAdapter(Adapter secretKeyAdapter);
-
- CryptoOperationHelper createCryptoOperationHelper(Callback callback);
-
- void addFakeBackStackItem(String tag);
-
- void finishFragmentOrActivity();
-
- void showConfirmSendDialog();
- void dismissConfirmationIfExists();
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/ReceivedSecretKeyList.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/ReceivedSecretKeyList.java
deleted file mode 100644
index b61c9e0c4..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/ReceivedSecretKeyList.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.ui.transfer.view;
-
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.content.Context;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import android.text.format.DateUtils;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import android.widget.ViewAnimator;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
-
-
-public class ReceivedSecretKeyList extends RecyclerView {
- private static final int STATE_INVISIBLE = 0;
- // private static final int STATE_BUTTON = 1; // used in TransferSecretKeyList
- private static final int STATE_PROGRESS = 2;
- private static final int STATE_TRANSFERRED = 3;
- private static final int STATE_IMPORT_BUTTON = 4;
-
-
- public ReceivedSecretKeyList(Context context) {
- super(context);
- init(context);
- }
-
- public ReceivedSecretKeyList(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public ReceivedSecretKeyList(Context context, @Nullable AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
-
- private void init(Context context) {
- setLayoutManager(new LinearLayoutManager(context));
- addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL_LIST, true));
- }
-
- public static class ReceivedKeyAdapter extends Adapter {
- private final Context context;
- private final LayoutInflater layoutInflater;
- private final OnClickImportKeyListener onClickImportKeyListener;
-
- private Long focusedMasterKeyId;
- private List data = new ArrayList<>();
- private ArrayList finishedItems = new ArrayList<>();
-
-
- public ReceivedKeyAdapter(Context context, LayoutInflater layoutInflater,
- OnClickImportKeyListener onClickImportKeyListener) {
- this.context = context;
- this.layoutInflater = layoutInflater;
- this.onClickImportKeyListener = onClickImportKeyListener;
- }
-
- @Override
- public ReceivedKeyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return new ReceivedKeyViewHolder(layoutInflater.inflate(R.layout.key_transfer_item, parent, false));
- }
-
- @Override
- public void onBindViewHolder(ReceivedKeyViewHolder holder, int position) {
- ReceivedKeyItem item = data.get(position);
- boolean isFinished = finishedItems.contains(item.masterKeyId);
- holder.bind(context, item, onClickImportKeyListener, focusedMasterKeyId, isFinished);
- }
-
- @Override
- public int getItemCount() {
- return data != null ? data.size() : 0;
- }
-
- @Override
- public long getItemId(int position) {
- return data.get(position).masterKeyId;
- }
-
- public void addToFinishedItems(long masterKeyId) {
- finishedItems.add(masterKeyId);
- // doeesn't notify, because it's non-trivial and this is called in conjunction with other refreshing things!
- }
-
- public void focusItem(Long masterKeyId) {
- focusedMasterKeyId = masterKeyId;
- notifyItemRangeChanged(0, getItemCount());
- }
-
- public void addItem(ReceivedKeyItem receivedKeyItem) {
- data.add(receivedKeyItem);
- notifyItemInserted(data.size() -1);
- }
-
- public void clear() {
- data.clear();
- finishedItems.clear();
- focusedMasterKeyId = null;
- notifyDataSetChanged();
- }
- }
-
- static class ReceivedKeyViewHolder extends ViewHolder {
- private final TextView vName;
- private final TextView vEmail;
- private final TextView vCreation;
- private final View vImportButton;
- private final ViewAnimator vState;
-
- ReceivedKeyViewHolder(View itemView) {
- super(itemView);
-
- vName = itemView.findViewById(R.id.key_list_item_name);
- vEmail = itemView.findViewById(R.id.key_list_item_email);
- vCreation = itemView.findViewById(R.id.key_list_item_creation);
-
- vImportButton = itemView.findViewById(R.id.button_import);
- vState = itemView.findViewById(R.id.transfer_state);
- }
-
- private void bind(Context context, final ReceivedKeyItem item,
- final OnClickImportKeyListener onClickReceiveKeyListener, Long focusedMasterKeyId,
- boolean isFinished) {
- if (item.name != null) {
- vName.setText(item.name);
- vName.setVisibility(View.VISIBLE);
- } else {
- vName.setVisibility(View.GONE);
- }
- if (item.email != null) {
- vEmail.setText(item.email);
- vEmail.setVisibility(View.VISIBLE);
- } else {
- vEmail.setVisibility(View.GONE);
- }
-
- String dateTime = DateUtils.formatDateTime(context, item.creationMillis,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME |
- DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH);
- vCreation.setText(context.getString(R.string.label_key_created, dateTime));
-
- if (focusedMasterKeyId != null) {
- if (focusedMasterKeyId != item.masterKeyId) {
- itemView.animate().alpha(0.2f).start();
- vState.setDisplayedChild(isFinished ? STATE_TRANSFERRED : STATE_INVISIBLE);
- } else {
- itemView.setAlpha(1.0f);
- vState.setDisplayedChild(STATE_PROGRESS);
- }
- } else {
- itemView.animate().alpha(1.0f).start();
- vState.setDisplayedChild(isFinished ? STATE_TRANSFERRED : STATE_IMPORT_BUTTON);
- }
-
- if (focusedMasterKeyId == null && onClickReceiveKeyListener != null) {
- vImportButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- onClickReceiveKeyListener.onUiClickImportKey(item.masterKeyId, item.keyData);
- }
- });
- } else {
- vImportButton.setOnClickListener(null);
- }
- }
- }
-
- public interface OnClickImportKeyListener {
- void onUiClickImportKey(long masterKeyId, String keyData);
- }
-
- public static class ReceivedKeyItem {
- private final String keyData;
-
- private final long masterKeyId;
- private final long creationMillis;
- private final String name;
- private final String email;
-
- public ReceivedKeyItem(String keyData, long masterKeyId, long creationMillis, String name, String email) {
- this.keyData = keyData;
- this.masterKeyId = masterKeyId;
- this.creationMillis = creationMillis;
- this.name = name;
- this.email = email;
- }
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferFragment.java
deleted file mode 100644
index fe55fc432..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferFragment.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.ui.transfer.view;
-
-
-import android.app.Activity;
-import androidx.lifecycle.ViewModelProviders;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.Bitmap;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.os.Parcelable;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AlertDialog.Builder;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.Adapter;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.google.zxing.client.android.Intents;
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
-import org.sufficientlysecure.keychain.operations.results.OperationResult;
-import org.sufficientlysecure.keychain.ui.MainActivity;
-import org.sufficientlysecure.keychain.ui.QrCodeCaptureActivity;
-import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
-import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.Callback;
-import org.sufficientlysecure.keychain.ui.keyview.GenericViewModel;
-import org.sufficientlysecure.keychain.ui.transfer.presenter.TransferPresenter;
-import org.sufficientlysecure.keychain.ui.transfer.presenter.TransferPresenter.TransferMvpView;
-import org.sufficientlysecure.keychain.ui.util.Notify;
-import org.sufficientlysecure.keychain.ui.util.Notify.Style;
-import org.sufficientlysecure.keychain.ui.widget.ConnectionStatusView;
-import org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator;
-
-
-@RequiresApi(api = VERSION_CODES.LOLLIPOP)
-public class TransferFragment extends Fragment implements TransferMvpView {
- public static final int REQUEST_CODE_SCAN = 1;
- public static final int LOADER_ID = 1;
-
- public static final String EXTRA_OPENPGP_SKT_INFO = "openpgp_skt_info";
-
-
- private ImageView vQrCodeImage;
- private TransferPresenter presenter;
- private ToolableViewAnimator vTransferAnimator;
- private TextView vConnectionStatusText1;
- private TextView vConnectionStatusText2;
- private ConnectionStatusView vConnectionStatusView1;
- private ConnectionStatusView vConnectionStatusView2;
- private RecyclerView vTransferKeyList;
- private View vTransferKeyListEmptyView;
- private RecyclerView vReceivedKeyList;
-
- private CryptoOperationHelper currentCryptoOperationHelper;
- private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
- NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- if (networkInfo != null && networkInfo.isConnected()) {
- presenter.onWifiConnected();
- }
- }
- }
- };
- private boolean showDoneIcon;
- private AlertDialog confirmationDialog;
- private TextView vWifiErrorInstructions;
-
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.transfer_fragment, container, false);
-
- vTransferAnimator = view.findViewById(R.id.transfer_animator);
-
- vConnectionStatusText1 = view.findViewById(R.id.connection_status_1);
- vConnectionStatusText2 = view.findViewById(R.id.connection_status_2);
- vConnectionStatusView1 = view.findViewById(R.id.connection_status_icon_1);
- vConnectionStatusView2 = view.findViewById(R.id.connection_status_icon_2);
- vTransferKeyList = view.findViewById(R.id.transfer_key_list);
- vTransferKeyListEmptyView = view.findViewById(R.id.transfer_key_list_empty);
- vReceivedKeyList = view.findViewById(R.id.received_key_list);
- vWifiErrorInstructions = view.findViewById(R.id.transfer_wifi_error_instructions);
-
- vQrCodeImage = view.findViewById(R.id.qr_code_image);
-
- view.findViewById(R.id.button_scan).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (presenter != null) {
- presenter.onUiClickScan();
- }
- }
- });
-
- view.findViewById(R.id.button_scan_again).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (presenter != null) {
- presenter.onUiClickScanAgain();
- }
- }
- });
-
- GenericViewModel genericViewModel = ViewModelProviders.of(this).get(GenericViewModel.class);
- presenter = new TransferPresenter(getContext(), this, genericViewModel, this);
-
- setHasOptionsMenu(true);
-
- return view;
- }
-
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- if (savedInstanceState != null) {
- return;
- }
-
- Intent activityIntent = getActivity().getIntent();
- if (activityIntent != null && activityIntent.hasExtra(EXTRA_OPENPGP_SKT_INFO)) {
- presenter.onUiInitFromIntentUri(activityIntent.getParcelableExtra(EXTRA_OPENPGP_SKT_INFO));
- }
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- presenter.onUiStart();
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- getContext().registerReceiver(broadcastReceiver, intentFilter);
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- getContext().unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public void onStop() {
- super.onStop();
-
- presenter.onUiStop();
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- if (showDoneIcon) {
- inflater.inflate(R.menu.transfer_menu, menu);
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.menu_done) {
- presenter.onUiClickDone();
- return true;
- }
- return false;
- }
-
- @Override
- public void showNotOnWifi() {
- vTransferAnimator.setDisplayedChildId(R.id.transfer_layout_no_wifi);
- }
-
- @Override
- public void showWaitingForConnection() {
- vTransferAnimator.setDisplayedChildId(R.id.transfer_layout_waiting);
- }
-
- @Override
- public void showEstablishingConnection() {
- vTransferAnimator.setDisplayedChildId(R.id.transfer_layout_connecting);
- }
-
- @Override
- public void showConnectionEstablished(String hostname) {
- // String statusText = getString(R.string.transfer_status_connected, hostname);
-
- vConnectionStatusText1.setText(R.string.transfer_status_connected);
- vConnectionStatusText2.setText(R.string.transfer_status_connected);
-
- vConnectionStatusView1.setConnected(true);
- vConnectionStatusView2.setConnected(true);
-
- vTransferAnimator.setDisplayedChildId(R.id.transfer_layout_connected);
- }
-
- @Override
- public void showWifiError(String wifiSsid) {
- vTransferAnimator.setDisplayedChildId(R.id.transfer_layout_wifi_error);
-
- if (!TextUtils.isEmpty(wifiSsid)) {
- vWifiErrorInstructions
- .setText(getResources().getString(R.string.transfer_error_wifi_text_instructions_ssid, wifiSsid));
- } else {
- vWifiErrorInstructions.setText(R.string.transfer_error_wifi_text_instructions);
- }
- }
-
- @Override
- public void showReceivingKeys() {
- vTransferAnimator.setDisplayedChildId(R.id.transfer_layout_passive);
- }
-
- @Override
- public void showViewDisconnected() {
- vConnectionStatusText1.setText(R.string.transfer_status_disconnected);
- vConnectionStatusText2.setText(R.string.transfer_status_disconnected);
-
- vConnectionStatusView1.setConnected(false);
- vConnectionStatusView2.setConnected(false);
- }
-
- @Override
- public void setQrImage(final Bitmap qrCode) {
- vQrCodeImage.getViewTreeObserver().addOnGlobalLayoutListener(
- new OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- int viewSize = vQrCodeImage.getWidth();
- if (viewSize == 0) {
- return;
- }
- // create actual bitmap in display dimensions
- Bitmap scaled = Bitmap.createScaledBitmap(qrCode, viewSize, viewSize, false);
- vQrCodeImage.setImageBitmap(scaled);
- }
- });
- vQrCodeImage.requestLayout();
- }
-
- @Override
- public void scanQrCode() {
- Intent intent = new Intent(getActivity(), QrCodeCaptureActivity.class);
- startActivityForResult(intent, REQUEST_CODE_SCAN);
- }
-
- @Override
- public void setShowDoneIcon(boolean showDoneIcon) {
- this.showDoneIcon = showDoneIcon;
- FragmentActivity activity = getActivity();
- if (activity != null) {
- activity.invalidateOptionsMenu();
- }
- }
-
- @Override
- public void setSecretKeyAdapter(Adapter adapter) {
- vTransferKeyList.setAdapter(adapter);
- }
-
- @Override
- public void setShowSecretKeyEmptyView(boolean isEmpty) {
- vTransferKeyListEmptyView.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
- }
-
- @Override
- public void setReceivedKeyAdapter(Adapter adapter) {
- vReceivedKeyList.setAdapter(adapter);
- }
-
- @Override
- public CryptoOperationHelper createCryptoOperationHelper(Callback callback) {
- CryptoOperationHelper cryptoOperationHelper = new CryptoOperationHelper<>(1, this, callback, null);
- currentCryptoOperationHelper = cryptoOperationHelper;
- return cryptoOperationHelper;
- }
-
- @Override
- public void releaseCryptoOperationHelper() {
- currentCryptoOperationHelper = null;
- }
-
- @Override
- public void showErrorBadKey() {
- Notify.create(getActivity(), R.string.transfer_error_read_incoming, Style.ERROR).show();
- }
-
- @Override
- public void showErrorConnectionFailed() {
- Notify.create(getActivity(), R.string.transfer_error_connect, Style.ERROR).show();
- }
-
- @Override
- public void showErrorListenFailed() {
- Notify.create(getActivity(), R.string.transfer_error_listen, Style.ERROR).show();
- }
-
- @Override
- public void showErrorConnectionError(String errorMessage) {
- if (errorMessage != null) {
- String text = getString(R.string.transfer_error_generic_msg, errorMessage);
- Notify.create(getActivity(), text, Style.ERROR).show();
- } else {
- Notify.create(getActivity(), R.string.transfer_error_generic, Style.ERROR).show();
- }
- }
-
- @Override
- public void showResultNotification(ImportKeyResult result) {
- result.createNotify(getActivity()).show();
- }
-
- @Override
- public void addFakeBackStackItem(final String tag) {
- FragmentManager fragmentManager = getFragmentManager();
-
- fragmentManager.beginTransaction()
- .addToBackStack(tag)
- .commitAllowingStateLoss();
- fragmentManager.executePendingTransactions();
-
- fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
- @Override
- public void onBackStackChanged() {
- FragmentManager fragMan = getFragmentManager();
- if (fragMan == null) {
- return;
- }
- fragMan.popBackStack(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
- fragMan.removeOnBackStackChangedListener(this);
-
- presenter.onUiBackStackPop();
- }
- });
- }
-
- @Override
- public void finishFragmentOrActivity() {
- FragmentActivity activity = getActivity();
- if (activity != null) {
- if (activity instanceof MainActivity) {
- ((MainActivity) activity).onKeysSelected();
- } else {
- activity.finish();
- }
- }
- }
-
- @Override
- public void showConfirmSendDialog() {
- if (confirmationDialog != null) {
- return;
- }
- confirmationDialog = new Builder(getContext())
- .setTitle(R.string.transfer_confirm_title)
- .setMessage(R.string.transfer_confirm_text)
- .setPositiveButton(R.string.transfer_confirm_ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- if (whichButton == DialogInterface.BUTTON_POSITIVE) {
- presenter.onUiClickConfirmSend();
- } else {
- dialog.dismiss();
- }
- }
- })
- .setNegativeButton(R.string.transfer_confirm_cancel, null)
- .setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- confirmationDialog = null;
- }
- })
- .create();
- confirmationDialog.show();
- }
-
- @Override
- public void dismissConfirmationIfExists() {
- if (confirmationDialog != null && confirmationDialog.isShowing()) {
- confirmationDialog.dismiss();
- }
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (currentCryptoOperationHelper != null &&
- currentCryptoOperationHelper.handleActivityResult(requestCode, resultCode, data)) {
- return;
- }
-
- switch (requestCode) {
- case REQUEST_CODE_SCAN:
- if (resultCode == Activity.RESULT_OK) {
- String qrCodeData = data.getStringExtra(Intents.Scan.RESULT);
- presenter.onUiQrCodeScanned(qrCodeData);
- }
- break;
- default:
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferNotAvailableFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferNotAvailableFragment.java
deleted file mode 100644
index a45de3191..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferNotAvailableFragment.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.ui.transfer.view;
-
-
-import android.os.Bundle;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import org.sufficientlysecure.keychain.R;
-
-
-public class TransferNotAvailableFragment extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return inflater.inflate(R.layout.transfer_not_available_fragment, container, false);
- }
-}
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
deleted file mode 100644
index 2f9e5b8f2..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/transfer/view/TransferSecretKeyList.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2017 Schürmann & Breitmoser GbR
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.sufficientlysecure.keychain.ui.transfer.view;
-
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.content.Context;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import android.text.format.DateUtils;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import android.widget.ViewAnimator;
-
-import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
-import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
-
-
-public class TransferSecretKeyList extends RecyclerView {
- private static final int STATE_INVISIBLE = 0;
- private static final int STATE_BUTTON = 1;
- private static final int STATE_PROGRESS = 2;
- private static final int STATE_TRANSFERRED = 3;
- // private static final int STATE_IMPORT_BUTTON = 4; // used in ReceivedSecretKeyList
-
-
- public TransferSecretKeyList(Context context) {
- super(context);
- init(context);
- }
-
- public TransferSecretKeyList(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public TransferSecretKeyList(Context context, @Nullable AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
-
- private void init(Context context) {
- setLayoutManager(new LinearLayoutManager(context));
- addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL_LIST, true));
- setItemAnimator(null);
- }
-
- public static class TransferKeyAdapter extends RecyclerView.Adapter {
- private final Context context;
- private final LayoutInflater layoutInflater;
- private final OnClickTransferKeyListener onClickTransferKeyListener;
-
- private Long focusedMasterKeyId;
- private List data;
- private ArrayList finishedItems = new ArrayList<>();
- private boolean allItemsDisabled;
-
-
- public TransferKeyAdapter(Context context, LayoutInflater layoutInflater,
- OnClickTransferKeyListener onClickTransferKeyListener) {
- this.context = context;
- this.layoutInflater = layoutInflater;
- this.onClickTransferKeyListener = onClickTransferKeyListener;
- }
-
- @NonNull
- @Override
- public TransferKeyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
- return new TransferKeyViewHolder(layoutInflater.inflate(R.layout.key_transfer_item, parent, false));
- }
-
- @Override
- public void onBindViewHolder(@NonNull TransferKeyViewHolder holder, int position) {
- UnifiedKeyInfo item = data.get(position);
- boolean isFinished = finishedItems.contains(item.master_key_id());
- holder.bind(context, item, onClickTransferKeyListener, focusedMasterKeyId, isFinished, allItemsDisabled);
- }
-
- @Override
- public int getItemCount() {
- return data != null ? data.size() : 0;
- }
-
- @Override
- public long getItemId(int position) {
- return data.get(position).master_key_id();
- }
-
- public void setData(List data) {
- this.data = data;
- notifyDataSetChanged();
- }
-
- public void clearFinishedItems() {
- finishedItems.clear();
- notifyItemRangeChanged(0, getItemCount());
- }
-
- public void addToFinishedItems(long masterKeyId) {
- finishedItems.add(masterKeyId);
- // doeesn't notify, because it's non-trivial and this is called in conjunction with other refreshing things!
- }
-
- public void focusItem(Long masterKeyId) {
- focusedMasterKeyId = masterKeyId;
- notifyItemRangeChanged(0, getItemCount());
- }
-
- public void setAllDisabled(boolean allItemsdisablde) {
- allItemsDisabled = allItemsdisablde;
- notifyItemRangeChanged(0, getItemCount());
- }
- }
-
- static class TransferKeyViewHolder extends RecyclerView.ViewHolder {
- private final TextView vName;
- private final TextView vEmail;
- private final TextView vCreation;
- private final View vSendButton;
- private final ViewAnimator vState;
-
- TransferKeyViewHolder(View itemView) {
- super(itemView);
-
- vName = itemView.findViewById(R.id.key_list_item_name);
- vEmail = itemView.findViewById(R.id.key_list_item_email);
- vCreation = itemView.findViewById(R.id.key_list_item_creation);
-
- vSendButton = itemView.findViewById(R.id.button_transfer);
- vState = itemView.findViewById(R.id.transfer_state);
- }
-
- private void bind(Context context, UnifiedKeyInfo item,
- final OnClickTransferKeyListener onClickTransferKeyListener, Long focusedMasterKeyId,
- boolean isFinished, boolean disableAll) {
- if (item.name() != null) {
- vName.setText(item.name());
- vName.setVisibility(View.VISIBLE);
- } else {
- vName.setVisibility(View.GONE);
- }
- if (item.email() != null) {
- vEmail.setText(item.email());
- vEmail.setVisibility(View.VISIBLE);
- } else {
- vEmail.setVisibility(View.GONE);
- }
-
- String dateTime = DateUtils.formatDateTime(context, item.creation() * 1000,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME |
- DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH);
- vCreation.setText(context.getString(R.string.label_key_created, dateTime));
-
- if (disableAll) {
- itemView.setAlpha(0.2f);
- vState.setDisplayedChild(STATE_INVISIBLE);
- vSendButton.setOnClickListener(null);
- return;
- }
-
- if (focusedMasterKeyId != null) {
- if (focusedMasterKeyId != item.master_key_id()) {
- itemView.animate().alpha(0.2f).start();
- vState.setDisplayedChild(isFinished ? STATE_TRANSFERRED : STATE_INVISIBLE);
- } else {
- itemView.setAlpha(1.0f);
- vState.setDisplayedChild(STATE_PROGRESS);
- }
- } else {
- itemView.animate().alpha(1.0f).start();
- vState.setDisplayedChild(isFinished ? STATE_TRANSFERRED : STATE_BUTTON);
- }
-
- if (focusedMasterKeyId == null && onClickTransferKeyListener != null) {
- vSendButton.setOnClickListener(
- v -> onClickTransferKeyListener.onUiClickTransferKey(item.master_key_id()));
- } else {
- vSendButton.setOnClickListener(null);
- }
- }
- }
-
- public interface OnClickTransferKeyListener {
- void onUiClickTransferKey(long masterKeyId);
- }
-}
diff --git a/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml
index 64be0789f..15420c92b 100644
--- a/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/create_key_start_fragment.xml
@@ -116,24 +116,6 @@
android:clickable="true"
style="?android:attr/borderlessButtonStyle" />
-
-
-
-
- "Close navigation drawer"
"My Keys"
"Backup/Restore"
- "Secure Wifi Transfer"
"Type text"
diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/network/KeyTransferInteractorTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/network/KeyTransferInteractorTest.java
deleted file mode 100644
index 1e8f33b37..000000000
--- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/network/KeyTransferInteractorTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.sufficientlysecure.keychain.network;
-
-
-import java.net.URISyntaxException;
-
-import android.os.Build.VERSION_CODES;
-import androidx.annotation.RequiresApi;
-
-import junit.framework.Assert;
-import org.robolectric.shadows.ShadowLog;
-import org.robolectric.shadows.ShadowLooper;
-import org.sufficientlysecure.keychain.network.KeyTransferInteractor.KeyTransferCallback;
-
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-
-
-@SuppressWarnings("WeakerAccess")
-// disabled, because we can't easily mock the tls-psk ciphersuite (it's removed in bouncycastle) :(
-//@RunWith(KeychainTestRunner.class)
-@RequiresApi(api = VERSION_CODES.LOLLIPOP)
-public class KeyTransferInteractorTest {
- private static final String DELIM_START = "--";
- private static final String DELIM_END = "--";
-
- private String receivedQrCodeData;
- private boolean clientConnectionEstablished;
- private boolean serverConnectionEstablished;
-
-// @Before
- public void setUp() throws Exception {
- ShadowLog.stream = System.out;
- }
-
-// @Test
- public void testServerShouldGiveSuccessCallback() throws URISyntaxException {
- KeyTransferInteractor serverKeyTransferInteractor = new KeyTransferInteractor(DELIM_START, DELIM_END);
-
- serverKeyTransferInteractor.startServer(new SimpleKeyTransferCallback() {
- @Override
- public void onServerStarted(String qrCodeData) {
- receivedQrCodeData = qrCodeData;
- }
-
- @Override
- public void onConnectionEstablished(String otherName) {
- serverConnectionEstablished = true;
- }
- }, null);
- waitForLooperCallback();
- Assert.assertNotNull(receivedQrCodeData);
-
- final KeyTransferInteractor clientKeyTransferInteractor = new KeyTransferInteractor(DELIM_START, DELIM_END);
- clientKeyTransferInteractor.connectToServer(receivedQrCodeData, new SimpleKeyTransferCallback() {
- @Override
- public void onConnectionEstablished(String otherName) {
- clientConnectionEstablished = true;
- }
- });
- waitForLooperCallback();
- waitForLooperCallback();
-
- assertTrue(clientConnectionEstablished);
- assertTrue(serverConnectionEstablished);
-
- serverKeyTransferInteractor.sendData(new byte[] { (byte) 1, (byte) 2 }, "passthrough");
- waitForLooperCallback();
- }
-
- private void waitForLooperCallback() {
- while (!ShadowLooper.getShadowMainLooper().getScheduler().runOneTask());
- }
-
-
- static class SimpleKeyTransferCallback implements KeyTransferCallback {
- @Override
- public void onServerStarted(String qrCodeData) {
- fail("unexpected callback: onServerStarted");
- }
-
- @Override
- public void onConnectionEstablished(String otherName) {
- fail("unexpected callback: onConnectionEstablished");
- }
-
- @Override
- public void onConnectionLost() {
- fail("unexpected callback: onConnectionLost");
- }
-
- @Override
- public void onDataReceivedOk(String receivedData) {
- fail("unexpected callback: onDataReceivedOk");
- }
-
- @Override
- public void onDataSentOk(String passthrough) {
- fail("unexpected callback: onDataSentOk");
- }
-
- @Override
- public void onConnectionErrorNoRouteToHost(String wifiSsid) {
- fail("unexpected callback: onConnectionErrorNoRouteToHost");
- }
-
- @Override
- public void onConnectionErrorConnect() {
- fail("unexpected callback: onConnectionErrorConnect");
- }
-
- @Override
- public void onConnectionErrorListen() {
- fail("unexpected callback: onConnectionErrorListen");
- }
-
- @Override
- public void onConnectionError(String arg) {
- fail("unexpected callback: onConnectionError");
- }
- }
-
-}
diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/network/SktUriTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/network/SktUriTest.java
deleted file mode 100644
index 8e15691c5..000000000
--- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/network/SktUriTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.sufficientlysecure.keychain.network;
-
-
-import java.net.URISyntaxException;
-
-import android.annotation.SuppressLint;
-
-import org.bouncycastle.util.encoders.Hex;
-import org.junit.Test;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-
-@SuppressWarnings("WeakerAccess")
-@SuppressLint("DefaultLocale")
-public class SktUriTest {
- static final String HOST = "127.0.0.1";
- static final int PORT = 1234;
- static final byte[] PRESHARED_KEY = { 1, 2 };
- static final String SSID = "ssid";
-
- static final String ENCODED_SKT = String.format("OPGPSKT:%s/%d/%s/SSID:%s",
- HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes()));
-
- @Test
- public void testCreate() {
- SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, null);
-
- assertEquals(HOST, sktUri.getHost());
- assertEquals(PORT, sktUri.getPort());
- assertArrayEquals(PRESHARED_KEY, sktUri.getPresharedKey());
- assertEquals(null, sktUri.getWifiSsid());
- }
-
- @Test
- public void testCreateWithSsid() {
- SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, SSID);
-
- assertEquals(HOST, sktUri.getHost());
- assertEquals(PORT, sktUri.getPort());
- assertArrayEquals(PRESHARED_KEY, sktUri.getPresharedKey());
- assertEquals(SSID, sktUri.getWifiSsid());
- }
-
- @Test
- public void testCreate_isAllUppercase() {
- SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, SSID);
-
- String encodedSktUri = sktUri.toUriString();
- assertEquals(encodedSktUri.toUpperCase(), encodedSktUri);
- }
-
- @Test
- public void testParse() throws URISyntaxException {
- SktUri sktUri = SktUri.parse(ENCODED_SKT);
-
- assertNotNull(sktUri);
- assertEquals(HOST, sktUri.getHost());
- assertEquals(PORT, sktUri.getPort());
- assertArrayEquals(PRESHARED_KEY, sktUri.getPresharedKey());
- assertEquals(SSID, sktUri.getWifiSsid());
- }
-
- @Test
- public void testBackAndForth() throws URISyntaxException {
- SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, null);
- String encodedSktUri = sktUri.toUriString();
- SktUri decodedSktUri = SktUri.parse(encodedSktUri);
-
- assertEquals(sktUri, decodedSktUri);
- }
-
- @Test
- public void testBackAndForthWithSsid() throws URISyntaxException {
- SktUri sktUri = SktUri.create(HOST, PORT, PRESHARED_KEY, SSID);
- String encodedSktUri = sktUri.toUriString();
- SktUri decodedSktUri = SktUri.parse(encodedSktUri);
-
- assertEquals(sktUri, decodedSktUri);
- }
-
- @Test(expected = URISyntaxException.class)
- public void testParse_withBadScheme_shouldFail() throws URISyntaxException {
- SktUri.parse(String.format("XXXGPSKT:%s/%d/%s/SSID:%s",
- HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes())));
- }
-
- @Test(expected = URISyntaxException.class)
- public void testParse_withBadPsk_shouldFail() throws URISyntaxException {
- SktUri.parse(String.format("OPGPSKT:%s/%d/xx%s/SSID:%s",
- HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes())));
- }
-
- @Test(expected = URISyntaxException.class)
- public void testParse_withBadPort_shouldFail() throws URISyntaxException {
- SktUri.parse(String.format("OPGPSKT:%s/x%d/%s/SSID:%s",
- HOST, PORT, Hex.toHexString(PRESHARED_KEY), Hex.toHexString(SSID.getBytes())));
- }
-}
\ No newline at end of file