aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2018-03-20 21:33:54 +0100
committerChristian Schneppe <christian@pix-art.de>2018-03-20 21:33:54 +0100
commit76e10f17a62f867116c146d7be9da3ea8dfc311d (patch)
tree63ca6a8902078517e5dd8447a78decb65f3fa6f0 /src/main/java/de/pixart
parent7df82563ab8650e3694a2b64acc9864e443078f3 (diff)
parent17d279b9c3f7dfa716592cca9f5fb2c9f3dd3cf6 (diff)
Merge branch 'app_compat'
Diffstat (limited to 'src/main/java/de/pixart')
-rw-r--r--src/main/java/de/pixart/messenger/Config.java2
-rw-r--r--src/main/java/de/pixart/messenger/crypto/DomainHostnameVerifier.java10
-rw-r--r--src/main/java/de/pixart/messenger/crypto/XmppDomainVerifier.java2
-rw-r--r--src/main/java/de/pixart/messenger/entities/MTMDecision.java33
-rw-r--r--src/main/java/de/pixart/messenger/generator/PresenceGenerator.java2
-rw-r--r--src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java904
-rw-r--r--src/main/java/de/pixart/messenger/services/XmppConnectionService.java1
-rw-r--r--src/main/java/de/pixart/messenger/ui/AboutActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/AbstractSearchableListItemActivity.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/BlockContactDialog.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/ChangePasswordActivity.java53
-rw-r--r--src/main/java/de/pixart/messenger/ui/ChooseContactActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java231
-rw-r--r--src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java223
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationActivity.java476
-rw-r--r--src/main/java/de/pixart/messenger/ui/ConversationFragment.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/EditAccountActivity.java453
-rw-r--r--src/main/java/de/pixart/messenger/ui/EnterJidDialog.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/LocationActivity.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java6
-rw-r--r--src/main/java/de/pixart/messenger/ui/MemorizingActivity.java119
-rw-r--r--src/main/java/de/pixart/messenger/ui/OmemoActivity.java148
-rw-r--r--src/main/java/de/pixart/messenger/ui/RecordingActivity.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/SetPresenceActivity.java80
-rw-r--r--src/main/java/de/pixart/messenger/ui/SettingsActivity.java185
-rw-r--r--src/main/java/de/pixart/messenger/ui/SettingsFragment.java76
-rw-r--r--src/main/java/de/pixart/messenger/ui/ShareLocationActivity.java6
-rw-r--r--src/main/java/de/pixart/messenger/ui/ShareViaAccountActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/ShareWithActivity.java6
-rw-r--r--src/main/java/de/pixart/messenger/ui/ShowFullscreenMessageActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/ShowLocationActivity.java10
-rw-r--r--src/main/java/de/pixart/messenger/ui/StartConversationActivity.java132
-rw-r--r--src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java149
-rw-r--r--src/main/java/de/pixart/messenger/ui/UpdaterActivity.java2
-rw-r--r--src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/VerifyOTRActivity.java6
-rw-r--r--src/main/java/de/pixart/messenger/ui/WelcomeActivity.java10
-rw-r--r--src/main/java/de/pixart/messenger/ui/XmppActivity.java15
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java36
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java3
-rw-r--r--src/main/java/de/pixart/messenger/ui/widget/DisabledActionModeCallback.java55
-rw-r--r--src/main/java/de/pixart/messenger/ui/widget/EditMessage.java12
-rw-r--r--src/main/java/de/pixart/messenger/ui/widget/Switch.java68
-rw-r--r--src/main/java/de/pixart/messenger/utils/ExceptionHelper.java2
-rw-r--r--src/main/java/de/pixart/messenger/utils/UIHelper.java15
-rw-r--r--src/main/java/de/pixart/messenger/utils/zxing/IntentIntegrator.java2
-rw-r--r--src/main/java/de/pixart/messenger/xmpp/XmppConnection.java4
49 files changed, 2244 insertions, 1334 deletions
diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java
index 8783e1c64..60f2410aa 100644
--- a/src/main/java/de/pixart/messenger/Config.java
+++ b/src/main/java/de/pixart/messenger/Config.java
@@ -114,6 +114,8 @@ public final class Config {
public static final boolean X509_VERIFICATION = false; //use x509 certificates to verify OMEMO keys
+ public static final boolean ONLY_INTERNAL_STORAGE = false; //use internal storage instead of sdcard to save attachments
+
public static final boolean IGNORE_ID_REWRITE_IN_MUC = true;
public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY * 5;
diff --git a/src/main/java/de/pixart/messenger/crypto/DomainHostnameVerifier.java b/src/main/java/de/pixart/messenger/crypto/DomainHostnameVerifier.java
new file mode 100644
index 000000000..0ceb650f3
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/crypto/DomainHostnameVerifier.java
@@ -0,0 +1,10 @@
+package de.pixart.messenger.crypto;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+public interface DomainHostnameVerifier extends HostnameVerifier {
+
+ boolean verify(String domain, String hostname, SSLSession sslSession);
+
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/crypto/XmppDomainVerifier.java b/src/main/java/de/pixart/messenger/crypto/XmppDomainVerifier.java
index e811a0f39..3f3c358a7 100644
--- a/src/main/java/de/pixart/messenger/crypto/XmppDomainVerifier.java
+++ b/src/main/java/de/pixart/messenger/crypto/XmppDomainVerifier.java
@@ -25,8 +25,6 @@ import java.util.List;
import javax.net.ssl.SSLSession;
-import de.duenndns.ssl.DomainHostnameVerifier;
-
public class XmppDomainVerifier implements DomainHostnameVerifier {
private static final String LOGTAG = "XmppDomainVerifier";
diff --git a/src/main/java/de/pixart/messenger/entities/MTMDecision.java b/src/main/java/de/pixart/messenger/entities/MTMDecision.java
new file mode 100644
index 000000000..38cc4b578
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/entities/MTMDecision.java
@@ -0,0 +1,33 @@
+/* MemorizingTrustManager - a TrustManager which asks the user about invalid
+ * certificates and memorizes their decision.
+ *
+ * Copyright (c) 2010 Georg Lukas <georg@op-co.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package de.pixart.messenger.entities;
+
+public class MTMDecision {
+ public final static int DECISION_INVALID = 0;
+ public final static int DECISION_ABORT = 1;
+ public final static int DECISION_ONCE = 2;
+ public final static int DECISION_ALWAYS = 3;
+
+ public int state = DECISION_INVALID;
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/generator/PresenceGenerator.java b/src/main/java/de/pixart/messenger/generator/PresenceGenerator.java
index a6e46cb76..9bbf2191d 100644
--- a/src/main/java/de/pixart/messenger/generator/PresenceGenerator.java
+++ b/src/main/java/de/pixart/messenger/generator/PresenceGenerator.java
@@ -57,7 +57,7 @@ public class PresenceGenerator extends AbstractGenerator {
Element cap = packet.addChild("c",
"http://jabber.org/protocol/caps");
cap.setAttribute("hash", "sha-1");
- cap.setAttribute("node", "http://conversations.im");
+ cap.setAttribute("node", "http://jabber.pix-art.de");
cap.setAttribute("ver", capHash);
}
return packet;
diff --git a/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java b/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java
new file mode 100644
index 000000000..d98e97a58
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/services/MemorizingTrustManager.java
@@ -0,0 +1,904 @@
+/* MemorizingTrustManager - a TrustManager which asks the user about invalid
+ * certificates and memorizes their decision.
+ *
+ * Copyright (c) 2010 Georg Lukas <georg@op-co.de>
+ *
+ * MemorizingTrustManager.java contains the actual trust manager and interface
+ * code to create a MemorizingActivity and obtain the results.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package de.pixart.messenger.services;
+
+import android.app.Application;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Base64;
+import android.util.Log;
+import android.util.SparseArray;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import de.pixart.messenger.R;
+import de.pixart.messenger.crypto.DomainHostnameVerifier;
+import de.pixart.messenger.entities.MTMDecision;
+import de.pixart.messenger.ui.MemorizingActivity;
+
+/**
+ * A X509 trust manager implementation which asks the user about invalid
+ * certificates and memorizes their decision.
+ * <p>
+ * The certificate validity is checked using the system default X509
+ * TrustManager, creating a query Dialog if the check fails.
+ * <p>
+ * <b>WARNING:</b> This only works if a dedicated thread is used for
+ * opening sockets!
+ */
+public class MemorizingTrustManager {
+
+
+ private static final Pattern PATTERN_IPV4 = Pattern.compile("\\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
+ private static final Pattern PATTERN_IPV6_HEX4DECCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::((?:[0-9A-Fa-f]{1,4}:)*)(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
+ private static final Pattern PATTERN_IPV6_6HEX4DEC = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}:){6,6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\z");
+ private static final Pattern PATTERN_IPV6_HEXCOMPRESSED = Pattern.compile("\\A((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)\\z");
+ private static final Pattern PATTERN_IPV6 = Pattern.compile("\\A(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\\z");
+
+ final static String DECISION_INTENT = "de.duenndns.ssl.DECISION";
+ public final static String DECISION_INTENT_ID = DECISION_INTENT + ".decisionId";
+ public final static String DECISION_INTENT_CERT = DECISION_INTENT + ".cert";
+ final static String DECISION_INTENT_CHOICE = DECISION_INTENT + ".decisionChoice";
+
+ private final static Logger LOGGER = Logger.getLogger(MemorizingTrustManager.class.getName());
+ public final static String DECISION_TITLE_ID = DECISION_INTENT + ".titleId";
+ private final static int NOTIFICATION_ID = 100509;
+
+ final static String NO_TRUST_ANCHOR = "Trust anchor for certification path not found.";
+
+ static String KEYSTORE_DIR = "KeyStore";
+ static String KEYSTORE_FILE = "KeyStore.bks";
+
+ Context master;
+ AppCompatActivity foregroundAct;
+ NotificationManager notificationManager;
+ private static int decisionId = 0;
+ private static SparseArray<MTMDecision> openDecisions = new SparseArray<MTMDecision>();
+
+ Handler masterHandler;
+ private File keyStoreFile;
+ private KeyStore appKeyStore;
+ private X509TrustManager defaultTrustManager;
+ private X509TrustManager appTrustManager;
+ private String poshCacheDir;
+
+ /** Creates an instance of the MemorizingTrustManager class that falls back to a custom TrustManager.
+ *
+ * You need to supply the application context. This has to be one of:
+ * - Application
+ * - Activity
+ * - Service
+ *
+ * The context is used for file management, to display the dialog /
+ * notification and for obtaining translated strings.
+ *
+ * @param m Context for the application.
+ * @param defaultTrustManager Delegate trust management to this TM. If null, the user must accept every certificate.
+ */
+ public MemorizingTrustManager(Context m, X509TrustManager defaultTrustManager) {
+ init(m);
+ this.appTrustManager = getTrustManager(appKeyStore);
+ this.defaultTrustManager = defaultTrustManager;
+ }
+
+ /** Creates an instance of the MemorizingTrustManager class using the system X509TrustManager.
+ *
+ * You need to supply the application context. This has to be one of:
+ * - Application
+ * - Activity
+ * - Service
+ *
+ * The context is used for file management, to display the dialog /
+ * notification and for obtaining translated strings.
+ *
+ * @param m Context for the application.
+ */
+ public MemorizingTrustManager(Context m) {
+ init(m);
+ this.appTrustManager = getTrustManager(appKeyStore);
+ this.defaultTrustManager = getTrustManager(null);
+ }
+
+ void init(Context m) {
+ master = m;
+ masterHandler = new Handler(m.getMainLooper());
+ notificationManager = (NotificationManager)master.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ Application app;
+ if (m instanceof Application) {
+ app = (Application)m;
+ } else if (m instanceof Service) {
+ app = ((Service)m).getApplication();
+ } else if (m instanceof AppCompatActivity) {
+ app = ((AppCompatActivity)m).getApplication();
+ } else throw new ClassCastException("MemorizingTrustManager context must be either Activity or Service!");
+
+ File dir = app.getDir(KEYSTORE_DIR, Context.MODE_PRIVATE);
+ keyStoreFile = new File(dir + File.separator + KEYSTORE_FILE);
+
+ poshCacheDir = app.getFilesDir().getAbsolutePath()+"/posh_cache/";
+
+ appKeyStore = loadAppKeyStore();
+ }
+
+
+ /**
+ * Binds an Activity to the MTM for displaying the query dialog.
+ *
+ * This is useful if your connection is run from a service that is
+ * triggered by user interaction -- in such cases the activity is
+ * visible and the user tends to ignore the service notification.
+ *
+ * You should never have a hidden activity bound to MTM! Use this
+ * function in onResume() and @see unbindDisplayActivity in onPause().
+ *
+ * @param act Activity to be bound
+ */
+ public void bindDisplayActivity(AppCompatActivity act) {
+ foregroundAct = act;
+ }
+
+ /**
+ * Removes an Activity from the MTM display stack.
+ *
+ * Always call this function when the Activity added with
+ * {@link #bindDisplayActivity(AppCompatActivity)} is hidden.
+ *
+ * @param act Activity to be unbound
+ */
+ public void unbindDisplayActivity(AppCompatActivity act) {
+ // do not remove if it was overridden by a different activity
+ if (foregroundAct == act)
+ foregroundAct = null;
+ }
+
+ /**
+ * Changes the path for the KeyStore file.
+ *
+ * The actual filename relative to the app's directory will be
+ * <code>app_<i>dirname</i>/<i>filename</i></code>.
+ *
+ * @param dirname directory to store the KeyStore.
+ * @param filename file name for the KeyStore.
+ */
+ public static void setKeyStoreFile(String dirname, String filename) {
+ KEYSTORE_DIR = dirname;
+ KEYSTORE_FILE = filename;
+ }
+
+ /**
+ * Get a list of all certificate aliases stored in MTM.
+ *
+ * @return an {@link Enumeration} of all certificates
+ */
+ public Enumeration<String> getCertificates() {
+ try {
+ return appKeyStore.aliases();
+ } catch (KeyStoreException e) {
+ // this should never happen, however...
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Get a certificate for a given alias.
+ *
+ * @param alias the certificate's alias as returned by {@link #getCertificates()}.
+ *
+ * @return the certificate associated with the alias or <tt>null</tt> if none found.
+ */
+ public Certificate getCertificate(String alias) {
+ try {
+ return appKeyStore.getCertificate(alias);
+ } catch (KeyStoreException e) {
+ // this should never happen, however...
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Removes the given certificate from MTMs key store.
+ *
+ * <p>
+ * <b>WARNING</b>: this does not immediately invalidate the certificate. It is
+ * well possible that (a) data is transmitted over still existing connections or
+ * (b) new connections are created using TLS renegotiation, without a new cert
+ * check.
+ * </p>
+ * @param alias the certificate's alias as returned by {@link #getCertificates()}.
+ *
+ * @throws KeyStoreException if the certificate could not be deleted.
+ */
+ public void deleteCertificate(String alias) throws KeyStoreException {
+ appKeyStore.deleteEntry(alias);
+ keyStoreUpdated();
+ }
+
+ /**
+ * Creates a new hostname verifier supporting user interaction.
+ *
+ * <p>This method creates a new {@link HostnameVerifier} that is bound to
+ * the given instance of {@link MemorizingTrustManager}, and leverages an
+ * existing {@link HostnameVerifier}. The returned verifier performs the
+ * following steps, returning as soon as one of them succeeds:
+ * </p>
+ * <ol>
+ * <li>Success, if the wrapped defaultVerifier accepts the certificate.</li>
+ * <li>Success, if the server certificate is stored in the keystore under the given hostname.</li>
+ * <li>Ask the user and return accordingly.</li>
+ * <li>Failure on exception.</li>
+ * </ol>
+ *
+ * @param defaultVerifier the {@link HostnameVerifier} that should perform the actual check
+ * @return a new hostname verifier using the MTM's key store
+ *
+ * @throws IllegalArgumentException if the defaultVerifier parameter is null
+ */
+ public DomainHostnameVerifier wrapHostnameVerifier(final HostnameVerifier defaultVerifier, final boolean interactive) {
+ if (defaultVerifier == null)
+ throw new IllegalArgumentException("The default verifier may not be null");
+
+ return new MemorizingHostnameVerifier(defaultVerifier, interactive);
+ }
+
+ X509TrustManager getTrustManager(KeyStore ks) {
+ try {
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
+ tmf.init(ks);
+ for (TrustManager t : tmf.getTrustManagers()) {
+ if (t instanceof X509TrustManager) {
+ return (X509TrustManager)t;
+ }
+ }
+ } catch (Exception e) {
+ // Here, we are covering up errors. It might be more useful
+ // however to throw them out of the constructor so the
+ // embedding app knows something went wrong.
+ LOGGER.log(Level.SEVERE, "getTrustManager(" + ks + ")", e);
+ }
+ return null;
+ }
+
+ KeyStore loadAppKeyStore() {
+ KeyStore ks;
+ try {
+ ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ } catch (KeyStoreException e) {
+ LOGGER.log(Level.SEVERE, "getAppKeyStore()", e);
+ return null;
+ }
+ try {
+ ks.load(null, null);
+ ks.load(new java.io.FileInputStream(keyStoreFile), "MTM".toCharArray());
+ } catch (java.io.FileNotFoundException e) {
+ LOGGER.log(Level.INFO, "getAppKeyStore(" + keyStoreFile + ") - file does not exist");
+ } catch (Exception e) {
+ LOGGER.log(Level.SEVERE, "getAppKeyStore(" + keyStoreFile + ")", e);
+ }
+ return ks;
+ }
+
+ void storeCert(String alias, Certificate cert) {
+ try {
+ appKeyStore.setCertificateEntry(alias, cert);
+ } catch (KeyStoreException e) {
+ LOGGER.log(Level.SEVERE, "storeCert(" + cert + ")", e);
+ return;
+ }
+ keyStoreUpdated();
+ }
+
+ void storeCert(X509Certificate cert) {
+ storeCert(cert.getSubjectDN().toString(), cert);
+ }
+
+ void keyStoreUpdated() {
+ // reload appTrustManager
+ appTrustManager = getTrustManager(appKeyStore);
+
+ // store KeyStore to file
+ java.io.FileOutputStream fos = null;
+ try {
+ fos = new java.io.FileOutputStream(keyStoreFile);
+ appKeyStore.store(fos, "MTM".toCharArray());
+ } catch (Exception e) {
+ LOGGER.log(Level.SEVERE, "storeCert(" + keyStoreFile + ")", e);
+ } finally {
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (IOException e) {
+ LOGGER.log(Level.SEVERE, "storeCert(" + keyStoreFile + ")", e);
+ }
+ }
+ }
+ }
+
+ // if the certificate is stored in the app key store, it is considered "known"
+ private boolean isCertKnown(X509Certificate cert) {
+ try {
+ return appKeyStore.getCertificateAlias(cert) != null;
+ } catch (KeyStoreException e) {
+ return false;
+ }
+ }
+
+ private boolean isExpiredException(Throwable e) {
+ do {
+ if (e instanceof CertificateExpiredException)
+ return true;
+ e = e.getCause();
+ } while (e != null);
+ return false;
+ }
+
+ public void checkCertTrusted(X509Certificate[] chain, String authType, String domain, boolean isServer, boolean interactive)
+ throws CertificateException
+ {
+ LOGGER.log(Level.FINE, "checkCertTrusted(" + chain + ", " + authType + ", " + isServer + ")");
+ try {
+ LOGGER.log(Level.FINE, "checkCertTrusted: trying appTrustManager");
+ if (isServer)
+ appTrustManager.checkServerTrusted(chain, authType);
+ else
+ appTrustManager.checkClientTrusted(chain, authType);
+ } catch (CertificateException ae) {
+ LOGGER.log(Level.FINER, "checkCertTrusted: appTrustManager failed", ae);
+ // if the cert is stored in our appTrustManager, we ignore expiredness
+ if (isExpiredException(ae)) {
+ LOGGER.log(Level.INFO, "checkCertTrusted: accepting expired certificate from keystore");
+ return;
+ }
+ if (isCertKnown(chain[0])) {
+ LOGGER.log(Level.INFO, "checkCertTrusted: accepting cert already stored in keystore");
+ return;
+ }
+ try {
+ if (defaultTrustManager == null)
+ throw ae;
+ LOGGER.log(Level.FINE, "checkCertTrusted: trying defaultTrustManager");
+ if (isServer)
+ defaultTrustManager.checkServerTrusted(chain, authType);
+ else
+ defaultTrustManager.checkClientTrusted(chain, authType);
+ } catch (CertificateException e) {
+ boolean trustSystemCAs = !PreferenceManager.getDefaultSharedPreferences(master).getBoolean("dont_trust_system_cas", false);
+ if (domain != null && isServer && trustSystemCAs && !isIp(domain)) {
+ String hash = getBase64Hash(chain[0],"SHA-256");
+ List<String> fingerprints = getPoshFingerprints(domain);
+ if (hash != null && fingerprints.contains(hash)) {
+ Log.d("mtm","trusted cert fingerprint of "+domain+" via posh");
+ return;
+ }
+ }
+ e.printStackTrace();
+ if (interactive) {
+ interactCert(chain, authType, e);
+ } else {
+ throw e;
+ }
+ }
+ }
+ }
+
+ private List<String> getPoshFingerprints(String domain) {
+ List<String> cached = getPoshFingerprintsFromCache(domain);
+ if (cached == null) {
+ return getPoshFingerprintsFromServer(domain);
+ } else {
+ return cached;
+ }
+ }
+
+ private List<String> getPoshFingerprintsFromServer(String domain) {
+ return getPoshFingerprintsFromServer(domain, "https://"+domain+"/.well-known/posh/xmpp-client.json",-1,true);
+ }
+
+ private List<String> getPoshFingerprintsFromServer(String domain, String url, int maxTtl, boolean followUrl) {
+ Log.d("mtm","downloading json for "+domain+" from "+url);
+ try {
+ List<String> results = new ArrayList<>();
+ HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
+ connection.setConnectTimeout(5000);
+ connection.setReadTimeout(5000);
+ BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String inputLine;
+ StringBuilder builder = new StringBuilder();
+ while ((inputLine = in.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ JSONObject jsonObject = new JSONObject(builder.toString());
+ in.close();
+ int expires = jsonObject.getInt("expires");
+ if (expires <= 0) {
+ return new ArrayList<>();
+ }
+ if (maxTtl >= 0) {
+ expires = Math.min(maxTtl,expires);
+ }
+ String redirect;
+ try {
+ redirect = jsonObject.getString("url");
+ } catch (JSONException e) {
+ redirect = null;
+ }
+ if (followUrl && redirect != null && redirect.toLowerCase().startsWith("https")) {
+ return getPoshFingerprintsFromServer(domain, redirect, expires, false);
+ }
+ JSONArray fingerprints = jsonObject.getJSONArray("fingerprints");
+ for(int i = 0; i < fingerprints.length(); i++) {
+ JSONObject fingerprint = fingerprints.getJSONObject(i);
+ String sha256 = fingerprint.getString("sha-256");
+ if (sha256 != null) {
+ results.add(sha256);
+ }
+ }
+ writeFingerprintsToCache(domain, results,1000L * expires+System.currentTimeMillis());
+ return results;
+ } catch (Exception e) {
+ Log.d("mtm","error fetching posh "+e.getMessage());
+ return new ArrayList<>();
+ }
+ }
+
+ private File getPoshCacheFile(String domain) {
+ return new File(poshCacheDir+domain+".json");
+ }
+
+ private void writeFingerprintsToCache(String domain, List<String> results, long expires) {
+ File file = getPoshCacheFile(domain);
+ file.getParentFile().mkdirs();
+ try {
+ file.createNewFile();
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("expires",expires);
+ jsonObject.put("fingerprints",new JSONArray(results));
+ FileOutputStream outputStream = new FileOutputStream(file);
+ outputStream.write(jsonObject.toString().getBytes());
+ outputStream.flush();
+ outputStream.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private List<String> getPoshFingerprintsFromCache(String domain) {
+ File file = getPoshCacheFile(domain);
+ try {
+ InputStream is = new FileInputStream(file);
+ BufferedReader buf = new BufferedReader(new InputStreamReader(is));
+
+ String line = buf.readLine();
+ StringBuilder sb = new StringBuilder();
+
+ while(line != null){
+ sb.append(line).append("\n");
+ line = buf.readLine();
+ }
+ JSONObject jsonObject = new JSONObject(sb.toString());
+ is.close();
+ long expires = jsonObject.getLong("expires");
+ long expiresIn = expires - System.currentTimeMillis();
+ if (expiresIn < 0) {
+ file.delete();
+ return null;
+ } else {
+ Log.d("mtm","posh fingerprints expire in "+(expiresIn/1000)+"s");
+ }
+ List<String> result = new ArrayList<>();
+ JSONArray jsonArray = jsonObject.getJSONArray("fingerprints");
+ for(int i = 0; i < jsonArray.length(); ++i) {
+ result.add(jsonArray.getString(i));
+ }
+ return result;
+ } catch (FileNotFoundException e) {
+ return null;
+ } catch (IOException e) {
+ return null;
+ } catch (JSONException e) {
+ file.delete();
+ return null;
+ }
+ }
+
+ private static boolean isIp(final String server) {
+ return server != null && (
+ PATTERN_IPV4.matcher(server).matches()
+ || PATTERN_IPV6.matcher(server).matches()
+ || PATTERN_IPV6_6HEX4DEC.matcher(server).matches()
+ || PATTERN_IPV6_HEX4DECCOMPRESSED.matcher(server).matches()
+ || PATTERN_IPV6_HEXCOMPRESSED.matcher(server).matches());
+ }
+
+ private static String getBase64Hash(X509Certificate certificate, String digest) throws CertificateEncodingException {
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance(digest);
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ }
+ md.update(certificate.getEncoded());
+ return Base64.encodeToString(md.digest(),Base64.NO_WRAP);
+ }
+
+ private X509Certificate[] getAcceptedIssuers() {
+ LOGGER.log(Level.FINE, "getAcceptedIssuers()");
+ return defaultTrustManager.getAcceptedIssuers();
+ }
+
+ private int createDecisionId(MTMDecision d) {
+ int myId;
+ synchronized(openDecisions) {
+ myId = decisionId;
+ openDecisions.put(myId, d);
+ decisionId += 1;
+ }
+ return myId;
+ }
+
+ private static String hexString(byte[] data) {
+ StringBuffer si = new StringBuffer();
+ for (int i = 0; i < data.length; i++) {
+ si.append(String.format("%02x", data[i]));
+ if (i < data.length - 1)
+ si.append(":");
+ }
+ return si.toString();
+ }
+
+ private static String certHash(final X509Certificate cert, String digest) {
+ try {
+ MessageDigest md = MessageDigest.getInstance(digest);
+ md.update(cert.getEncoded());
+ return hexString(md.digest());
+ } catch (java.security.cert.CertificateEncodingException e) {
+ return e.getMessage();
+ } catch (java.security.NoSuchAlgorithmException e) {
+ return e.getMessage();
+ }
+ }
+
+ private void certDetails(StringBuffer si, X509Certificate c) {
+ SimpleDateFormat validityDateFormater = new SimpleDateFormat("yyyy-MM-dd");
+ si.append("\n");
+ si.append(c.getSubjectDN().toString());
+ si.append("\n");
+ si.append(validityDateFormater.format(c.getNotBefore()));
+ si.append(" - ");
+ si.append(validityDateFormater.format(c.getNotAfter()));
+ si.append("\nSHA-256: ");
+ si.append(certHash(c, "SHA-256"));
+ si.append("\nSHA-1: ");
+ si.append(certHash(c, "SHA-1"));
+ si.append("\nSigned by: ");
+ si.append(c.getIssuerDN().toString());
+ si.append("\n");
+ }
+
+ private String certChainMessage(final X509Certificate[] chain, CertificateException cause) {
+ Throwable e = cause;
+ LOGGER.log(Level.FINE, "certChainMessage for " + e);
+ StringBuffer si = new StringBuffer();
+ if (e.getCause() != null) {
+ e = e.getCause();
+ // HACK: there is no sane way to check if the error is a "trust anchor
+ // not found", so we use string comparison.
+ if (NO_TRUST_ANCHOR.equals(e.getMessage())) {
+ si.append(master.getString(R.string.mtm_trust_anchor));
+ } else
+ si.append(e.getLocalizedMessage());
+ si.append("\n");
+ }
+ si.append("\n");
+ si.append(master.getString(R.string.mtm_connect_anyway));
+ si.append("\n\n");
+ si.append(master.getString(R.string.mtm_cert_details));
+ for (X509Certificate c : chain) {
+ certDetails(si, c);
+ }
+ return si.toString();
+ }
+
+ private String hostNameMessage(X509Certificate cert, String hostname) {
+ StringBuffer si = new StringBuffer();
+
+ si.append(master.getString(R.string.mtm_hostname_mismatch, hostname));
+ si.append("\n\n");
+ try {
+ Collection<List<?>> sans = cert.getSubjectAlternativeNames();
+ if (sans == null) {
+ si.append(cert.getSubjectDN());
+ si.append("\n");
+ } else for (List<?> altName : sans) {
+ Object name = altName.get(1);
+ if (name instanceof String) {
+ si.append("[");
+ si.append((Integer)altName.get(0));
+ si.append("] ");
+ si.append(name);
+ si.append("\n");
+ }
+ }
+ } catch (CertificateParsingException e) {
+ e.printStackTrace();
+ si.append("<Parsing error: ");
+ si.append(e.getLocalizedMessage());
+ si.append(">\n");
+ }
+ si.append("\n");
+ si.append(master.getString(R.string.mtm_connect_anyway));
+ si.append("\n\n");
+ si.append(master.getString(R.string.mtm_cert_details));
+ certDetails(si, cert);
+ return si.toString();
+ }
+ /**
+ * Returns the top-most entry of the activity stack.
+ *
+ * @return the Context of the currently bound UI or the master context if none is bound
+ */
+ Context getUI() {
+ return (foregroundAct != null) ? foregroundAct : master;
+ }
+
+ int interact(final String message, final int titleId) {
+ /* prepare the MTMDecision blocker object */
+ MTMDecision choice = new MTMDecision();
+ final int myId = createDecisionId(choice);
+
+ masterHandler.post(new Runnable() {
+ public void run() {
+ Intent ni = new Intent(master, MemorizingActivity.class);
+ ni.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ ni.setData(Uri.parse(MemorizingTrustManager.class.getName() + "/" + myId));
+ ni.putExtra(DECISION_INTENT_ID, myId);
+ ni.putExtra(DECISION_INTENT_CERT, message);
+ ni.putExtra(DECISION_TITLE_ID, titleId);
+
+ // we try to directly start the activity and fall back to
+ // making a notification
+ try {
+ getUI().startActivity(ni);
+ } catch (Exception e) {
+ LOGGER.log(Level.FINE, "startActivity(MemorizingActivity)", e);
+ }
+ }
+ });
+
+ LOGGER.log(Level.FINE, "openDecisions: " + openDecisions + ", waiting on " + myId);
+ try {
+ synchronized(choice) { choice.wait(); }
+ } catch (InterruptedException e) {
+ LOGGER.log(Level.FINER, "InterruptedException", e);
+ }
+ LOGGER.log(Level.FINE, "finished wait on " + myId + ": " + choice.state);
+ return choice.state;
+ }
+
+ void interactCert(final X509Certificate[] chain, String authType, CertificateException cause)
+ throws CertificateException
+ {
+ switch (interact(certChainMessage(chain, cause), R.string.mtm_accept_cert)) {
+ case MTMDecision.DECISION_ALWAYS:
+ storeCert(chain[0]); // only store the server cert, not the whole chain
+ case MTMDecision.DECISION_ONCE:
+ break;
+ default:
+ throw (cause);
+ }
+ }
+
+ boolean interactHostname(X509Certificate cert, String hostname)
+ {
+ switch (interact(hostNameMessage(cert, hostname), R.string.mtm_accept_servername)) {
+ case MTMDecision.DECISION_ALWAYS:
+ storeCert(hostname, cert);
+ case MTMDecision.DECISION_ONCE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public static void interactResult(int decisionId, int choice) {
+ MTMDecision d;
+ synchronized(openDecisions) {
+ d = openDecisions.get(decisionId);
+ openDecisions.remove(decisionId);
+ }
+ if (d == null) {
+ LOGGER.log(Level.SEVERE, "interactResult: aborting due to stale decision reference!");
+ return;
+ }
+ synchronized(d) {
+ d.state = choice;
+ d.notify();
+ }
+ }
+
+ class MemorizingHostnameVerifier implements DomainHostnameVerifier {
+ private final HostnameVerifier defaultVerifier;
+ private final boolean interactive;
+
+ public MemorizingHostnameVerifier(HostnameVerifier wrapped, boolean interactive) {
+ this.defaultVerifier = wrapped;
+ this.interactive = interactive;
+ }
+
+ @Override
+ public boolean verify(String domain, String hostname, SSLSession session) {
+ LOGGER.log(Level.FINE, "hostname verifier for " + domain + ", trying default verifier first");
+ // if the default verifier accepts the hostname, we are done
+ if (defaultVerifier instanceof DomainHostnameVerifier) {
+ if (((DomainHostnameVerifier) defaultVerifier).verify(domain,hostname, session)) {
+ return true;
+ }
+ } else {
+ if (defaultVerifier.verify(domain, session)) {
+ return true;
+ }
+ }
+
+
+ // otherwise, we check if the hostname is an alias for this cert in our keystore
+ try {
+ X509Certificate cert = (X509Certificate)session.getPeerCertificates()[0];
+ //Log.d(TAG, "cert: " + cert);
+ if (cert.equals(appKeyStore.getCertificate(domain.toLowerCase(Locale.US)))) {
+ LOGGER.log(Level.FINE, "certificate for " + domain + " is in our keystore. accepting.");
+ return true;
+ } else {
+ LOGGER.log(Level.FINE, "server " + domain + " provided wrong certificate, asking user.");
+ if (interactive) {
+ return interactHostname(cert, domain);
+ } else {
+ return false;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public boolean verify(String domain, SSLSession sslSession) {
+ return verify(domain,null,sslSession);
+ }
+ }
+
+
+ public X509TrustManager getNonInteractive(String domain) {
+ return new NonInteractiveMemorizingTrustManager(domain);
+ }
+
+ public X509TrustManager getInteractive(String domain) {
+ return new InteractiveMemorizingTrustManager(domain);
+ }
+
+ public X509TrustManager getNonInteractive() {
+ return new NonInteractiveMemorizingTrustManager(null);
+ }
+
+ public X509TrustManager getInteractive() {
+ return new InteractiveMemorizingTrustManager(null);
+ }
+
+ private class NonInteractiveMemorizingTrustManager implements X509TrustManager {
+
+ private final String domain;
+
+ public NonInteractiveMemorizingTrustManager(String domain) {
+ this.domain = domain;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, false, false);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, true, false);
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return MemorizingTrustManager.this.getAcceptedIssuers();
+ }
+
+ }
+
+ private class InteractiveMemorizingTrustManager implements X509TrustManager {
+ private final String domain;
+
+ public InteractiveMemorizingTrustManager(String domain) {
+ this.domain = domain;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, false, true);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ MemorizingTrustManager.this.checkCertTrusted(chain, authType, domain, true, true);
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return MemorizingTrustManager.this.getAcceptedIssuers();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
index d26114b47..2c2f0b2d4 100644
--- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
+++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java
@@ -70,7 +70,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-import de.duenndns.ssl.MemorizingTrustManager;
import de.pixart.messenger.BuildConfig;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
diff --git a/src/main/java/de/pixart/messenger/ui/AboutActivity.java b/src/main/java/de/pixart/messenger/ui/AboutActivity.java
index b3b296c42..e00707d96 100644
--- a/src/main/java/de/pixart/messenger/ui/AboutActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/AboutActivity.java
@@ -1,11 +1,11 @@
package de.pixart.messenger.ui;
-import android.app.Activity;
import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
import de.pixart.messenger.R;
-public class AboutActivity extends Activity {
+public class AboutActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/src/main/java/de/pixart/messenger/ui/AbstractSearchableListItemActivity.java b/src/main/java/de/pixart/messenger/ui/AbstractSearchableListItemActivity.java
index 4852c5961..a3536a368 100644
--- a/src/main/java/de/pixart/messenger/ui/AbstractSearchableListItemActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/AbstractSearchableListItemActivity.java
@@ -104,8 +104,7 @@ public abstract class AbstractSearchableListItemActivity extends XmppActivity {
getMenuInflater().inflate(R.menu.choose_contact, menu);
final MenuItem menuSearchView = menu.findItem(R.id.action_search);
final View mSearchView = menuSearchView.getActionView();
- mSearchEditText = mSearchView
- .findViewById(R.id.search_field);
+ mSearchEditText = mSearchView.findViewById(R.id.search_field);
mSearchEditText.addTextChangedListener(mSearchTextWatcher);
menuSearchView.setOnActionExpandListener(mOnActionExpandListener);
return true;
diff --git a/src/main/java/de/pixart/messenger/ui/BlockContactDialog.java b/src/main/java/de/pixart/messenger/ui/BlockContactDialog.java
index 5a911298f..0775d2cf7 100644
--- a/src/main/java/de/pixart/messenger/ui/BlockContactDialog.java
+++ b/src/main/java/de/pixart/messenger/ui/BlockContactDialog.java
@@ -1,6 +1,6 @@
package de.pixart.messenger.ui;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.text.SpannableString;
diff --git a/src/main/java/de/pixart/messenger/ui/ChangePasswordActivity.java b/src/main/java/de/pixart/messenger/ui/ChangePasswordActivity.java
index 49a826f29..f6bec9838 100644
--- a/src/main/java/de/pixart/messenger/ui/ChangePasswordActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ChangePasswordActivity.java
@@ -2,15 +2,16 @@ package de.pixart.messenger.ui;
import android.content.Intent;
import android.os.Bundle;
+import android.support.design.widget.TextInputLayout;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
-import android.widget.TextView;
import android.widget.Toast;
import de.pixart.messenger.R;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.services.XmppConnectionService;
+import de.pixart.messenger.ui.widget.DisabledActionModeCallback;
public class ChangePasswordActivity extends XmppActivity implements XmppConnectionService.OnAccountPasswordChanged {
@@ -21,20 +22,17 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
if (mAccount != null) {
final String currentPassword = mCurrentPassword.getText().toString();
final String newPassword = mNewPassword.getText().toString();
- final String newPasswordConfirm = mNewPasswordConfirm.getText().toString();
if (!mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE) && !currentPassword.equals(mAccount.getPassword())) {
mCurrentPassword.requestFocus();
- mCurrentPassword.setError(getString(R.string.account_status_unauthorized));
- } else if (!newPassword.equals(newPasswordConfirm)) {
- mNewPasswordConfirm.requestFocus();
- mNewPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
+ mCurrentPasswordLayout.setError(getString(R.string.account_status_unauthorized));
+ removeErrorsOnAllBut(mCurrentPasswordLayout);
} else if (newPassword.trim().isEmpty()) {
mNewPassword.requestFocus();
- mNewPassword.setError(getString(R.string.password_should_not_be_empty));
+ mNewPasswordLayout.setError(getString(R.string.password_should_not_be_empty));
+ removeErrorsOnAllBut(mNewPasswordLayout);
} else {
- mCurrentPassword.setError(null);
- mNewPassword.setError(null);
- mNewPasswordConfirm.setError(null);
+ mCurrentPasswordLayout.setError(null);
+ mNewPasswordLayout.setError(null);
xmppConnectionService.updateAccountPasswordOnServer(mAccount, newPassword, ChangePasswordActivity.this);
mChangePasswordButton.setEnabled(false);
mChangePasswordButton.setTextColor(getSecondaryTextColor());
@@ -43,20 +41,18 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
}
}
};
- private TextView mCurrentPasswordLabel;
private EditText mCurrentPassword;
private EditText mNewPassword;
- private EditText mNewPasswordConfirm;
private Account mAccount;
+ private TextInputLayout mNewPasswordLayout;
+ private TextInputLayout mCurrentPasswordLayout;
@Override
void onBackendConnected() {
this.mAccount = extractAccount(getIntent());
if (this.mAccount != null && this.mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) {
- this.mCurrentPasswordLabel.setVisibility(View.GONE);
this.mCurrentPassword.setVisibility(View.GONE);
} else {
- this.mCurrentPasswordLabel.setVisibility(View.VISIBLE);
this.mCurrentPassword.setVisibility(View.VISIBLE);
}
}
@@ -74,10 +70,10 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
});
this.mChangePasswordButton = findViewById(R.id.right_button);
this.mChangePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked);
- this.mCurrentPasswordLabel = findViewById(R.id.current_password_label);
this.mCurrentPassword = findViewById(R.id.current_password);
+ this.mCurrentPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
this.mNewPassword = findViewById(R.id.new_password);
- this.mNewPasswordConfirm = findViewById(R.id.new_password_confirm);
+ this.mNewPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
}
@Override
@@ -104,18 +100,27 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
@Override
public void onPasswordChangeFailed() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mNewPassword.setError(getString(R.string.could_not_change_password));
- mChangePasswordButton.setEnabled(true);
- mChangePasswordButton.setTextColor(getPrimaryTextColor());
- mChangePasswordButton.setText(R.string.change_password);
- }
+ runOnUiThread(() -> {
+ mNewPasswordLayout.setError(getString(R.string.could_not_change_password));
+ mChangePasswordButton.setEnabled(true);
+ mChangePasswordButton.setTextColor(getPrimaryTextColor());
+ mChangePasswordButton.setText(R.string.change_password);
});
}
+ private void removeErrorsOnAllBut(TextInputLayout exception) {
+ if (this.mCurrentPasswordLayout != exception) {
+ this.mCurrentPasswordLayout.setErrorEnabled(false);
+ this.mCurrentPasswordLayout.setError(null);
+ }
+ if (this.mNewPasswordLayout != exception) {
+ this.mNewPasswordLayout.setErrorEnabled(false);
+ this.mNewPasswordLayout.setError(null);
+ }
+
+ }
+
public void refreshUiReal() {
}
diff --git a/src/main/java/de/pixart/messenger/ui/ChooseContactActivity.java b/src/main/java/de/pixart/messenger/ui/ChooseContactActivity.java
index 9d51a1c1d..011c8b051 100644
--- a/src/main/java/de/pixart/messenger/ui/ChooseContactActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ChooseContactActivity.java
@@ -1,10 +1,10 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.StringRes;
+import android.support.v7.app.ActionBar;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
@@ -140,7 +140,7 @@ public class ChooseContactActivity extends AbstractSearchableListItemActivity {
Intent intent = getIntent();
@StringRes
int res = intent != null ? intent.getIntExtra(EXTRA_TITLE_RES_ID, R.string.title_activity_choose_contact) : R.string.title_activity_choose_contact;
- ActionBar bar = getActionBar();
+ ActionBar bar = getSupportActionBar();
if (bar != null) {
try {
bar.setTitle(res);
diff --git a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
index 21442bcd1..fa77b9423 100644
--- a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java
@@ -1,14 +1,21 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
-import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
+import android.content.res.Resources;
+import android.databinding.DataBindingUtil;
+import android.graphics.Bitmap;
import android.graphics.PorterDuff;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.CardView;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
@@ -26,13 +33,16 @@ import android.widget.Toast;
import org.openintents.openpgp.util.OpenPgpUtils;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.PgpEngine;
+import de.pixart.messenger.databinding.ContactBinding;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Bookmark;
import de.pixart.messenger.entities.Contact;
@@ -42,6 +52,7 @@ import de.pixart.messenger.entities.MucOptions.User;
import de.pixart.messenger.services.XmppConnectionService;
import de.pixart.messenger.services.XmppConnectionService.OnConversationUpdate;
import de.pixart.messenger.services.XmppConnectionService.OnMucRosterUpdate;
+import de.pixart.messenger.utils.UIHelper;
import de.pixart.messenger.xmpp.jid.Jid;
public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConfigurationPushed {
@@ -83,10 +94,10 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
private TextView mFullJid;
private TextView mAccountJid;
private LinearLayout membersView;
- private LinearLayout mMoreDetails;
+ private CardView mMoreDetails;
private RelativeLayout mMucSettings;
private TextView mConferenceType;
- private LinearLayout mConferenceInfoTable;
+ private CardView mConferenceInfoTable;
private TextView mConferenceInfoMam;
private TextView mNotifyStatusText;
private ImageButton mChangeConferenceSettingsButton;
@@ -294,29 +305,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
mDestroyButton.setOnClickListener(destroyListener);
mDestroyButton.getBackground().setColorFilter(getWarningButtonColor(), PorterDuff.Mode.MULTIPLY);
mConferenceType = findViewById(R.id.muc_conference_type);
- if (getActionBar() != null) {
- getActionBar().setHomeButtonEnabled(true);
- getActionBar().setDisplayHomeAsUpEnabled(true);
- }
- mEditNickButton.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- quickEdit(mConversation.getMucOptions().getActualNick(),
- 0,
- new OnValueEdited() {
-
- @Override
- public String onValueEdited(String value) {
- if (xmppConnectionService.renameInMuc(mConversation, value, renameCallback)) {
- return null;
- } else {
- return getString(R.string.invalid_username);
- }
- }
- });
- }
- });
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+ mEditNickButton.setOnClickListener(v -> quickEdit(mConversation.getMucOptions().getActualNick(),
+ 0,
+ value -> {
+ if (xmppConnectionService.renameInMuc(mConversation, value, renameCallback)) {
+ return null;
+ } else {
+ return getString(R.string.invalid_username);
+ }
+ }));
this.mAdvancedMode = getPreferences().getBoolean("advanced_muc_mode", false);
this.mConferenceInfoTable = findViewById(R.id.muc_info_more);
this.mConferenceInfoTable.setVisibility(this.mAdvancedMode ? View.VISIBLE : View.GONE);
@@ -600,17 +601,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
} else {
account = mConversation.getAccount().getJid().toBareJid().toString();
}
- if (getActionBar() != null) {
- final ActionBar ab = getActionBar();
- ab.setCustomView(R.layout.ab_title);
- ab.setDisplayShowCustomEnabled(true);
- TextView abtitle = findViewById(android.R.id.text1);
- TextView absubtitle = findViewById(android.R.id.text2);
- abtitle.setText(mConversation.getName());
- abtitle.setSelected(true);
- abtitle.setClickable(false);
- absubtitle.setVisibility(View.GONE);
- absubtitle.setClickable(false);
+ if (getSupportActionBar() != null) {
+ final ActionBar ab = getSupportActionBar();
+ if (ab != null) {
+ ab.setCustomView(R.layout.ab_title);
+ ab.setDisplayShowCustomEnabled(true);
+ TextView abtitle = findViewById(android.R.id.text1);
+ TextView absubtitle = findViewById(android.R.id.text2);
+ abtitle.setText(mConversation.getName());
+ abtitle.setSelected(true);
+ abtitle.setClickable(false);
+ absubtitle.setVisibility(View.GONE);
+ absubtitle.setClickable(false);
+ }
}
ConferenceName.setText(mConversation.getName());
mAccountJid.setText(getString(R.string.using_account, account));
@@ -668,56 +671,44 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
mNotifyStatusText.setText(R.string.notify_only_when_highlighted);
}
- LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ final LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
membersView.removeAllViews();
+ if (inflater == null) {
+ return;
+ }
final ArrayList<User> users = mucOptions.getUsers();
Collections.sort(users);
for (final User user : users) {
+ ContactBinding binding = DataBindingUtil.inflate(inflater, R.layout.contact, membersView, false);
final Contact contact = user.getContact();
- View view = inflater.inflate(R.layout.contact, membersView, false);
- this.setListItemBackgroundOnView(view);
+ final String name = user.getName();
+ this.setListItemBackgroundOnView(binding.getRoot());
if (contact != null && contact.showInRoster()) {
- view.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- switchToContactDetails(contact);
- }
- });
+ binding.getRoot().setOnClickListener((OnClickListener) view -> switchToContactDetails(contact));
}
- registerForContextMenu(view);
- view.setTag(user);
- TextView tvDisplayName = view.findViewById(R.id.contact_display_name);
- TextView tvKey = view.findViewById(R.id.key);
- TextView tvStatus = view.findViewById(R.id.contact_jid);
+ registerForContextMenu(binding.getRoot());
+ binding.getRoot().setTag(user);
if (mAdvancedMode && user.getPgpKeyId() != 0) {
- tvKey.setVisibility(View.VISIBLE);
- tvKey.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- viewPgpKey(user);
- }
- });
- tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
+ binding.key.setVisibility(View.VISIBLE);
+ binding.key.setOnClickListener(v -> viewPgpKey(user));
+ binding.key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
}
- String name = user.getName();
if (contact != null) {
- tvDisplayName.setText(contact.getDisplayName());
- tvStatus.setText((name != null ? name + " \u2022 " : "") + getStatus(user));
+ binding.contactDisplayName.setText(contact.getDisplayName());
+ binding.contactJid.setText((name != null ? name + " \u2022 " : "") + getStatus(user));
} else {
- tvDisplayName.setText(name == null ? "" : name);
- tvStatus.setText(getStatus(user));
+ binding.contactDisplayName.setText(name == null ? "" : name);
+ binding.contactJid.setText(getStatus(user));
}
- ImageView iv = view.findViewById(R.id.contact_photo);
- iv.setImageBitmap(avatarService().get(user, getPixel(48), false));
+ loadAvatar(user, binding.contactPhoto);
if (user.getRole() == MucOptions.Role.NONE) {
- tvDisplayName.setAlpha(INACTIVE_ALPHA);
- tvKey.setAlpha(INACTIVE_ALPHA);
- tvStatus.setAlpha(INACTIVE_ALPHA);
- iv.setAlpha(INACTIVE_ALPHA);
+ binding.contactDisplayName.setAlpha(INACTIVE_ALPHA);
+ binding.key.setAlpha(INACTIVE_ALPHA);
+ binding.contactJid.setAlpha(INACTIVE_ALPHA);
+ binding.contactPhoto.setAlpha(INACTIVE_ALPHA);
}
- membersView.addView(view);
+ membersView.addView(binding.getRoot());
if (mConversation.getMucOptions().canInvite()) {
mInviteButton.setVisibility(View.VISIBLE);
} else {
@@ -780,11 +771,95 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
}
private void displayToast(final String msg) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(ConferenceDetailsActivity.this, msg, Toast.LENGTH_SHORT).show();
+ runOnUiThread(() -> Toast.makeText(ConferenceDetailsActivity.this, msg, Toast.LENGTH_SHORT).show());
+ }
+
+ public static boolean cancelPotentialWork(User user, ImageView imageView) {
+ final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+ if (bitmapWorkerTask != null) {
+ final User old = bitmapWorkerTask.o;
+ if (old == null || user != old) {
+ bitmapWorkerTask.cancel(true);
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
+ if (imageView != null) {
+ final Drawable drawable = imageView.getDrawable();
+ if (drawable instanceof AsyncDrawable) {
+ final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
}
- });
+ }
+ return null;
+ }
+
+ public void loadAvatar(User user, ImageView imageView) {
+ if (cancelPotentialWork(user, imageView)) {
+ final Bitmap bm = avatarService().get(user, getPixel(48), true);
+ if (bm != null) {
+ cancelPotentialWork(user, imageView);
+ imageView.setImageBitmap(bm);
+ imageView.setBackgroundColor(0x00000000);
+ } else {
+ String seed = user.getRealJid() != null ? user.getRealJid().toBareJid().toString() : null;
+ imageView.setBackgroundColor(UIHelper.getColorForName(seed == null ? user.getName() : seed));
+ imageView.setImageDrawable(null);
+ final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
+ final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), null, task);
+ imageView.setImageDrawable(asyncDrawable);
+ try {
+ task.execute(user);
+ } catch (final RejectedExecutionException ignored) {
+ }
+ }
+ }
+ }
+
+ static class AsyncDrawable extends BitmapDrawable {
+ private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
+
+ public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
+ super(res, bitmap);
+ bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
+ }
+
+ public BitmapWorkerTask getBitmapWorkerTask() {
+ return bitmapWorkerTaskReference.get();
+ }
+ }
+
+ class BitmapWorkerTask extends AsyncTask<User, Void, Bitmap> {
+ private final WeakReference<ImageView> imageViewReference;
+ private User o = null;
+
+ private BitmapWorkerTask(ImageView imageView) {
+ imageViewReference = new WeakReference<>(imageView);
+ }
+
+ @Override
+ protected Bitmap doInBackground(User... params) {
+ this.o = params[0];
+ if (imageViewReference.get() == null) {
+ return null;
+ }
+ return avatarService().get(this.o, getPixel(48), isCancelled());
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ if (bitmap != null && !isCancelled()) {
+ final ImageView imageView = imageViewReference.get();
+ if (imageView != null) {
+ imageView.setImageBitmap(bitmap);
+ imageView.setBackgroundColor(0x00000000);
+ }
+ }
+ }
}
}
diff --git a/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java
index ca435d6a5..824546266 100644
--- a/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java
@@ -1,11 +1,10 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
-import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.databinding.DataBindingUtil;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Bundle;
@@ -14,23 +13,19 @@ import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Intents;
import android.support.v4.content.ContextCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.QuickContactBadge;
import android.widget.TextView;
import android.widget.Toast;
-import com.wefika.flowlayout.FlowLayout;
-
import org.openintents.openpgp.util.OpenPgpUtils;
import java.util.List;
@@ -51,6 +46,7 @@ import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.Namespace;
import de.pixart.messenger.utils.UIHelper;
import de.pixart.messenger.utils.XmppUri;
+import de.pixart.messenger.databinding.ActivityContactDetailsBinding;
import de.pixart.messenger.xmpp.OnKeyStatusUpdated;
import de.pixart.messenger.xmpp.OnUpdateBlocklist;
import de.pixart.messenger.xmpp.XmppConnection;
@@ -109,22 +105,11 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
}
};
+
+ ActivityContactDetailsBinding binding;
+
private Jid accountJid;
- private TextView lastseen;
private Jid contactJid;
- private TextView contactDisplayName;
- private TextView contactJidTv;
- private TextView accountJidTv;
- private TextView statusMessage;
- private TextView resource;
- private CheckBox send;
- private CheckBox receive;
- private Button addContactButton;
- private Button mShowInactiveDevicesButton;
- private QuickContactBadge badge;
- private LinearLayout keys;
- private LinearLayout keysWrapper;
- private FlowLayout tags;
private boolean showDynamicTags = false;
private boolean showLastSeen = false;
private boolean showInactiveOmemo = false;
@@ -272,32 +257,15 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
}
this.messageFingerprint = getIntent().getStringExtra("fingerprint");
- setContentView(R.layout.activity_contact_details);
-
- contactDisplayName = findViewById(R.id.contact_display_name);
- contactJidTv = findViewById(R.id.details_contactjid);
- accountJidTv = findViewById(R.id.details_account);
- lastseen = findViewById(R.id.details_lastseen);
- statusMessage = findViewById(R.id.status_message);
- resource = findViewById(R.id.resource);
- send = findViewById(R.id.details_send_presence);
- receive = findViewById(R.id.details_receive_presence);
- badge = findViewById(R.id.details_contact_badge);
- addContactButton = findViewById(R.id.add_contact_button);
- keys = findViewById(R.id.details_contact_keys);
- keysWrapper = findViewById(R.id.keys_wrapper);
- tags = findViewById(R.id.tags);
- mShowInactiveDevicesButton = findViewById(R.id.show_inactive_devices);
- if (getActionBar() != null) {
- getActionBar().setHomeButtonEnabled(true);
- getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ this.binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_details);
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
- mShowInactiveDevicesButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- showInactiveOmemo = !showInactiveOmemo;
- populateView();
- }
+ binding.showInactiveDevices.setOnClickListener(v -> {
+ showInactiveOmemo = !showInactiveOmemo;
+ populateView();
});
this.mNotifyStatusButton = findViewById(R.id.notification_status_button);
this.mNotifyStatusButton.setOnClickListener(this.mNotifyStatusClickListener);
@@ -409,34 +377,39 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
mNotifyStatusButton.setImageResource(R.drawable.ic_notifications_grey600_24dp);
mNotifyStatusText.setText(R.string.notify_on_all_messages);
}
- if (getActionBar() != null) {
- final ActionBar ab = getActionBar();
- ab.setCustomView(R.layout.ab_title);
- ab.setDisplayShowCustomEnabled(true);
- TextView abtitle = findViewById(android.R.id.text1);
- TextView absubtitle = findViewById(android.R.id.text2);
- abtitle.setText(contact.getDisplayName());
- abtitle.setSelected(true);
- abtitle.setClickable(false);
- absubtitle.setVisibility(View.GONE);
- absubtitle.setClickable(false);
+ if (getSupportActionBar() != null) {
+ final ActionBar ab = getSupportActionBar();
+ if (ab != null) {
+ ab.setCustomView(R.layout.ab_title);
+ ab.setDisplayShowCustomEnabled(true);
+ TextView abtitle = findViewById(android.R.id.text1);
+ TextView absubtitle = findViewById(android.R.id.text2);
+ abtitle.setText(contact.getDisplayName());
+ abtitle.setSelected(true);
+ abtitle.setClickable(false);
+ absubtitle.setVisibility(View.GONE);
+ absubtitle.setClickable(false);
+ }
}
invalidateOptionsMenu();
setTitle(contact.getDisplayName());
if (contact.getServer().toString().toLowerCase().equals(accountJid.getDomainpart().toLowerCase())) {
- contactDisplayName.setText(contact.getDisplayName());
+ binding.contactDisplayName.setText(contact.getDisplayName());
} else {
- contactDisplayName.setText(contact.getDisplayJid());
+ binding.contactDisplayName.setText(contact.getDisplayJid());
}
if (contact.showInRoster()) {
- send.setVisibility(View.VISIBLE);
- receive.setVisibility(View.VISIBLE);
- addContactButton.setVisibility(View.VISIBLE);
- addContactButton.setText(getString(R.string.action_delete_contact));
- addContactButton.getBackground().setColorFilter(getWarningButtonColor(), PorterDuff.Mode.MULTIPLY);
+ binding.detailsSendPresence.setVisibility(View.VISIBLE);
+ binding.detailsReceivePresence.setVisibility(View.VISIBLE);
+ binding.addContactButton.setVisibility(View.VISIBLE);
+ binding.addContactButton.setText(getString(R.string.action_delete_contact));
+ binding.addContactButton.getBackground().setColorFilter(getWarningButtonColor(), PorterDuff.Mode.MULTIPLY);
+ binding.detailsSendPresence.setOnCheckedChangeListener(null);
+ binding.detailsReceivePresence.setOnCheckedChangeListener(null);
+
final AlertDialog.Builder deleteFromRosterDialog = new AlertDialog.Builder(ContactDetailsActivity.this);
- addContactButton.setOnClickListener(new OnClickListener() {
+ binding.addContactButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
deleteFromRosterDialog.setNegativeButton(getString(R.string.cancel), null);
@@ -448,15 +421,15 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
removeFromRoster).create().show();
}
});
- send.setOnCheckedChangeListener(null);
- receive.setOnCheckedChangeListener(null);
+ binding.detailsSendPresence.setOnCheckedChangeListener(null);
+ binding.detailsReceivePresence.setOnCheckedChangeListener(null);
List<String> statusMessages = contact.getPresences().getStatusMessages();
if (statusMessages.size() == 0) {
- statusMessage.setVisibility(View.GONE);
+ binding.statusMessage.setVisibility(View.GONE);
} else {
StringBuilder builder = new StringBuilder();
- statusMessage.setVisibility(View.VISIBLE);
+ binding.statusMessage.setVisibility(View.VISIBLE);
int s = statusMessages.size();
for (int i = 0; i < s; ++i) {
if (s > 1) {
@@ -467,85 +440,85 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
builder.append("\n");
}
}
- statusMessage.setText(builder);
+ binding.statusMessage.setText(builder);
}
String resources = contact.getPresences().getMostAvailableResource();
if (resources.length() == 0) {
- resource.setVisibility(View.GONE);
+ binding.resource.setVisibility(View.GONE);
} else {
- resource.setVisibility(View.VISIBLE);
- resource.setText(resources);
+ binding.resource.setVisibility(View.VISIBLE);
+ binding.resource.setText(resources);
}
if (contact.getOption(Contact.Options.FROM)) {
- send.setText(R.string.send_presence_updates);
- send.setChecked(true);
+ binding.detailsSendPresence.setText(R.string.send_presence_updates);
+ binding.detailsSendPresence.setChecked(true);
} else if (contact.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
- send.setChecked(false);
- send.setText(R.string.send_presence_updates);
+ binding.detailsSendPresence.setChecked(false);
+ binding.detailsSendPresence.setText(R.string.send_presence_updates);
} else {
- send.setText(R.string.preemptively_grant);
+ binding.detailsSendPresence.setText(R.string.preemptively_grant);
if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
- send.setChecked(true);
+ binding.detailsSendPresence.setChecked(true);
} else {
- send.setChecked(false);
+ binding.detailsSendPresence.setChecked(false);
}
}
if (contact.getOption(Contact.Options.TO)) {
- receive.setText(R.string.receive_presence_updates);
- receive.setChecked(true);
+ binding.detailsReceivePresence.setText(R.string.receive_presence_updates);
+ binding.detailsReceivePresence.setChecked(true);
} else {
- receive.setText(R.string.ask_for_presence_updates);
+ binding.detailsReceivePresence.setText(R.string.ask_for_presence_updates);
if (contact.getOption(Contact.Options.ASKING)) {
- receive.setChecked(true);
+ binding.detailsReceivePresence.setChecked(true);
} else {
- receive.setChecked(false);
+ binding.detailsReceivePresence.setChecked(false);
}
}
if (contact.getAccount().isOnlineAndConnected()) {
- receive.setEnabled(true);
- send.setEnabled(true);
+ binding.detailsReceivePresence.setEnabled(true);
+ binding.detailsSendPresence.setEnabled(true);
} else {
- receive.setEnabled(false);
- send.setEnabled(false);
+ binding.detailsReceivePresence.setEnabled(false);
+ binding.detailsSendPresence.setEnabled(false);
}
- send.setOnCheckedChangeListener(this.mOnSendCheckedChange);
- receive.setOnCheckedChangeListener(this.mOnReceiveCheckedChange);
+ binding.detailsSendPresence.setOnCheckedChangeListener(this.mOnSendCheckedChange);
+ binding.detailsReceivePresence.setOnCheckedChangeListener(this.mOnReceiveCheckedChange);
} else {
- addContactButton.setVisibility(View.VISIBLE);
- addContactButton.setText(getString(R.string.add_contact));
- addContactButton.getBackground().clearColorFilter();
- addContactButton.setOnClickListener(new OnClickListener() {
+ binding.addContactButton.setVisibility(View.VISIBLE);
+ binding.addContactButton.setText(getString(R.string.add_contact));
+ binding.addContactButton.getBackground().clearColorFilter();
+ binding.addContactButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
showAddToRosterDialog(contact);
}
});
- send.setVisibility(View.GONE);
- receive.setVisibility(View.GONE);
- statusMessage.setVisibility(View.GONE);
+ binding.detailsSendPresence.setVisibility(View.GONE);
+ binding.detailsReceivePresence.setVisibility(View.GONE);
+ binding.statusMessage.setVisibility(View.GONE);
}
if (contact.isBlocked() && !this.showDynamicTags) {
- lastseen.setVisibility(View.VISIBLE);
- lastseen.setText(R.string.contact_blocked);
+ binding.detailsLastseen.setVisibility(View.VISIBLE);
+ binding.detailsLastseen.setText(R.string.contact_blocked);
} else {
if (showLastSeen
&& contact.getLastseen() > 0
&& contact.getPresences().allOrNonSupport(Namespace.IDLE)) {
- lastseen.setVisibility(View.VISIBLE);
- lastseen.setText(UIHelper.lastseen(getApplicationContext(), contact.isActive(), contact.getLastseen()));
+ binding.detailsLastseen.setVisibility(View.VISIBLE);
+ binding.detailsLastseen.setText(UIHelper.lastseen(getApplicationContext(), contact.isActive(), contact.getLastseen()));
} else {
- lastseen.setVisibility(View.GONE);
+ binding.detailsLastseen.setVisibility(View.GONE);
}
}
if (contact.getPresences().size() > 1) {
- contactJidTv.setText(contact.getDisplayJid() + " ("
+ binding.detailsContactjid.setText(contact.getDisplayJid() + " ("
+ contact.getPresences().size() + ")");
} else {
- contactJidTv.setText(contact.getDisplayJid());
+ binding.detailsContactjid.setText(contact.getDisplayJid());
}
String account;
if (Config.DOMAIN_LOCK != null) {
@@ -553,17 +526,17 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} else {
account = contact.getAccount().getJid().toBareJid().toString();
}
- accountJidTv.setText(getString(R.string.using_account, account));
- badge.setImageBitmap(avatarService().get(contact, getPixel(Config.AVATAR_SIZE)));
- badge.setOnClickListener(this.onBadgeClick);
+ binding.detailsAccount.setText(getString(R.string.using_account, account));
+ binding.detailsContactBadge.setImageBitmap(avatarService().get(contact, getPixel(Config.AVATAR_SIZE)));
+ binding.detailsContactBadge.setOnClickListener(this.onBadgeClick);
- keys.removeAllViews();
+ binding.detailsContactKeys.removeAllViews();
boolean hasKeys = false;
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (Config.supportOtr()) {
for (final String otrFingerprint : contact.getOtrFingerprints()) {
hasKeys = true;
- View view = inflater.inflate(R.layout.contact_key, keys, false);
+ View view = inflater.inflate(R.layout.contact_key, binding.detailsContactKeys, false);
TextView key = view.findViewById(R.id.key);
TextView keyType = view.findViewById(R.id.key_type);
ImageButton removeButton = view
@@ -576,7 +549,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
} else {
keyType.setText(R.string.otr_fingerprint);
}
- keys.addView(view);
+ binding.detailsContactKeys.addView(view);
removeButton.setOnClickListener(new OnClickListener() {
@Override
@@ -603,21 +576,21 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
if (!trust.isCompromised()) {
boolean highlight = session.getFingerprint().equals(messageFingerprint);
- addFingerprintRow(keys, session, highlight);
+ addFingerprintRow(binding.detailsContactKeys, session, highlight);
}
}
if (showsInactive || skippedInactive) {
- mShowInactiveDevicesButton.setText(showsInactive ? R.string.hide_inactive_devices : R.string.show_inactive_devices);
- mShowInactiveDevicesButton.setVisibility(View.VISIBLE);
+ binding.showInactiveDevices.setText(showsInactive ? R.string.hide_inactive_devices : R.string.show_inactive_devices);
+ binding.showInactiveDevices.setVisibility(View.VISIBLE);
} else {
- mShowInactiveDevicesButton.setVisibility(View.GONE);
+ binding.showInactiveDevices.setVisibility(View.GONE);
}
} else {
- mShowInactiveDevicesButton.setVisibility(View.GONE);
+ binding.showInactiveDevices.setVisibility(View.GONE);
}
if (Config.supportOpenPgp() && contact.getPgpKeyId() != 0) {
hasKeys = true;
- View view = inflater.inflate(R.layout.contact_key, keys, false);
+ View view = inflater.inflate(R.layout.contact_key, binding.detailsContactKeys, false);
TextView key = view.findViewById(R.id.key);
TextView keyType = view.findViewById(R.id.key_type);
keyType.setText(R.string.openpgp_key_id);
@@ -635,21 +608,21 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
view.setOnClickListener(openKey);
key.setOnClickListener(openKey);
keyType.setOnClickListener(openKey);
- keys.addView(view);
+ binding.detailsContactKeys.addView(view);
}
- keysWrapper.setVisibility(hasKeys ? View.VISIBLE : View.GONE);
+ binding.keysWrapper.setVisibility(hasKeys ? View.VISIBLE : View.GONE);
List<ListItem.Tag> tagList = contact.getTags(this);
if (tagList.size() == 0 || !this.showDynamicTags) {
- tags.setVisibility(View.GONE);
+ binding.tags.setVisibility(View.GONE);
} else {
- tags.setVisibility(View.VISIBLE);
- tags.removeAllViewsInLayout();
+ binding.tags.setVisibility(View.VISIBLE);
+ binding.tags.removeAllViewsInLayout();
for (final ListItem.Tag tag : tagList) {
- final TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag, tags, false);
+ final TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag, binding.tags, false);
tv.setText(tag.getName());
tv.setBackgroundColor(tag.getColor());
- tags.addView(tv);
+ binding.tags.addView(tv);
}
}
}
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
index 192979083..dbfc61a0c 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationActivity.java
@@ -1,8 +1,6 @@
package de.pixart.messenger.ui;
import android.annotation.SuppressLint;
-import android.app.ActionBar;
-import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
@@ -18,16 +16,17 @@ import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
-import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.support.media.ExifInterface;
import android.support.v4.widget.SlidingPaneLayout;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.util.Pair;
import android.view.Gravity;
@@ -250,7 +249,7 @@ public class ConversationActivity extends XmppActivity
this.listAdapter = new ConversationAdapter(this, conversationList);
listView.setAdapter(this.listAdapter);
- final ActionBar actionBar = getActionBar();
+ final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
}
@@ -350,12 +349,9 @@ public class ConversationActivity extends XmppActivity
@Override
public void switchToConversation(Conversation conversation) {
setSelectedConversation(conversation);
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
- openConversation();
- }
+ runOnUiThread(() -> {
+ ConversationActivity.this.mConversationFragment.reInit(getSelectedConversation());
+ openConversation();
});
}
@@ -364,7 +360,7 @@ public class ConversationActivity extends XmppActivity
}
private void updateActionBarTitle(boolean titleShouldBeName) {
- final ActionBar ab = getActionBar();
+ final ActionBar ab = getSupportActionBar();
final Conversation conversation = getSelectedConversation();
if (ab != null) {
if (titleShouldBeName && conversation != null) {
@@ -481,6 +477,8 @@ public class ConversationActivity extends XmppActivity
final MenuItem menuClearHistory = menu.findItem(R.id.action_clear_history);
final MenuItem menuAdd = menu.findItem(R.id.action_add);
final MenuItem menuInviteContact = menu.findItem(R.id.action_invite);
+ final MenuItem menuAttachSoundRecorder = menu.findItem(R.id.attach_record_voice);
+ final MenuItem menuAttachLocation = menu.findItem(R.id.attach_location);
final MenuItem menuUpdater = menu.findItem(R.id.action_check_updates);
final MenuItem menuInviteUser = menu.findItem(R.id.action_invite_user);
final MenuItem menuSearchHistory = menu.findItem(R.id.action_search_history);
@@ -498,6 +496,8 @@ public class ConversationActivity extends XmppActivity
menuSecure.setVisible(false);
menuInviteContact.setVisible(false);
menuAttach.setVisible(false);
+ menuAttachLocation.setVisible(false);
+ menuAttachSoundRecorder.setVisible(false);
menuClearHistory.setVisible(false);
menuSearchHistory.setVisible(false);
if (xmppConnectionService.installedFromFDroid()) {
@@ -518,11 +518,7 @@ public class ConversationActivity extends XmppActivity
menuArchiveChat.setVisible(false);
}
if (this.getSelectedConversation().getNextEncryption() != Message.ENCRYPTION_NONE) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- menuSecure.setIcon(R.drawable.ic_lock_white_24dp);
- } else {
- menuSecure.setIcon(R.drawable.ic_action_secure);
- }
+ menuSecure.setIcon(R.drawable.ic_lock_white_24dp);
}
if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
menuAttach.setVisible(getSelectedConversation().getAccount().httpUploadAvailable() && getSelectedConversation().getMucOptions().participating());
@@ -532,133 +528,119 @@ public class ConversationActivity extends XmppActivity
menuSecure.setVisible(Config.multipleEncryptionChoices());
menuInviteContact.setVisible(xmppConnectionService != null && xmppConnectionService.findConferenceServer(getSelectedConversation().getAccount()) != null);
}
+ menuAttachLocation.setVisible(true);
+ menuAttachSoundRecorder.setVisible(true);
+ configureEncryptionMenu(getSelectedConversation(), menu);
}
}
- if (Config.supportOmemo()) {
- new Handler().post(addOmemoDebuggerRunnable);
- }
return super.onCreateOptionsMenu(menu);
}
- private Runnable addOmemoDebuggerRunnable = new Runnable() {
- @Override
- public void run() {
- View view = findViewById(R.id.action_security);
- if (view != null) {
- view.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- return v.getId() == R.id.action_security && quickOmemoDebugger(getSelectedConversation());
- }
- });
- }
- }
- };
-
- private boolean quickOmemoDebugger(Conversation c) {
- if (c != null) {
- boolean single = c.getMode() == Conversation.MODE_SINGLE;
- AxolotlService axolotlService = c.getAccount().getAxolotlService();
- Pair<AxolotlService.AxolotlCapability, Jid> capabilityJidPair = axolotlService.isConversationAxolotlCapableDetailed(c);
- switch (capabilityJidPair.first) {
- case MISSING_PRESENCE:
- Toast.makeText(ConversationActivity.this, single ? getString(R.string.missing_presence_subscription) : getString(R.string.missing_presence_subscription_with_x, capabilityJidPair.second.toBareJid().toString()), Toast.LENGTH_SHORT).show();
- return true;
- case MISSING_KEYS:
- Toast.makeText(ConversationActivity.this, single ? getString(R.string.missing_omemo_keys) : getString(R.string.missing_keys_from_x, capabilityJidPair.second.toBareJid().toString()), Toast.LENGTH_SHORT).show();
- return true;
- case WRONG_CONFIGURATION:
- Toast.makeText(ConversationActivity.this, R.string.wrong_conference_configuration, Toast.LENGTH_SHORT).show();
- return true;
- case NO_MEMBERS:
- Toast.makeText(ConversationActivity.this, R.string.this_conference_has_no_members, Toast.LENGTH_SHORT).show();
- return true;
- }
+ private static void configureEncryptionMenu(Conversation conversation, Menu menu) {
+ MenuItem otr = menu.findItem(R.id.encryption_choice_otr);
+ MenuItem none = menu.findItem(R.id.encryption_choice_none);
+ MenuItem pgp = menu.findItem(R.id.encryption_choice_pgp);
+ MenuItem axolotl = menu.findItem(R.id.encryption_choice_axolotl);
+ pgp.setVisible(Config.supportOpenPgp());
+ none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
+ otr.setVisible(Config.supportOtr());
+ axolotl.setVisible(Config.supportOmemo());
+ if (conversation.getMode() == Conversation.MODE_MULTI) {
+ otr.setVisible(false);
+ }
+ if (!conversation.getAccount().getAxolotlService().isConversationAxolotlCapable(conversation)) {
+ axolotl.setEnabled(false);
+ }
+ switch (conversation.getNextEncryption()) {
+ case Message.ENCRYPTION_NONE:
+ none.setChecked(true);
+ break;
+ case Message.ENCRYPTION_OTR:
+ otr.setChecked(true);
+ break;
+ case Message.ENCRYPTION_PGP:
+ pgp.setChecked(true);
+ break;
+ case Message.ENCRYPTION_AXOLOTL:
+ axolotl.setChecked(true);
+ break;
+ default:
+ none.setChecked(true);
+ break;
}
- return false;
}
protected void selectPresenceToAttachFile(final int attachmentChoice, final int encryption) {
final Conversation conversation = getSelectedConversation();
final Account account = conversation.getAccount();
- final OnPresenceSelected callback = new OnPresenceSelected() {
-
- @Override
- public void onPresenceSelected() {
- final Intent intent = new Intent();
- boolean chooser = false;
- String fallbackPackageId = null;
- switch (attachmentChoice) {
- case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
- intent.setAction(Intent.ACTION_GET_CONTENT);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
- }
- intent.setType("image/*");
- chooser = true;
- break;
- case ATTACHMENT_CHOICE_CHOOSE_VIDEO:
- chooser = true;
- intent.setType("video/*");
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setAction(Intent.ACTION_GET_CONTENT);
- break;
- case ATTACHMENT_CHOICE_TAKE_FROM_CAMERA:
- AlertDialog.Builder builder = new AlertDialog.Builder(ConversationActivity.this);
- builder.setTitle(getString(R.string.attach_take_from_camera));
- builder.setNegativeButton(getString(R.string.action_take_photo),
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri();
- intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mPendingPhotoUris.clear();
- mPendingPhotoUris.add(uri);
- startActivityForResult(intent, attachmentChoice);
- }
- });
- builder.setPositiveButton(getString(R.string.action_take_video),
- new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Uri uri = xmppConnectionService.getFileBackend().getTakeVideoUri();
- intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
- mPendingFileUris.clear();
- mPendingFileUris.add(uri);
- startActivityForResult(intent, attachmentChoice);
- }
- });
- builder.create().show();
- break;
- case ATTACHMENT_CHOICE_CHOOSE_FILE:
- chooser = true;
- intent.setType("*/*");
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setAction(Intent.ACTION_GET_CONTENT);
- break;
- case ATTACHMENT_CHOICE_RECORD_VOICE:
- startActivityForResult(new Intent(getApplicationContext(), RecordingActivity.class), attachmentChoice);
- break;
- case ATTACHMENT_CHOICE_LOCATION:
- startActivityForResult(new Intent(getApplicationContext(), ShareLocationActivity.class), attachmentChoice);
- break;
- }
- if (intent.resolveActivity(getPackageManager()) != null) {
- Log.d(Config.LOGTAG, "Attachment: " + attachmentChoice);
- if (chooser) {
- startActivityForResult(
- Intent.createChooser(intent, getString(R.string.perform_action_with)),
- attachmentChoice);
- } else {
- startActivityForResult(intent, attachmentChoice);
+ final OnPresenceSelected callback = () -> {
+ final Intent intent = new Intent();
+ boolean chooser = false;
+ String fallbackPackageId = null;
+ switch (attachmentChoice) {
+ case ATTACHMENT_CHOICE_CHOOSE_IMAGE:
+ intent.setAction(Intent.ACTION_GET_CONTENT);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
- } else if (fallbackPackageId != null) {
- startActivity(getInstallApkIntent(fallbackPackageId));
+ intent.setType("image/*");
+ chooser = true;
+ break;
+ case ATTACHMENT_CHOICE_CHOOSE_VIDEO:
+ chooser = true;
+ intent.setType("video/*");
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setAction(Intent.ACTION_GET_CONTENT);
+ break;
+ case ATTACHMENT_CHOICE_TAKE_FROM_CAMERA:
+ AlertDialog.Builder builder = new AlertDialog.Builder(ConversationActivity.this);
+ builder.setTitle(getString(R.string.attach_take_from_camera));
+ builder.setNegativeButton(getString(R.string.action_take_photo),
+ (dialog, which) -> {
+ Uri uri = xmppConnectionService.getFileBackend().getTakePhotoUri();
+ intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
+ mPendingPhotoUris.clear();
+ mPendingPhotoUris.add(uri);
+ startActivityForResult(intent, attachmentChoice);
+ });
+ builder.setPositiveButton(getString(R.string.action_take_video),
+ (dialog, which) -> {
+ Uri uri = xmppConnectionService.getFileBackend().getTakeVideoUri();
+ intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
+ mPendingFileUris.clear();
+ mPendingFileUris.add(uri);
+ startActivityForResult(intent, attachmentChoice);
+ });
+ builder.create().show();
+ break;
+ case ATTACHMENT_CHOICE_CHOOSE_FILE:
+ chooser = true;
+ intent.setType("*/*");
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setAction(Intent.ACTION_GET_CONTENT);
+ break;
+ case ATTACHMENT_CHOICE_RECORD_VOICE:
+ startActivityForResult(new Intent(getApplicationContext(), RecordingActivity.class), attachmentChoice);
+ break;
+ case ATTACHMENT_CHOICE_LOCATION:
+ startActivityForResult(new Intent(getApplicationContext(), ShareLocationActivity.class), attachmentChoice);
+ break;
+ }
+ if (intent.resolveActivity(getPackageManager()) != null) {
+ Log.d(Config.LOGTAG, "Attachment: " + attachmentChoice);
+ if (chooser) {
+ startActivityForResult(
+ Intent.createChooser(intent, getString(R.string.perform_action_with)),
+ attachmentChoice);
+ } else {
+ startActivityForResult(intent, attachmentChoice);
}
+ } else if (fallbackPackageId != null) {
+ startActivity(getInstallApkIntent(fallbackPackageId));
}
};
if ((account.httpUploadAvailable() || attachmentChoice == ATTACHMENT_CHOICE_LOCATION) && encryption != Message.ENCRYPTION_OTR) {
@@ -817,8 +799,26 @@ public class ConversationActivity extends XmppActivity
return true;
} else if (getSelectedConversation() != null) {
switch (item.getItemId()) {
- case R.id.action_attach_file:
- attachFileDialog();
+ case R.id.encryption_choice_axolotl:
+ case R.id.encryption_choice_otr:
+ case R.id.encryption_choice_pgp:
+ case R.id.encryption_choice_none:
+ handleEncryptionSelection(item);
+ break;
+ case R.id.attach_choose_picture:
+ attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
+ break;
+ case R.id.attach_take_picture:
+ attachFile(ATTACHMENT_CHOICE_TAKE_FROM_CAMERA);
+ break;
+ case R.id.attach_choose_file:
+ attachFile(ATTACHMENT_CHOICE_CHOOSE_FILE);
+ break;
+ case R.id.attach_record_voice:
+ attachFile(ATTACHMENT_CHOICE_RECORD_VOICE);
+ break;
+ case R.id.attach_location:
+ attachFile(ATTACHMENT_CHOICE_LOCATION);
break;
case R.id.action_archive_chat:
this.endConversation(getSelectedConversation());
@@ -840,9 +840,6 @@ public class ConversationActivity extends XmppActivity
case R.id.action_invite:
inviteToConversation(getSelectedConversation());
break;
- case R.id.action_security:
- selectEncryptionDialog(getSelectedConversation());
- break;
case R.id.action_clear_history:
clearHistoryDialog(getSelectedConversation());
break;
@@ -893,10 +890,8 @@ public class ConversationActivity extends XmppActivity
protected void clearHistoryDialog(final Conversation conversation) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.clear_conversation_history));
- View dialogView = getLayoutInflater().inflate(
- R.layout.dialog_clear_history, null);
- final CheckBox endConversationCheckBox = dialogView
- .findViewById(R.id.end_conversation_checkbox);
+ final View dialogView = getLayoutInflater().inflate(R.layout.dialog_clear_history, null);
+ final CheckBox endConversationCheckBox = dialogView.findViewById(R.id.end_conversation_checkbox);
if (conversation.getMode() == Conversation.MODE_SINGLE) {
endConversationCheckBox.setVisibility(View.VISIBLE);
endConversationCheckBox.setChecked(true);
@@ -904,65 +899,23 @@ public class ConversationActivity extends XmppActivity
builder.setView(dialogView);
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.delete_messages),
- new OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- ConversationActivity.this.xmppConnectionService.clearConversationHistory(conversation);
- if (conversation.getMode() == Conversation.MODE_SINGLE) {
- if (endConversationCheckBox.isChecked()) {
- endConversation(conversation);
- } else {
- updateConversationList();
- ConversationActivity.this.mConversationFragment.updateMessages();
- }
+ (dialog, which) -> {
+ ConversationActivity.this.xmppConnectionService.clearConversationHistory(conversation);
+ if (conversation.getMode() == Conversation.MODE_SINGLE) {
+ if (endConversationCheckBox.isChecked()) {
+ endConversation(conversation);
} else {
updateConversationList();
ConversationActivity.this.mConversationFragment.updateMessages();
}
+ } else {
+ updateConversationList();
+ ConversationActivity.this.mConversationFragment.updateMessages();
}
});
builder.create().show();
}
- protected void attachFileDialog() {
- View menuAttachFile = findViewById(R.id.action_attach_file);
- if (menuAttachFile == null) {
- return;
- }
- PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile);
- attachFilePopup.inflate(R.menu.attachment_choices);
- attachFilePopup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.attach_choose_picture:
- attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
- break;
- case R.id.attach_take_picture:
- attachFile(ATTACHMENT_CHOICE_TAKE_FROM_CAMERA);
- break;
- case R.id.attach_choose_video:
- attachFile(ATTACHMENT_CHOICE_CHOOSE_VIDEO);
- break;
- case R.id.attach_choose_file:
- attachFile(ATTACHMENT_CHOICE_CHOOSE_FILE);
- break;
- case R.id.attach_record_voice:
- attachFile(ATTACHMENT_CHOICE_RECORD_VOICE);
- break;
- case R.id.attach_location:
- attachFile(ATTACHMENT_CHOICE_LOCATION);
- break;
- }
- return false;
- }
- });
- UIHelper.showIconsInPopup(attachFilePopup);
- attachFilePopup.show();
- }
-
public void verifyOtrSessionDialog(final Conversation conversation, View view) {
if (!conversation.hasValidOtrSession() || conversation.getOtrSession().getSessionStatus() != SessionStatus.ENCRYPTED) {
Toast.makeText(this, R.string.otr_session_not_started, Toast.LENGTH_LONG).show();
@@ -998,91 +951,47 @@ public class ConversationActivity extends XmppActivity
popup.show();
}
- protected void selectEncryptionDialog(final Conversation conversation) {
- View menuItemView = findViewById(R.id.action_security);
- if (menuItemView == null) {
+ private void handleEncryptionSelection(MenuItem item) {
+ Conversation conversation = getSelectedConversation();
+ if (conversation == null) {
return;
}
- PopupMenu popup = new PopupMenu(this, menuItemView);
- final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
- .findFragmentByTag("conversation");
- if (fragment != null) {
- popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.encryption_choice_none:
- conversation.setNextEncryption(Message.ENCRYPTION_NONE);
- item.setChecked(true);
- break;
- case R.id.encryption_choice_otr:
- conversation.setNextEncryption(Message.ENCRYPTION_OTR);
- item.setChecked(true);
- break;
- case R.id.encryption_choice_pgp:
- if (hasPgp()) {
- if (conversation.getAccount().getPgpSignature() != null) {
- conversation.setNextEncryption(Message.ENCRYPTION_PGP);
- item.setChecked(true);
- } else {
- announcePgp(conversation.getAccount(), conversation, null, onOpenPGPKeyPublished);
- }
- } else {
- showInstallPgpDialog();
- }
- break;
- case R.id.encryption_choice_axolotl:
- Log.d(Config.LOGTAG, AxolotlService.getLogprefix(conversation.getAccount())
- + "Enabled axolotl for Contact " + conversation.getContact().getJid());
- conversation.setNextEncryption(Message.ENCRYPTION_AXOLOTL);
- item.setChecked(true);
- break;
- default:
- conversation.setNextEncryption(Message.ENCRYPTION_NONE);
- break;
+ final ConversationFragment fragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation");
+ switch (item.getItemId()) {
+ case R.id.encryption_choice_none:
+ conversation.setNextEncryption(Message.ENCRYPTION_NONE);
+ item.setChecked(true);
+ break;
+ case R.id.encryption_choice_otr:
+ conversation.setNextEncryption(Message.ENCRYPTION_OTR);
+ item.setChecked(true);
+ break;
+ case R.id.encryption_choice_pgp:
+ if (hasPgp()) {
+ if (conversation.getAccount().getPgpSignature() != null) {
+ conversation.setNextEncryption(Message.ENCRYPTION_PGP);
+ item.setChecked(true);
+ } else {
+ announcePgp(conversation.getAccount(), conversation, null, onOpenPGPKeyPublished);
}
- xmppConnectionService.updateConversation(conversation);
- fragment.updateChatMsgHint();
- invalidateOptionsMenu();
- refreshUi();
- return true;
+ } else {
+ showInstallPgpDialog();
}
- });
- popup.inflate(R.menu.encryption_choices);
- MenuItem otr = popup.getMenu().findItem(R.id.encryption_choice_otr);
- MenuItem none = popup.getMenu().findItem(R.id.encryption_choice_none);
- MenuItem pgp = popup.getMenu().findItem(R.id.encryption_choice_pgp);
- MenuItem axolotl = popup.getMenu().findItem(R.id.encryption_choice_axolotl);
- pgp.setVisible(Config.supportOpenPgp());
- none.setVisible(Config.supportUnencrypted() || conversation.getMode() == Conversation.MODE_MULTI);
- otr.setVisible(Config.supportOtr());
- axolotl.setVisible(Config.supportOmemo());
- if (conversation.getMode() == Conversation.MODE_MULTI) {
- otr.setVisible(false);
- }
- if (!conversation.getAccount().getAxolotlService().isConversationAxolotlCapable(conversation)) {
- axolotl.setEnabled(false);
- }
- switch (conversation.getNextEncryption()) {
- case Message.ENCRYPTION_NONE:
- none.setChecked(true);
- break;
- case Message.ENCRYPTION_OTR:
- otr.setChecked(true);
- break;
- case Message.ENCRYPTION_PGP:
- pgp.setChecked(true);
- break;
- case Message.ENCRYPTION_AXOLOTL:
- axolotl.setChecked(true);
- break;
- default:
- none.setChecked(true);
- break;
- }
- popup.show();
+ break;
+ case R.id.encryption_choice_axolotl:
+ Log.d(Config.LOGTAG, AxolotlService.getLogprefix(conversation.getAccount())
+ + "Enabled axolotl for Contact " + conversation.getContact().getJid());
+ conversation.setNextEncryption(Message.ENCRYPTION_AXOLOTL);
+ item.setChecked(true);
+ break;
+ default:
+ conversation.setNextEncryption(Message.ENCRYPTION_NONE);
+ break;
}
+ xmppConnectionService.updateConversation(conversation);
+ fragment.updateChatMsgHint();
+ invalidateOptionsMenu();
+ refreshUi();
}
@Override
@@ -1260,7 +1169,6 @@ public class ConversationActivity extends XmppActivity
recreate();
}
this.mActivityPaused = false;
-
if (!isConversationsOverviewVisable() || !isConversationsOverviewHideable()) {
sendReadMarkerIfNecessary(getSelectedConversation());
}
@@ -1699,26 +1607,18 @@ public class ConversationActivity extends XmppActivity
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.battery_optimizations_enabled);
builder.setMessage(R.string.battery_optimizations_enabled_dialog);
- builder.setPositiveButton(R.string.next, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
- Uri uri = Uri.parse("package:" + getPackageName());
- intent.setData(uri);
- try {
- startActivityForResult(intent, REQUEST_BATTERY_OP);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(ConversationActivity.this, R.string.device_does_not_support_battery_op, Toast.LENGTH_SHORT).show();
- }
+ builder.setPositiveButton(R.string.next, (dialog, which) -> {
+ Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ Uri uri = Uri.parse("package:" + getPackageName());
+ intent.setData(uri);
+ try {
+ startActivityForResult(intent, REQUEST_BATTERY_OP);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(ConversationActivity.this, R.string.device_does_not_support_battery_op, Toast.LENGTH_SHORT).show();
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
- builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- setNeverAskForBatteryOptimizationsAgain();
- }
- });
+ builder.setOnDismissListener(dialog -> setNeverAskForBatteryOptimizationsAgain());
}
builder.create().show();
}
diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
index e73f30211..e4c648e25 100644
--- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java
@@ -1,7 +1,7 @@
package de.pixart.messenger.ui;
import android.app.Activity;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.app.Fragment;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
diff --git a/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java b/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java
index c94ceb44b..d26c2123c 100644
--- a/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/EditAccountActivity.java
@@ -1,27 +1,28 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
-import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.provider.Settings;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
+import android.support.design.widget.TextInputLayout;
import android.support.v4.content.ContextCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -48,6 +49,7 @@ import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.axolotl.AxolotlService;
import de.pixart.messenger.crypto.axolotl.XmppAxolotlSession;
+import de.pixart.messenger.databinding.ActivityEditAccountBinding;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.services.BarcodeProvider;
import de.pixart.messenger.services.XmppConnectionService;
@@ -66,24 +68,20 @@ import de.pixart.messenger.xmpp.forms.Data;
import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.xmpp.jid.Jid;
import de.pixart.messenger.xmpp.pep.Avatar;
-
public class EditAccountActivity extends OmemoActivity implements OnAccountUpdate, OnUpdateBlocklist,
OnKeyStatusUpdated, OnCaptchaRequested, KeyChainAliasCallback, XmppConnectionService.OnShowErrorToast, XmppConnectionService.OnMamPreferencesFetched {
private static final int REQUEST_DATA_SAVER = 0x37af244;
- private AutoCompleteTextView mAccountJid;
+ private TextInputLayout mAccountJidLayout;
private EditText mPassword;
- private EditText mPasswordConfirm;
+ private TextInputLayout mPasswordLayout;
private CheckBox mRegisterNew;
private Button mCancelButton;
private Button mSaveButton;
private Button mDisableOsOptimizationsButton;
- private TextView mDisableOsOptimizationsHeadline;
private TextView getmDisableOsOptimizationsBody;
private TableLayout mMoreTable;
- private LinearLayout mStats;
- private RelativeLayout mOsOptimizations;
private TextView mServerInfoSm;
private TextView mServerInfoRosterVersion;
private TextView mServerInfoCarbons;
@@ -100,7 +98,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private TextView mOwnFingerprintDesc;
private TextView mOtrFingerprintDesc;
private TextView getmPgpFingerprintDesc;
- private TextView mAccountJidLabel;
private ImageView mAvatar;
private RelativeLayout mOtrFingerprintBox;
private RelativeLayout mAxolotlFingerprintBox;
@@ -109,10 +106,11 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private ImageButton mAxolotlFingerprintToClipboardButton;
private ImageButton mPgpDeleteFingerprintButton;
private LinearLayout keys;
- private LinearLayout keysCard;
private LinearLayout mNamePort;
private EditText mHostname;
+ private TextInputLayout mHostnameLayout;
private EditText mPort;
+ private TextInputLayout mPortLayout;
private AlertDialog mCaptchaDialog = null;
private Jid jidToEdit;
@@ -129,7 +127,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
@Override
public void onClick(final View v) {
final String password = mPassword.getText().toString();
- final String passwordConfirm = mPasswordConfirm.getText().toString();
final boolean wasDisabled = mAccount != null && mAccount.getStatus() == Account.State.DISABLED;
if (!mInitMode && passwordChangedInMagicCreateMode()) {
@@ -147,9 +144,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
return;
}
final boolean registerNewAccount = mRegisterNew.isChecked() && !Config.DISALLOW_REGISTRATION_IN_UI;
- if (mUsernameMode && mAccountJid.getText().toString().contains("@")) {
- mAccountJid.setError(getString(R.string.invalid_username));
- mAccountJid.requestFocus();
+ if (mUsernameMode && binding.accountJid.getText().toString().contains("@")) {
+ mAccountJidLayout.setError(getString(R.string.invalid_username));
+ removeErrorsOnAllBut(mAccountJidLayout);
+ binding.accountJid.requestFocus();
return;
}
@@ -171,17 +169,18 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
final Jid jid;
try {
if (mUsernameMode) {
- jid = Jid.fromParts(mAccountJid.getText().toString(), getUserModeDomain(), null);
+ jid = Jid.fromParts(binding.accountJid.getText().toString(), getUserModeDomain(), null);
} else {
- jid = Jid.fromString(mAccountJid.getText().toString());
+ jid = Jid.fromString(binding.accountJid.getText().toString());
}
} catch (final InvalidJidException e) {
if (mUsernameMode) {
- mAccountJid.setError(getString(R.string.invalid_username));
+ mAccountJidLayout.setError(getString(R.string.invalid_username));
} else {
- mAccountJid.setError(getString(R.string.invalid_jid));
+ mAccountJidLayout.setError(getString(R.string.invalid_jid));
}
- mAccountJid.requestFocus();
+ binding.accountJid.requestFocus();
+ removeErrorsOnAllBut(mAccountJidLayout);
return;
}
String hostname = null;
@@ -190,20 +189,23 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
hostname = mHostname.getText().toString().replaceAll("\\s", "");
final String port = mPort.getText().toString().replaceAll("\\s", "");
if (hostname.contains(" ")) {
- mHostname.setError(getString(R.string.not_valid_hostname));
+ mHostnameLayout.setError(getString(R.string.not_valid_hostname));
mHostname.requestFocus();
+ removeErrorsOnAllBut(mHostnameLayout);
return;
}
try {
numericPort = Integer.parseInt(port);
if (numericPort < 0 || numericPort > 65535) {
- mPort.setError(getString(R.string.not_a_valid_port));
+ mPortLayout.setError(getString(R.string.not_a_valid_port));
+ removeErrorsOnAllBut(mPortLayout);
mPort.requestFocus();
return;
}
} catch (NumberFormatException e) {
- mPort.setError(getString(R.string.not_a_valid_port));
+ mPortLayout.setError(getString(R.string.not_a_valid_port));
+ removeErrorsOnAllBut(mPortLayout);
mPort.requestFocus();
return;
}
@@ -211,22 +213,18 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
if (jid.isDomainJid()) {
if (mUsernameMode) {
- mAccountJid.setError(getString(R.string.invalid_username));
+ mAccountJidLayout.setError(getString(R.string.invalid_username));
} else {
- mAccountJid.setError(getString(R.string.invalid_jid));
+ mAccountJidLayout.setError(getString(R.string.invalid_jid));
}
- mAccountJid.requestFocus();
+ removeErrorsOnAllBut(mAccountJidLayout);
+ binding.accountJid.requestFocus();
return;
}
if (registerNewAccount) {
if (XmppConnection.errorMessage != null) {
Toast.makeText(EditAccountActivity.this, XmppConnection.errorMessage, Toast.LENGTH_LONG).show();
}
- if (!password.equals(passwordConfirm)) {
- mPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
- mPasswordConfirm.requestFocus();
- return;
- }
}
if (mAccount != null) {
if (mInitMode && mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) {
@@ -236,11 +234,10 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
mAccount.setPort(numericPort);
mAccount.setHostname(hostname);
if (XmppConnection.errorMessage != null) {
- mAccountJid.setError(XmppConnection.errorMessage);
+ mAccountJidLayout.setError(XmppConnection.errorMessage);
} else {
- mAccountJid.setError(null);
+ mAccountJidLayout.setError(null);
}
- mPasswordConfirm.setError(null);
mAccount.setPassword(password);
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
if (!xmppConnectionService.updateAccount(mAccount)) {
@@ -249,8 +246,9 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
} else {
if (xmppConnectionService.findAccountByJid(jid) != null) {
- mAccountJid.setError(getString(R.string.account_already_exists));
- mAccountJid.requestFocus();
+ mAccountJidLayout.setError(getString(R.string.account_already_exists));
+ removeErrorsOnAllBut(mAccountJidLayout);
+ binding.accountJid.requestFocus();
return;
}
mAccount = new Account(jid.toBareJid(), password);
@@ -261,8 +259,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
xmppConnectionService.createAccount(mAccount);
}
- mHostname.setError(null);
- mPort.setError(null);
+ mHostnameLayout.setError(null);
+ mPortLayout.setError(null);
if (mAccount.isEnabled()
&& !registerNewAccount
&& !mInitMode) {
@@ -288,6 +286,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private boolean mSavedInstanceInit = false;
private Button mClearDevicesButton;
private XmppUri pendingUri = null;
+ private boolean mUseTor;
+ private ActivityEditAccountBinding binding;
public void refreshUiReal() {
invalidateOptionsMenu();
@@ -371,6 +371,24 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
};
+ private View.OnFocusChangeListener mEditTextFocusListener = new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View view, boolean b) {
+ EditText et = (EditText) view;
+ if (b) {
+ int resId = mUsernameMode ? R.string.username : R.string.account_settings_example_jabber_id;
+ if (view.getId() == R.id.hostname) {
+ resId = mUseTor ? R.string.hostname_or_onion : R.string.hostname_example;
+ }
+ final int res = resId;
+ new Handler().postDelayed(() -> et.setHint(res), 500);
+ } else {
+ et.setHint(null);
+ }
+ }
+ };
+
+
private final OnClickListener mAvatarClickListener = new OnClickListener() {
@Override
public void onClick(final View view) {
@@ -499,7 +517,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
} else {
unmodified = this.mAccount.getJid().toBareJid().toString();
}
- return !unmodified.equals(this.mAccountJid.getText().toString());
+ return !unmodified.equals(this.binding.accountJid.getText().toString());
}
protected boolean passwordChangedInMagicCreateMode() {
@@ -526,20 +544,17 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mSavedInstanceAccount = savedInstanceState.getString("account");
this.mSavedInstanceInit = savedInstanceState.getBoolean("initMode", false);
}
- setContentView(R.layout.activity_edit_account);
- this.mAccountJid = findViewById(R.id.account_jid);
- this.mAccountJid.addTextChangedListener(this.mTextWatcher);
- this.mAccountJidLabel = findViewById(R.id.account_jid_label);
+ this.binding = DataBindingUtil.setContentView(this, R.layout.activity_edit_account);
+ this.binding.accountJid.addTextChangedListener(this.mTextWatcher);
+ this.binding.accountJid.setOnFocusChangeListener(this.mEditTextFocusListener);
+ this.mAccountJidLayout = (TextInputLayout) findViewById(R.id.account_jid_layout);
this.mPassword = findViewById(R.id.account_password);
this.mPassword.addTextChangedListener(this.mTextWatcher);
- this.mPasswordConfirm = findViewById(R.id.account_password_confirm);
+ this.mPasswordLayout = (TextInputLayout) findViewById(R.id.account_password_layout);
this.mAvatar = findViewById(R.id.avater);
this.mAvatar.setOnClickListener(this.mAvatarClickListener);
this.mRegisterNew = findViewById(R.id.account_register_new);
- this.mStats = findViewById(R.id.stats);
- this.mOsOptimizations = findViewById(R.id.os_optimization);
this.mDisableOsOptimizationsButton = findViewById(R.id.os_optimization_disable);
- this.mDisableOsOptimizationsHeadline = findViewById(R.id.os_optimization_headline);
this.getmDisableOsOptimizationsBody = findViewById(R.id.os_optimization_body);
this.mSessionEst = findViewById(R.id.session_est);
this.mServerInfoRosterVersion = findViewById(R.id.server_info_roster_version);
@@ -564,11 +579,12 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mAxolotlFingerprintBox = findViewById(R.id.axolotl_fingerprint_box);
this.mAxolotlFingerprintToClipboardButton = findViewById(R.id.action_copy_axolotl_to_clipboard);
this.mOwnFingerprintDesc = findViewById(R.id.own_fingerprint_desc);
- this.keysCard = findViewById(R.id.other_device_keys_card);
this.keys = findViewById(R.id.other_device_keys);
this.mNamePort = findViewById(R.id.name_port);
this.mHostname = findViewById(R.id.hostname);
this.mHostname.addTextChangedListener(mTextWatcher);
+ this.mHostname.setOnFocusChangeListener(mEditTextFocusListener);
+ this.mHostnameLayout = (TextInputLayout)findViewById(R.id.hostname_layout);
this.mClearDevicesButton = findViewById(R.id.clear_devices);
this.mClearDevicesButton.setOnClickListener(new OnClickListener() {
@Override
@@ -579,6 +595,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mPort = findViewById(R.id.port);
this.mPort.setText("5222");
this.mPort.addTextChangedListener(mTextWatcher);
+ this.mPortLayout = (TextInputLayout)findViewById(R.id.port_layout);
this.mSaveButton = findViewById(R.id.save_button);
this.mCancelButton = findViewById(R.id.cancel_button);
this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
@@ -589,13 +606,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
final OnCheckedChangeListener OnCheckedShowConfirmPassword = new OnCheckedChangeListener() {
@Override
- public void onCheckedChanged(final CompoundButton buttonView,
- final boolean isChecked) {
- if (isChecked) {
- mPasswordConfirm.setVisibility(View.VISIBLE);
- } else {
- mPasswordConfirm.setVisibility(View.GONE);
- }
+ public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
updateSaveButton();
}
};
@@ -688,12 +699,12 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.messageFingerprint = getIntent().getStringExtra("fingerprint");
if (!mInitMode) {
this.mRegisterNew.setVisibility(View.GONE);
- if (getActionBar() != null) {
- getActionBar().setTitle(getString(R.string.account_details));
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setTitle(getString(R.string.account_details));
}
} else {
this.mAvatar.setVisibility(View.GONE);
- ActionBar ab = getActionBar();
+ ActionBar ab = getSupportActionBar();
if (ab != null) {
if (init && Config.MAGIC_CREATE_DOMAIN == null) {
ab.setDisplayShowHomeEnabled(false);
@@ -704,9 +715,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
}
SharedPreferences preferences = getPreferences();
- boolean useTor = Config.FORCE_ORBOT || preferences.getBoolean("use_tor", false);
- this.mShowOptions = useTor || preferences.getBoolean("show_connection_options", false);
- mHostname.setHint(useTor ? R.string.hostname_or_onion : R.string.hostname_example);
+ mUseTor = Config.FORCE_ORBOT || preferences.getBoolean("use_tor", false);
+ this.mShowOptions = mUseTor || preferences.getBoolean("show_connection_options", false);
this.mNamePort.setVisibility(mShowOptions ? View.VISIBLE : View.GONE);
}
@@ -769,13 +779,12 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mCancelButton.setTextColor(getSecondaryTextColor());
}
if (mUsernameMode) {
- this.mAccountJidLabel.setText(R.string.username);
- this.mAccountJid.setHint(R.string.username_hint);
+ this.binding.accountJid.setHint(R.string.username_hint);
} else {
final KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
R.layout.simple_list_item,
xmppConnectionService.getKnownHosts());
- this.mAccountJid.setAdapter(mKnownHostsAdapter);
+ this.binding.accountJid.setAdapter(mKnownHostsAdapter);
}
if (pendingUri != null) {
processFingerprintVerification(pendingUri, false);
@@ -890,11 +899,11 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private void updateAccountInformation(boolean init) {
if (init) {
- this.mAccountJid.getEditableText().clear();
+ this.binding.accountJid.getEditableText().clear();
if (mUsernameMode) {
- this.mAccountJid.getEditableText().append(this.mAccount.getJid().getLocalpart());
+ this.binding.accountJid.getEditableText().append(this.mAccount.getJid().getLocalpart());
} else {
- this.mAccountJid.getEditableText().append(this.mAccount.getJid().toBareJid().toString());
+ this.binding.accountJid.getEditableText().append(this.mAccount.getJid().toBareJid().toString());
}
this.mPassword.getEditableText().clear();
this.mPassword.getEditableText().append(this.mAccount.getPassword());
@@ -908,28 +917,28 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
final boolean editable = !mAccount.isOptionSet(Account.OPTION_LOGGED_IN_SUCCESSFULLY);
- this.mAccountJid.setEnabled(editable);
- this.mAccountJid.setFocusable(editable);
- this.mAccountJid.setFocusableInTouchMode(editable);
+ this.binding.accountJid.setEnabled(editable);
+ this.binding.accountJid.setFocusable(editable);
+ this.binding.accountJid.setFocusableInTouchMode(editable);
+ this.mPasswordLayout.setPasswordVisibilityToggleEnabled(editable);
if (!mInitMode) {
this.mAvatar.setVisibility(View.VISIBLE);
this.mAvatar.setImageBitmap(avatarService().get(this.mAccount, getPixel(Config.AVATAR_SIZE)));
- this.mAccountJid.setEnabled(false);
+ this.binding.accountJid.setEnabled(false);
} else {
this.mAvatar.setVisibility(View.GONE);
}
if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) {
this.mRegisterNew.setVisibility(View.VISIBLE);
this.mRegisterNew.setChecked(true);
- this.mPasswordConfirm.setText(this.mAccount.getPassword());
} else {
this.mRegisterNew.setVisibility(View.GONE);
this.mRegisterNew.setChecked(false);
}
if (this.mAccount.isOnlineAndConnected() && !this.mFetchingAvatar) {
Features features = this.mAccount.getXmppConnection().getFeatures();
- this.mStats.setVisibility(View.VISIBLE);
+ this.binding.stats.setVisibility(View.VISIBLE);
boolean showBatteryWarning = !xmppConnectionService.getPushManagementService().available(mAccount) && isOptimizingBattery();
boolean showDataSaverWarning = isAffectedByDataSaver();
showOsOptimizationWarning(showBatteryWarning, showDataSaverWarning);
@@ -993,18 +1002,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
final long pgpKeyId = this.mAccount.getPgpId();
if (pgpKeyId != 0 && Config.supportOpenPgp()) {
- OnClickListener openPgp = new OnClickListener() {
- @Override
- public void onClick(View view) {
- launchOpenKeyChain(pgpKeyId);
- }
- };
- OnClickListener delete = new OnClickListener() {
- @Override
- public void onClick(View view) {
- showDeletePgpDialog();
- }
- };
+ OnClickListener openPgp = view -> launchOpenKeyChain(pgpKeyId);
+ OnClickListener delete = view -> showDeletePgpDialog();
this.mPgpFingerprintBox.setVisibility(View.VISIBLE);
this.mPgpFingerprint.setText(OpenPgpUtils.convertKeyIdToHex(pgpKeyId));
this.mPgpFingerprint.setOnClickListener(openPgp);
@@ -1023,20 +1022,13 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(otrFingerprint));
- this.mOtrFingerprintToClipboardButton
- .setVisibility(View.VISIBLE);
- this.mOtrFingerprintToClipboardButton
- .setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(final View v) {
-
- if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(otrFingerprint), R.string.otr_fingerprint)) {
- Toast.makeText(
- EditAccountActivity.this,
- R.string.toast_message_otr_fingerprint,
- Toast.LENGTH_SHORT).show();
- }
+ this.mOtrFingerprintToClipboardButton.setVisibility(View.VISIBLE);
+ this.mOtrFingerprintToClipboardButton.setOnClickListener(v -> {
+ if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(otrFingerprint), R.string.otr_fingerprint)) {
+ Toast.makeText(
+ EditAccountActivity.this,
+ R.string.toast_message_otr_fingerprint,
+ Toast.LENGTH_SHORT).show();
}
});
} else {
@@ -1053,16 +1045,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mOwnFingerprintDesc.setText(R.string.omemo_fingerprint);
}
this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(ownAxolotlFingerprint.substring(2)));
- this.mAxolotlFingerprintToClipboardButton
- .setVisibility(View.VISIBLE);
- this.mAxolotlFingerprintToClipboardButton
- .setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(final View v) {
- copyOmemoFingerprint(ownAxolotlFingerprint);
- }
- });
+ this.mAxolotlFingerprintToClipboardButton.setVisibility(View.VISIBLE);
+ this.mAxolotlFingerprintToClipboardButton.setOnClickListener(v -> copyOmemoFingerprint(ownAxolotlFingerprint));
} else {
this.mAxolotlFingerprintBox.setVisibility(View.GONE);
}
@@ -1076,7 +1060,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
}
}
if (hasKeys && Config.supportOmemo()) {
- keysCard.setVisibility(View.VISIBLE);
+ this.binding.otherDeviceKeysCard.setVisibility(View.VISIBLE);
Set<Integer> otherDevices = mAccount.getAxolotlService().getOwnDeviceIds();
if (otherDevices == null || otherDevices.isEmpty()) {
mClearDevicesButton.setVisibility(View.GONE);
@@ -1084,30 +1068,49 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
mClearDevicesButton.setVisibility(View.VISIBLE);
}
} else {
- keysCard.setVisibility(View.GONE);
+ this.binding.otherDeviceKeysCard.setVisibility(View.GONE);
}
} else {
+ final TextInputLayout errorLayout;
if (this.mAccount.errorStatus()) {
- final EditText errorTextField;
if (this.mAccount.getStatus() == Account.State.UNAUTHORIZED) {
- errorTextField = this.mPassword;
+ errorLayout = this.mPasswordLayout;
} else if (mShowOptions
&& this.mAccount.getStatus() == Account.State.SERVER_NOT_FOUND
&& this.mHostname.getText().length() > 0) {
- errorTextField = this.mHostname;
+ errorLayout = this.mHostnameLayout;
} else {
- errorTextField = this.mAccountJid;
+ errorLayout = this.mAccountJidLayout;
}
- errorTextField.setError(getString(this.mAccount.getStatus().getReadableId()));
+ errorLayout.setError(getString(this.mAccount.getStatus().getReadableId()));
if (init || !accountInfoEdited()) {
- errorTextField.requestFocus();
+ errorLayout.requestFocus();
}
} else {
- this.mAccountJid.setError(null);
- this.mPassword.setError(null);
- this.mHostname.setError(null);
+ errorLayout = null;
}
- this.mStats.setVisibility(View.GONE);
+ removeErrorsOnAllBut(errorLayout);
+ this.binding.stats.setVisibility(View.GONE);
+ this.binding.otherDeviceKeysCard.setVisibility(View.GONE);
+ }
+ }
+
+ private void removeErrorsOnAllBut(TextInputLayout exception) {
+ if (this.mAccountJidLayout != exception) {
+ this.mAccountJidLayout.setErrorEnabled(false);
+ this.mAccountJidLayout.setError(null);
+ }
+ if (this.mPasswordLayout != exception) {
+ this.mPasswordLayout.setErrorEnabled(false);
+ this.mPasswordLayout.setError(null);
+ }
+ if (this.mHostnameLayout != exception) {
+ this.mHostnameLayout.setErrorEnabled(false);
+ this.mHostnameLayout.setError(null);
+ }
+ if (this.mPortLayout != exception) {
+ this.mPortLayout.setErrorEnabled(false);
+ this.mPortLayout.setError(null);
}
}
@@ -1116,53 +1119,44 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
builder.setTitle(R.string.unpublish_pgp);
builder.setMessage(R.string.unpublish_pgp_message);
builder.setNegativeButton(R.string.cancel, null);
- builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- mAccount.setPgpSignId(0);
- mAccount.unsetPgpSignature();
- xmppConnectionService.databaseBackend.updateAccount(mAccount);
- xmppConnectionService.sendPresence(mAccount);
- refreshUiReal();
- }
+ builder.setPositiveButton(R.string.confirm, (dialogInterface, i) -> {
+ mAccount.setPgpSignId(0);
+ mAccount.unsetPgpSignature();
+ xmppConnectionService.databaseBackend.updateAccount(mAccount);
+ xmppConnectionService.sendPresence(mAccount);
+ refreshUiReal();
});
builder.create().show();
}
private void showOsOptimizationWarning(boolean showBatteryWarning, boolean showDataSaverWarning) {
- this.mOsOptimizations.setVisibility(showBatteryWarning || showDataSaverWarning ? View.VISIBLE : View.GONE);
+ this.binding.osOptimization.setVisibility(showBatteryWarning || showDataSaverWarning ? View.VISIBLE : View.GONE);
if (showDataSaverWarning) {
- this.mDisableOsOptimizationsHeadline.setText(R.string.data_saver_enabled);
+ this.binding.osOptimizationHeadline.setText(R.string.data_saver_enabled);
this.getmDisableOsOptimizationsBody.setText(R.string.data_saver_enabled_explained);
this.mDisableOsOptimizationsButton.setText(R.string.allow);
- this.mDisableOsOptimizationsButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS);
- Uri uri = Uri.parse("package:" + getPackageName());
- intent.setData(uri);
- try {
- startActivityForResult(intent, REQUEST_DATA_SAVER);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(EditAccountActivity.this, R.string.device_does_not_support_data_saver, Toast.LENGTH_SHORT).show();
- }
+ this.mDisableOsOptimizationsButton.setOnClickListener(v -> {
+ Intent intent = new Intent(Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS);
+ Uri uri = Uri.parse("package:" + getPackageName());
+ intent.setData(uri);
+ try {
+ startActivityForResult(intent, REQUEST_DATA_SAVER);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(EditAccountActivity.this, R.string.device_does_not_support_data_saver, Toast.LENGTH_SHORT).show();
}
});
} else if (showBatteryWarning) {
this.mDisableOsOptimizationsButton.setText(R.string.disable);
- this.mDisableOsOptimizationsHeadline.setText(R.string.battery_optimizations_enabled);
+ this.binding.osOptimizationHeadline.setText(R.string.battery_optimizations_enabled);
this.getmDisableOsOptimizationsBody.setText(R.string.battery_optimizations_enabled_explained);
- this.mDisableOsOptimizationsButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
- Uri uri = Uri.parse("package:" + getPackageName());
- intent.setData(uri);
- try {
- startActivityForResult(intent, REQUEST_BATTERY_OP);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(EditAccountActivity.this, R.string.device_does_not_support_battery_op, Toast.LENGTH_SHORT).show();
- }
+ this.mDisableOsOptimizationsButton.setOnClickListener(v -> {
+ Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+ Uri uri = Uri.parse("package:" + getPackageName());
+ intent.setData(uri);
+ try {
+ startActivityForResult(intent, REQUEST_BATTERY_OP);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(EditAccountActivity.this, R.string.device_does_not_support_battery_op, Toast.LENGTH_SHORT).show();
}
});
}
@@ -1175,12 +1169,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
builder.setMessage(getString(R.string.clear_other_devices_desc));
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.accept),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mAccount.getAxolotlService().wipeOtherPepDevices();
- }
- });
+ (dialog, which) -> mAccount.getAxolotlService().wipeOtherPepDevices());
builder.create().show();
}
@@ -1208,58 +1197,46 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
@Override
public void onCaptchaRequested(final Account account, final String id, final Data data, final Bitmap captcha) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if ((mCaptchaDialog != null) && mCaptchaDialog.isShowing()) {
- mCaptchaDialog.dismiss();
- }
- final AlertDialog.Builder builder = new AlertDialog.Builder(EditAccountActivity.this);
- final View view = getLayoutInflater().inflate(R.layout.captcha, null);
- final ImageView imageView = view.findViewById(R.id.captcha);
- final EditText input = view.findViewById(R.id.input);
- imageView.setImageBitmap(captcha);
-
- builder.setTitle(getString(R.string.captcha_required));
- builder.setView(view);
-
- builder.setPositiveButton(getString(R.string.ok),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String rc = input.getText().toString();
- data.put("username", account.getUsername());
- data.put("password", account.getPassword());
- data.put("ocr", rc);
- data.submit();
-
- if (xmppConnectionServiceBound) {
- xmppConnectionService.sendCreateAccountWithCaptchaPacket(
- account, id, data);
- }
- }
- });
- builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (xmppConnectionService != null) {
- xmppConnectionService.sendCreateAccountWithCaptchaPacket(account, null, null);
+ runOnUiThread(() -> {
+ if ((mCaptchaDialog != null) && mCaptchaDialog.isShowing()) {
+ mCaptchaDialog.dismiss();
+ }
+ final AlertDialog.Builder builder = new AlertDialog.Builder(EditAccountActivity.this);
+ final View view = getLayoutInflater().inflate(R.layout.captcha, null);
+ final ImageView imageView = view.findViewById(R.id.captcha);
+ final EditText input = view.findViewById(R.id.input);
+ imageView.setImageBitmap(captcha);
+
+ builder.setTitle(getString(R.string.captcha_required));
+ builder.setView(view);
+
+ builder.setPositiveButton(getString(R.string.ok),
+ (dialog, which) -> {
+ String rc = input.getText().toString();
+ data.put("username", account.getUsername());
+ data.put("password", account.getPassword());
+ data.put("ocr", rc);
+ data.submit();
+
+ if (xmppConnectionServiceBound) {
+ xmppConnectionService.sendCreateAccountWithCaptchaPacket(
+ account, id, data);
}
- }
- });
+ });
+ builder.setNegativeButton(getString(R.string.cancel), (dialog, which) -> {
+ if (xmppConnectionService != null) {
+ xmppConnectionService.sendCreateAccountWithCaptchaPacket(account, null, null);
+ }
+ });
- builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- if (xmppConnectionService != null) {
- xmppConnectionService.sendCreateAccountWithCaptchaPacket(account, null, null);
- }
- }
- });
- mCaptchaDialog = builder.create();
- mCaptchaDialog.show();
- input.requestFocus();
- }
+ builder.setOnCancelListener(dialog -> {
+ if (xmppConnectionService != null) {
+ xmppConnectionService.sendCreateAccountWithCaptchaPacket(account, null, null);
+ }
+ });
+ mCaptchaDialog = builder.create();
+ mCaptchaDialog.show();
+ input.requestFocus();
});
}
@@ -1274,46 +1251,32 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
@Override
public void onPreferencesFetched(final Element prefs) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (mFetchingMamPrefsToast != null) {
- mFetchingMamPrefsToast.cancel();
- }
- AlertDialog.Builder builder = new Builder(EditAccountActivity.this);
- builder.setTitle(R.string.server_side_mam_prefs);
- String defaultAttr = prefs.getAttribute("default");
- final List<String> defaults = Arrays.asList("never", "roster", "always");
- final AtomicInteger choice = new AtomicInteger(Math.max(0, defaults.indexOf(defaultAttr)));
- builder.setSingleChoiceItems(R.array.mam_prefs, choice.get(), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- choice.set(which);
- }
- });
- builder.setNegativeButton(R.string.cancel, null);
- builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- prefs.setAttribute("default", defaults.get(choice.get()));
- xmppConnectionService.pushMamPreferences(mAccount, prefs);
- }
- });
- builder.create().show();
+ runOnUiThread(() -> {
+ if (mFetchingMamPrefsToast != null) {
+ mFetchingMamPrefsToast.cancel();
}
+ Builder builder = new Builder(EditAccountActivity.this);
+ builder.setTitle(R.string.server_side_mam_prefs);
+ String defaultAttr = prefs.getAttribute("default");
+ final List<String> defaults = Arrays.asList("never", "roster", "always");
+ final AtomicInteger choice = new AtomicInteger(Math.max(0, defaults.indexOf(defaultAttr)));
+ builder.setSingleChoiceItems(R.array.mam_prefs, choice.get(), (dialog, which) -> choice.set(which));
+ builder.setNegativeButton(R.string.cancel, null);
+ builder.setPositiveButton(R.string.ok, (dialog, which) -> {
+ prefs.setAttribute("default", defaults.get(choice.get()));
+ xmppConnectionService.pushMamPreferences(mAccount, prefs);
+ });
+ builder.create().show();
});
}
@Override
public void onPreferencesFetchFailed() {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (mFetchingMamPrefsToast != null) {
- mFetchingMamPrefsToast.cancel();
- }
- Toast.makeText(EditAccountActivity.this, R.string.unable_to_fetch_mam_prefs, Toast.LENGTH_LONG).show();
+ runOnUiThread(() -> {
+ if (mFetchingMamPrefsToast != null) {
+ mFetchingMamPrefsToast.cancel();
}
+ Toast.makeText(EditAccountActivity.this, R.string.unable_to_fetch_mam_prefs, Toast.LENGTH_LONG).show();
});
}
diff --git a/src/main/java/de/pixart/messenger/ui/EnterJidDialog.java b/src/main/java/de/pixart/messenger/ui/EnterJidDialog.java
index 4fabd3e89..d43c34ee4 100644
--- a/src/main/java/de/pixart/messenger/ui/EnterJidDialog.java
+++ b/src/main/java/de/pixart/messenger/ui/EnterJidDialog.java
@@ -1,6 +1,6 @@
package de.pixart.messenger.ui;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
diff --git a/src/main/java/de/pixart/messenger/ui/LocationActivity.java b/src/main/java/de/pixart/messenger/ui/LocationActivity.java
index 6389fa7d4..04bd03584 100644
--- a/src/main/java/de/pixart/messenger/ui/LocationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/LocationActivity.java
@@ -6,10 +6,11 @@ import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
import de.pixart.messenger.Config;
-public abstract class LocationActivity extends Activity implements LocationListener {
+public abstract class LocationActivity extends AppCompatActivity implements LocationListener {
private LocationManager locationManager;
@Override
diff --git a/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java b/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java
index 2d0d98ce7..b98efde3b 100644
--- a/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ManageAccountActivity.java
@@ -1,12 +1,12 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
+import android.support.v7.app.ActionBar;
import android.util.Pair;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -60,7 +60,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
accountList.clear();
accountList.addAll(xmppConnectionService.getAccounts());
}
- ActionBar actionBar = getActionBar();
+ ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(this.accountList.size() > 0);
actionBar.setDisplayHomeAsUpEnabled(this.accountList.size() > 0);
diff --git a/src/main/java/de/pixart/messenger/ui/MemorizingActivity.java b/src/main/java/de/pixart/messenger/ui/MemorizingActivity.java
new file mode 100644
index 000000000..8172e6f9c
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/ui/MemorizingActivity.java
@@ -0,0 +1,119 @@
+/* MemorizingTrustManager - a TrustManager which asks the user about invalid
+ * certificates and memorizes their decision.
+ *
+ * Copyright (c) 2010 Georg Lukas <georg@op-co.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package de.pixart.messenger.ui;
+
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import de.pixart.messenger.R;
+import de.pixart.messenger.entities.MTMDecision;
+import de.pixart.messenger.services.MemorizingTrustManager;
+
+public class MemorizingActivity extends AppCompatActivity implements OnClickListener,OnCancelListener {
+
+ private final static Logger LOGGER = Logger.getLogger(MemorizingActivity.class.getName());
+
+ int decisionId;
+
+ AlertDialog dialog;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ LOGGER.log(Level.FINE, "onCreate");
+ //setTheme(findTheme());
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ Intent i = getIntent();
+ decisionId = i.getIntExtra(MemorizingTrustManager.DECISION_INTENT_ID, MTMDecision.DECISION_INVALID);
+ int titleId = i.getIntExtra(MemorizingTrustManager.DECISION_TITLE_ID, R.string.mtm_accept_cert);
+ String cert = i.getStringExtra(MemorizingTrustManager.DECISION_INTENT_CERT);
+ LOGGER.log(Level.FINE, "onResume with " + i.getExtras() + " decId=" + decisionId + " data: " + i.getData());
+ dialog = new AlertDialog.Builder(this).setTitle(titleId)
+ .setMessage(cert)
+ .setPositiveButton(R.string.always, this)
+ .setNeutralButton(R.string.once, this)
+ .setNegativeButton(R.string.cancel, this)
+ .setOnCancelListener(this)
+ .create();
+ dialog.show();
+ }
+
+ @Override
+ protected void onPause() {
+ if (dialog.isShowing())
+ dialog.dismiss();
+ super.onPause();
+ }
+
+ void sendDecision(int decision) {
+ LOGGER.log(Level.FINE, "Sending decision: " + decision);
+ MemorizingTrustManager.interactResult(decisionId, decision);
+ finish();
+ }
+
+ protected int findTheme() {
+ return 0;
+ //return getPreferences().getString(SettingsActivity.THEME, getResources().getString(R.string.theme)).equals("dark") ? R.style.ConversationsTheme_Dark : R.style.ConversationsTheme;
+ }
+
+ protected SharedPreferences getPreferences() {
+ return PreferenceManager
+ .getDefaultSharedPreferences(getApplicationContext());
+ }
+
+ // react on AlertDialog button press
+ public void onClick(DialogInterface dialog, int btnId) {
+ int decision;
+ dialog.dismiss();
+ switch (btnId) {
+ case DialogInterface.BUTTON_POSITIVE:
+ decision = MTMDecision.DECISION_ALWAYS;
+ break;
+ case DialogInterface.BUTTON_NEUTRAL:
+ decision = MTMDecision.DECISION_ONCE;
+ break;
+ default:
+ decision = MTMDecision.DECISION_ABORT;
+ }
+ sendDecision(decision);
+ }
+
+ public void onCancel(DialogInterface dialog) {
+ sendDecision(MTMDecision.DECISION_ABORT);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/ui/OmemoActivity.java b/src/main/java/de/pixart/messenger/ui/OmemoActivity.java
index f45134e34..a549c76e3 100644
--- a/src/main/java/de/pixart/messenger/ui/OmemoActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/OmemoActivity.java
@@ -1,16 +1,15 @@
package de.pixart.messenger.ui;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
import android.content.Intent;
+import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AlertDialog;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CompoundButton;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -22,8 +21,8 @@ import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.axolotl.FingerprintStatus;
import de.pixart.messenger.crypto.axolotl.XmppAxolotlSession;
+import de.pixart.messenger.databinding.ContactKeyBinding;
import de.pixart.messenger.entities.Account;
-import de.pixart.messenger.ui.widget.Switch;
import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.XmppUri;
import de.pixart.messenger.utils.zxing.IntentIntegrator;
@@ -116,12 +115,7 @@ public abstract class OmemoActivity extends XmppActivity {
session.getTrust(),
true,
true,
- new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(isChecked));
- }
- });
+ (buttonView, isChecked) -> account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(isChecked)));
}
protected void addFingerprintRowWithListeners(LinearLayout keys, final Account account,
@@ -133,110 +127,81 @@ public abstract class OmemoActivity extends XmppActivity {
CompoundButton.OnCheckedChangeListener
onCheckedChangeListener) {
- View view = getLayoutInflater().inflate(R.layout.contact_key, keys, false);
- TextView key = view.findViewById(R.id.key);
- TextView keyType = view.findViewById(R.id.key_type);
+ ContactKeyBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.contact_key, keys, true);
if (Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509) {
- View.OnClickListener listener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showX509Certificate(account, fingerprint);
- }
- };
- key.setOnClickListener(listener);
- keyType.setOnClickListener(listener);
+ binding.key.setOnClickListener(v -> showX509Certificate(account, fingerprint));
+ binding.keyType.setOnClickListener(v -> showX509Certificate(account, fingerprint));
}
- Switch trustToggle = view.findViewById(R.id.tgl_trust);
- ImageView verifiedFingerprintSymbol = view.findViewById(R.id.verified_fingerprint);
- trustToggle.setVisibility(View.VISIBLE);
- registerForContextMenu(view);
- view.setTag(R.id.TAG_ACCOUNT, account);
- view.setTag(R.id.TAG_FINGERPRINT, fingerprint);
- view.setTag(R.id.TAG_FINGERPRINT_STATUS, status);
+ binding.tglTrust.setVisibility(View.VISIBLE);
+ registerForContextMenu(binding.getRoot());
+ binding.getRoot().setTag(R.id.TAG_ACCOUNT, account);
+ binding.getRoot().setTag(R.id.TAG_FINGERPRINT, fingerprint);
+ binding.getRoot().setTag(R.id.TAG_FINGERPRINT_STATUS, status);
boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509;
final View.OnClickListener toast;
- trustToggle.setChecked(status.isTrusted(), false);
+ binding.tglTrust.setChecked(status.isTrusted());
if (status.isActive()) {
- key.setTextColor(getPrimaryTextColor());
- keyType.setTextColor(getSecondaryTextColor());
+ binding.key.setTextColor(getPrimaryTextColor());
+ binding.keyType.setTextColor(getSecondaryTextColor());
if (status.isVerified()) {
- verifiedFingerprintSymbol.setVisibility(View.VISIBLE);
- verifiedFingerprintSymbol.setAlpha(1.0f);
- trustToggle.setVisibility(View.GONE);
- verifiedFingerprintSymbol.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- replaceToast(getString(R.string.this_device_has_been_verified), false);
- }
- });
+ binding.verifiedFingerprint.setVisibility(View.VISIBLE);
+ binding.verifiedFingerprint.setAlpha(1.0f);
+ binding.tglTrust.setVisibility(View.GONE);
+ binding.verifiedFingerprint.setOnClickListener(v -> replaceToast(getString(R.string.this_device_has_been_verified), false));
toast = null;
} else {
- verifiedFingerprintSymbol.setVisibility(View.GONE);
- trustToggle.setVisibility(View.VISIBLE);
- trustToggle.setOnCheckedChangeListener(onCheckedChangeListener);
+ binding.verifiedFingerprint.setVisibility(View.GONE);
+ binding.tglTrust.setVisibility(View.VISIBLE);
+ binding.tglTrust.setOnCheckedChangeListener(onCheckedChangeListener);
if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED && undecidedNeedEnablement) {
- trustToggle.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(false));
- v.setEnabled(true);
- v.setOnClickListener(null);
- }
+ binding.buttonEnableDevice.setVisibility(View.VISIBLE);
+ binding.buttonEnableDevice.setOnClickListener(v -> {
+ account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(false));
+ binding.buttonEnableDevice.setVisibility(View.GONE);
+ binding.tglTrust.setVisibility(View.VISIBLE);
});
- trustToggle.setEnabled(false);
+ binding.tglTrust.setVisibility(View.GONE);
} else {
- trustToggle.setOnClickListener(null);
- trustToggle.setEnabled(true);
+ binding.tglTrust.setOnClickListener(null);
+ binding.tglTrust.setEnabled(true);
}
- toast = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- hideToast();
- }
- };
+ toast = v -> hideToast();
}
} else {
- key.setTextColor(getTertiaryTextColor());
- keyType.setTextColor(getTertiaryTextColor());
- toast = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- replaceToast(getString(R.string.this_device_is_no_longer_in_use), false);
- }
- };
+ binding.key.setTextColor(getTertiaryTextColor());
+ binding.keyType.setTextColor(getTertiaryTextColor());
+ toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false);
if (status.isVerified()) {
- trustToggle.setVisibility(View.GONE);
- verifiedFingerprintSymbol.setVisibility(View.VISIBLE);
- verifiedFingerprintSymbol.setAlpha(0.4368f);
- verifiedFingerprintSymbol.setOnClickListener(toast);
+ binding.tglTrust.setVisibility(View.GONE);
+ binding.verifiedFingerprint.setVisibility(View.VISIBLE);
+ binding.verifiedFingerprint.setAlpha(0.4368f);
+ binding.verifiedFingerprint.setOnClickListener(toast);
} else {
- trustToggle.setVisibility(View.VISIBLE);
- verifiedFingerprintSymbol.setVisibility(View.GONE);
- trustToggle.setOnClickListener(null);
- trustToggle.setEnabled(false);
- trustToggle.setOnClickListener(toast);
+ binding.tglTrust.setVisibility(View.VISIBLE);
+ binding.verifiedFingerprint.setVisibility(View.GONE);
+ binding.tglTrust.setOnClickListener(null);
+ binding.tglTrust.setEnabled(false);
+ binding.tglTrust.setOnClickListener(toast);
}
}
- view.setOnClickListener(toast);
- key.setOnClickListener(toast);
- keyType.setOnClickListener(toast);
+ binding.getRoot().setOnClickListener(toast);
+ binding.key.setOnClickListener(toast);
+ binding.keyType.setOnClickListener(toast);
if (showTag) {
- keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
+ binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
} else {
- keyType.setVisibility(View.GONE);
+ binding.keyType.setVisibility(View.GONE);
}
if (highlight) {
- keyType.setTextColor(ContextCompat.getColor(this, R.color.accent));
- keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message));
+ binding.keyType.setTextColor(ContextCompat.getColor(this, R.color.accent));
+ binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message));
} else {
- keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
+ binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint));
}
- key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)));
-
- keys.addView(view);
+ binding.key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)));
}
public void showPurgeKeyDialog(final Account account, final String fingerprint) {
@@ -245,12 +210,9 @@ public abstract class OmemoActivity extends XmppActivity {
builder.setMessage(R.string.distrust_omemo_key_text);
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(R.string.confirm,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- account.getAxolotlService().distrustFingerprint(fingerprint);
- refreshUi();
- }
+ (dialog, which) -> {
+ account.getAxolotlService().distrustFingerprint(fingerprint);
+ refreshUi();
});
builder.create().show();
}
diff --git a/src/main/java/de/pixart/messenger/ui/RecordingActivity.java b/src/main/java/de/pixart/messenger/ui/RecordingActivity.java
index cfa743c69..21462ebfa 100644
--- a/src/main/java/de/pixart/messenger/ui/RecordingActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/RecordingActivity.java
@@ -8,6 +8,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
+import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
@@ -24,7 +25,7 @@ import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.persistance.FileBackend;
-public class RecordingActivity extends Activity implements View.OnClickListener {
+public class RecordingActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTimerTextView;
private Button mCancelButton;
diff --git a/src/main/java/de/pixart/messenger/ui/SetPresenceActivity.java b/src/main/java/de/pixart/messenger/ui/SetPresenceActivity.java
index 18d28914e..d4bddb534 100644
--- a/src/main/java/de/pixart/messenger/ui/SetPresenceActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/SetPresenceActivity.java
@@ -1,6 +1,7 @@
package de.pixart.messenger.ui;
import android.content.Intent;
+import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.os.Handler;
import android.util.Pair;
@@ -9,18 +10,13 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-import android.widget.Spinner;
import android.widget.TextView;
import java.util.List;
import de.pixart.messenger.R;
+import de.pixart.messenger.databinding.ActivitySetPresenceBinding;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.ListItem;
import de.pixart.messenger.entities.Presence;
@@ -33,12 +29,8 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
protected Account mAccount;
private List<PresenceTemplate> mTemplates;
- //UI Elements
- protected ScrollView mScrollView;
- protected EditText mStatusMessage;
- protected Spinner mShowSpinner;
- protected CheckBox mAllAccounts;
- protected LinearLayout mTemplatesView;
+ private ActivitySetPresenceBinding binding;
+
private Pair<Integer, Intent> mPostponedActivityResult;
private Runnable onPresenceChanged = new Runnable() {
@@ -50,24 +42,13 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_set_presence);
- mScrollView = findViewById(R.id.scroll_view);
- mShowSpinner = findViewById(R.id.presence_show);
+ this.binding = DataBindingUtil.setContentView(this, R.layout.activity_set_presence);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
R.array.presence_show_options,
R.layout.simple_list_item);
- mShowSpinner.setAdapter(adapter);
- mShowSpinner.setSelection(1);
- mStatusMessage = findViewById(R.id.presence_status_message);
- mAllAccounts = findViewById(R.id.all_accounts);
- mTemplatesView = findViewById(R.id.templates);
- final Button changePresence = findViewById(R.id.change_presence);
- changePresence.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- executeChangePresence();
- }
- });
+ this.binding.presenceShow.setAdapter(adapter);
+ this.binding.presenceShow.setSelection(1);
+ this.binding.changePresence.setOnClickListener(v -> executeChangePresence());
}
@Override
@@ -105,8 +86,8 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
private void executeChangePresence() {
Presence.Status status = getStatusFromSpinner();
- boolean allAccounts = mAllAccounts.isChecked();
- String statusMessage = mStatusMessage.getText().toString().trim();
+ boolean allAccounts = this.binding.allAccounts.isChecked();
+ String statusMessage = this.binding.presenceStatusMessage.getText().toString().trim();
if (allAccounts && noAccountUsesPgp()) {
xmppConnectionService.changeStatus(status, statusMessage);
finish();
@@ -122,7 +103,7 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
}
private Presence.Status getStatusFromSpinner() {
- switch (mShowSpinner.getSelectedItemPosition()) {
+ switch (this.binding.presenceShow.getSelectedItemPosition()) {
case 0:
return Presence.Status.CHAT;
case 2:
@@ -139,19 +120,19 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
private void setStatusInSpinner(Presence.Status status) {
switch (status) {
case AWAY:
- mShowSpinner.setSelection(2);
+ this.binding.presenceShow.setSelection(2);
break;
case XA:
- mShowSpinner.setSelection(3);
+ this.binding.presenceShow.setSelection(3);
break;
case CHAT:
- mShowSpinner.setSelection(0);
+ this.binding.presenceShow.setSelection(0);
break;
case DND:
- mShowSpinner.setSelection(4);
+ this.binding.presenceShow.setSelection(4);
break;
default:
- mShowSpinner.setSelection(1);
+ this.binding.presenceShow.setSelection(1);
break;
}
}
@@ -167,29 +148,29 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
if (mAccount != null) {
setStatusInSpinner(mAccount.getPresenceStatus());
String message = mAccount.getPresenceStatusMessage();
- if (mStatusMessage.getText().length() == 0 && message != null) {
- mStatusMessage.append(message);
+ if (this.binding.presenceStatusMessage.getText().length() == 0 && message != null) {
+ this.binding.presenceStatusMessage.append(message);
}
mTemplates = xmppConnectionService.getPresenceTemplates(mAccount);
if (this.mPostponedActivityResult != null) {
this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
}
boolean e = noAccountUsesPgp();
- mAllAccounts.setEnabled(e);
- mAllAccounts.setTextColor(e ? getPrimaryTextColor() : getSecondaryTextColor());
+ this.binding.allAccounts.setEnabled(e);
+ this.binding.allAccounts.setTextColor(e ? getPrimaryTextColor() : getSecondaryTextColor());
}
redrawTemplates();
}
private void redrawTemplates() {
if (mTemplates == null || mTemplates.size() == 0) {
- mTemplatesView.setVisibility(View.GONE);
+ this.binding.templates.setVisibility(View.GONE);
} else {
- mTemplatesView.removeAllViews();
- mTemplatesView.setVisibility(View.VISIBLE);
+ this.binding.templates.removeAllViews();
+ this.binding.templates.setVisibility(View.VISIBLE);
LayoutInflater inflater = getLayoutInflater();
for (PresenceTemplate template : mTemplates) {
- View templateLayout = inflater.inflate(R.layout.presence_template, mTemplatesView, false);
+ View templateLayout = inflater.inflate(R.layout.presence_template, this.binding.templates, false);
templateLayout.setTag(template);
setListItemBackgroundOnView(templateLayout);
templateLayout.setOnClickListener(this);
@@ -202,7 +183,7 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
status.setText(tag.getName());
status.setBackgroundColor(tag.getColor());
message.setText(template.getStatusMessage());
- mTemplatesView.addView(templateLayout);
+ this.binding.templates.addView(templateLayout);
}
}
}
@@ -215,14 +196,9 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
}
if (v.getId() == R.id.presence_template) {
setStatusInSpinner(template.getStatus());
- mStatusMessage.getEditableText().clear();
- mStatusMessage.getEditableText().append(template.getStatusMessage());
- new Handler().post(new Runnable() {
- @Override
- public void run() {
- mScrollView.smoothScrollTo(0, 0);
- }
- });
+ this.binding.presenceStatusMessage.getEditableText().clear();
+ this.binding.presenceStatusMessage.getEditableText().append(template.getStatusMessage());
+ new Handler().post(() -> this.binding.scrollView.smoothScrollTo(0,0));
} else if (v.getId() == R.id.delete_button) {
xmppConnectionService.databaseBackend.deletePresenceTemplate(template);
mTemplates.remove(template);
diff --git a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
index 988f4be1e..cf1ccd658 100644
--- a/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/SettingsActivity.java
@@ -1,6 +1,5 @@
package de.pixart.messenger.ui;
-import android.app.AlertDialog;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
@@ -8,6 +7,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
@@ -16,12 +16,14 @@ import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
+import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
+import java.io.File;
import java.security.KeyStoreException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -29,11 +31,11 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
-import de.duenndns.ssl.MemorizingTrustManager;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.services.ExportLogsService;
+import de.pixart.messenger.services.MemorizingTrustManager;
import de.pixart.messenger.xmpp.XmppConnection;
import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.xmpp.jid.Jid;
@@ -70,6 +72,10 @@ public class SettingsActivity extends XmppActivity implements
mSettingsFragment = new SettingsFragment();
fm.beginTransaction().replace(android.R.id.content, mSettingsFragment).commit();
}
+ mSettingsFragment.setActivityIntent(getIntent());
+
+ this.mTheme = findTheme();
+ setTheme(this.mTheme);
}
@Override
@@ -83,7 +89,9 @@ public class SettingsActivity extends XmppActivity implements
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
multiAccountPreference = mSettingsFragment.findPreference("enable_multi_accounts");
- isMultiAccountChecked = ((CheckBoxPreference) multiAccountPreference).isChecked();
+ if (multiAccountPreference != null) {
+ isMultiAccountChecked = ((CheckBoxPreference) multiAccountPreference).isChecked();
+ }
ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource");
if (resources != null) {
@@ -121,9 +129,8 @@ public class SettingsActivity extends XmppActivity implements
}
final Preference removeCertsPreference = mSettingsFragment.findPreference("remove_trusted_certificates");
- removeCertsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
+ if (removeCertsPreference != null) {
+ removeCertsPreference.setOnPreferenceClickListener(preference -> {
final MemorizingTrustManager mtm = xmppConnectionService.getMemorizingTrustManager();
final ArrayList<String> aliases = Collections.list(mtm.getCertificates());
if (aliases.size() == 0) {
@@ -134,44 +141,37 @@ public class SettingsActivity extends XmppActivity implements
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SettingsActivity.this);
dialogBuilder.setTitle(getResources().getString(R.string.dialog_manage_certs_title));
dialogBuilder.setMultiChoiceItems(aliases.toArray(new CharSequence[aliases.size()]), null,
- new DialogInterface.OnMultiChoiceClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int indexSelected,
- boolean isChecked) {
- if (isChecked) {
- selectedItems.add(indexSelected);
- } else if (selectedItems.contains(indexSelected)) {
- selectedItems.remove(Integer.valueOf(indexSelected));
- }
- if (selectedItems.size() > 0)
- ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
- else {
- ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
- }
+ (dialog, indexSelected, isChecked) -> {
+ if (isChecked) {
+ selectedItems.add(indexSelected);
+ } else if (selectedItems.contains(indexSelected)) {
+ selectedItems.remove(Integer.valueOf(indexSelected));
+ }
+ if (selectedItems.size() > 0)
+ ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
+ else {
+ ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
}
});
dialogBuilder.setPositiveButton(
- getResources().getString(R.string.dialog_manage_certs_positivebutton), new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- int count = selectedItems.size();
- if (count > 0) {
- for (int i = 0; i < count; i++) {
- try {
- Integer item = Integer.valueOf(selectedItems.get(i).toString());
- String alias = aliases.get(item);
- mtm.deleteCertificate(alias);
- } catch (KeyStoreException e) {
- e.printStackTrace();
- displayToast("Error: " + e.getLocalizedMessage());
- }
- }
- if (xmppConnectionServiceBound) {
- reconnectAccounts();
+ getResources().getString(R.string.dialog_manage_certs_positivebutton), (dialog, which) -> {
+ int count = selectedItems.size();
+ if (count > 0) {
+ for (int i = 0; i < count; i++) {
+ try {
+ Integer item = Integer.valueOf(selectedItems.get(i).toString());
+ String alias = aliases.get(item);
+ mtm.deleteCertificate(alias);
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ displayToast("Error: " + e.getLocalizedMessage());
}
- displayToast(getResources().getQuantityString(R.plurals.toast_delete_certificates, count, count));
}
+ if (xmppConnectionServiceBound) {
+ reconnectAccounts();
+ }
+ displayToast(getResources().getQuantityString(R.plurals.toast_delete_certificates, count, count));
}
});
dialogBuilder.setNegativeButton(getResources().getString(R.string.dialog_manage_certs_negativebutton), null);
@@ -179,33 +179,41 @@ public class SettingsActivity extends XmppActivity implements
removeCertsDialog.show();
removeCertsDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
return true;
- }
- });
+ });
+ }
final Preference exportLogsPreference = mSettingsFragment.findPreference("export_logs");
- exportLogsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
+ if (exportLogsPreference != null) {
+ exportLogsPreference.setOnPreferenceClickListener(preference -> {
if (hasStoragePermission(REQUEST_WRITE_LOGS)) {
startExport();
}
return true;
+ });
+ }
+
+ if (Config.ONLY_INTERNAL_STORAGE) {
+ final Preference cleanCachePreference = mSettingsFragment.findPreference("clean_cache");
+ if (cleanCachePreference != null) {
+ cleanCachePreference.setOnPreferenceClickListener(preference -> cleanCache());
}
- });
- final Preference deleteOmemoPreference = mSettingsFragment.findPreference("delete_omemo_identities");
- deleteOmemoPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- deleteOmemoIdentities();
- return true;
+ final Preference cleanPrivateStoragePreference = mSettingsFragment.findPreference("clean_private_storage");
+ if (cleanPrivateStoragePreference != null) {
+ cleanPrivateStoragePreference.setOnPreferenceClickListener(preference -> cleanPrivateStorage());
}
- });
+ }
+
+ final Preference deleteOmemoPreference = mSettingsFragment.findPreference("delete_omemo_identities");
+ if (deleteOmemoPreference != null) {
+ deleteOmemoPreference.setOnPreferenceClickListener(preference -> deleteOmemoIdentities());
+ }
final Preference enableMultiAccountsPreference = mSettingsFragment.findPreference("enable_multi_accounts");
- Log.d(Config.LOGTAG, "Multi account checkbox checked: " + isMultiAccountChecked);
- if (isMultiAccountChecked) {
- enableMultiAccountsPreference.setEnabled(false);
+ if (enableMultiAccountsPreference != null) {
+ Log.d(Config.LOGTAG, "Multi account checkbox checked: " + isMultiAccountChecked);
+ if (isMultiAccountChecked) {
+ enableMultiAccountsPreference.setEnabled(false);
/*
if (xmppConnectionServiceBound) { // todo doesn't work --> it seems the service is never bound
final List<Account> accounts = xmppConnectionService.getAccounts();
@@ -221,12 +229,13 @@ public class SettingsActivity extends XmppActivity implements
enableMultiAccountsPreference.setEnabled(false);
}
*/
- } else {
- enableMultiAccountsPreference.setEnabled(true);
- enableMultiAccountsPreference.setOnPreferenceClickListener(preference -> {
- enableMultiAccounts();
- return true;
- });
+ } else {
+ enableMultiAccountsPreference.setEnabled(true);
+ enableMultiAccountsPreference.setOnPreferenceClickListener(preference -> {
+ enableMultiAccounts();
+ return true;
+ });
+ }
}
}
@@ -234,7 +243,60 @@ public class SettingsActivity extends XmppActivity implements
return i != null && getPackageManager().queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
}
- private void deleteOmemoIdentities() {
+ private boolean cleanCache() {
+ Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ intent.setData(Uri.parse("package:" + getPackageName()));
+ startActivity(intent);
+ return true;
+ }
+
+ private boolean cleanPrivateStorage() {
+ cleanPrivatePictures();
+ cleanPrivateFiles();
+ return true;
+ }
+
+ private void cleanPrivatePictures() {
+ try {
+ File dir = new File(getFilesDir().getAbsolutePath(), "/Pictures/");
+ File[] array = dir.listFiles();
+ if (array != null) {
+ for (int b = 0; b < array.length; b++) {
+ String name = array[b].getName().toLowerCase();
+ if (name.equals(".nomedia")) {
+ continue;
+ }
+ if (array[b].isFile()) {
+ array[b].delete();
+ }
+ }
+ }
+ } catch (Throwable e) {
+ Log.e("CleanCache", e.toString());
+ }
+ }
+
+ private void cleanPrivateFiles() {
+ try {
+ File dir = new File(getFilesDir().getAbsolutePath(), "/Files/");
+ File[] array = dir.listFiles();
+ if (array != null) {
+ for (int b = 0; b < array.length; b++) {
+ String name = array[b].getName().toLowerCase();
+ if (name.equals(".nomedia")) {
+ continue;
+ }
+ if (array[b].isFile()) {
+ array[b].delete();
+ }
+ }
+ }
+ } catch (Throwable e) {
+ Log.e("CleanCache", e.toString());
+ }
+ }
+
+ private boolean deleteOmemoIdentities() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.pref_delete_omemo_identities);
final List<CharSequence> accounts = new ArrayList<>();
@@ -281,6 +343,7 @@ public class SettingsActivity extends XmppActivity implements
AlertDialog dialog = builder.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+ return true;
}
private void enableMultiAccounts() {
diff --git a/src/main/java/de/pixart/messenger/ui/SettingsFragment.java b/src/main/java/de/pixart/messenger/ui/SettingsFragment.java
index 8cea5eb61..939ef6145 100644
--- a/src/main/java/de/pixart/messenger/ui/SettingsFragment.java
+++ b/src/main/java/de/pixart/messenger/ui/SettingsFragment.java
@@ -1,64 +1,58 @@
package de.pixart.messenger.ui;
-import android.app.Dialog;
+import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
+import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
+import android.text.TextUtils;
+import de.pixart.messenger.Config;
import de.pixart.messenger.R;
public class SettingsFragment extends PreferenceFragment {
- //http://stackoverflow.com/questions/16374820/action-bar-home-button-not-functional-with-nested-preferencescreen/16800527#16800527
- private void initializeActionBar(PreferenceScreen preferenceScreen) {
- final Dialog dialog = preferenceScreen.getDialog();
+ private String page = null;
- if (dialog != null) {
- View homeBtn = dialog.findViewById(android.R.id.home);
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
- if (homeBtn != null) {
- View.OnClickListener dismissDialogClickListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dialog.dismiss();
- }
- };
+ // Remove from standard preferences if the flag ONLY_INTERNAL_STORAGE is false
+ if (!Config.ONLY_INTERNAL_STORAGE) {
+ PreferenceCategory mCategory = (PreferenceCategory) findPreference("security_options");
+ if (mCategory != null) {
+ Preference cleanCache = findPreference("clean_cache");
+ Preference cleanPrivateStorage = findPreference("clean_private_storage");
+ mCategory.removePreference(cleanCache);
+ mCategory.removePreference(cleanPrivateStorage);
+ }
+ }
- ViewParent homeBtnContainer = homeBtn.getParent();
+ if (!TextUtils.isEmpty(page)) {
+ openPreferenceScreen(page);
+ }
+ }
- if (homeBtnContainer instanceof FrameLayout) {
- ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();
- if (containerParent instanceof LinearLayout) {
- containerParent.setOnClickListener(dismissDialogClickListener);
- } else {
- ((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
- }
- } else {
- homeBtn.setOnClickListener(dismissDialogClickListener);
+ public void setActivityIntent(final Intent intent) {
+ if (intent != null) {
+ if (Intent.ACTION_VIEW.equals(intent.getAction())) {
+ if (intent.getExtras() != null) {
+ this.page = intent.getExtras().getString("page");
}
}
}
}
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.preferences);
- }
-
- @Override
- public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
- super.onPreferenceTreeClick(preferenceScreen, preference);
- if (preference instanceof PreferenceScreen) {
- initializeActionBar((PreferenceScreen) preference);
+ private void openPreferenceScreen(final String screenName) {
+ final Preference pref = findPreference(screenName);
+ if (pref instanceof PreferenceScreen) {
+ final PreferenceScreen preferenceScreen = (PreferenceScreen) pref;
+ getActivity().setTitle(preferenceScreen.getTitle());
+ preferenceScreen.setDependency("");
+ setPreferenceScreen((PreferenceScreen) pref);
}
- return false;
}
}
diff --git a/src/main/java/de/pixart/messenger/ui/ShareLocationActivity.java b/src/main/java/de/pixart/messenger/ui/ShareLocationActivity.java
index 5a1122c7a..510135c5a 100644
--- a/src/main/java/de/pixart/messenger/ui/ShareLocationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ShareLocationActivity.java
@@ -41,9 +41,9 @@ public class ShareLocationActivity extends LocationActivity implements LocationL
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_locaction);
- if (getActionBar() != null) {
- getActionBar().setHomeButtonEnabled(true);
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
diff --git a/src/main/java/de/pixart/messenger/ui/ShareViaAccountActivity.java b/src/main/java/de/pixart/messenger/ui/ShareViaAccountActivity.java
index 41d22f2a5..e7ee427db 100644
--- a/src/main/java/de/pixart/messenger/ui/ShareViaAccountActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ShareViaAccountActivity.java
@@ -1,7 +1,7 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
import android.os.Bundle;
+import android.support.v7.app.ActionBar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
@@ -31,7 +31,7 @@ public class ShareViaAccountActivity extends XmppActivity {
accountList.clear();
accountList.addAll(xmppConnectionService.getAccounts());
}
- ActionBar actionBar = getActionBar();
+ ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(this.accountList.size() > 0);
actionBar.setDisplayHomeAsUpEnabled(this.accountList.size() > 0);
diff --git a/src/main/java/de/pixart/messenger/ui/ShareWithActivity.java b/src/main/java/de/pixart/messenger/ui/ShareWithActivity.java
index 15e7b7267..64671c1f2 100644
--- a/src/main/java/de/pixart/messenger/ui/ShareWithActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ShareWithActivity.java
@@ -170,9 +170,9 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer
super.onCreate(savedInstanceState);
boolean useBundledEmoji = getPreferences().getBoolean(USE_BUNDLED_EMOJIS, getResources().getBoolean(R.bool.use_bundled_emoji));
new EmojiService(this).init(useBundledEmoji);
- if (getActionBar() != null) {
- getActionBar().setDisplayHomeAsUpEnabled(false);
- getActionBar().setHomeButtonEnabled(false);
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setDisplayHomeAsUpEnabled(false);
+ getSupportActionBar().setHomeButtonEnabled(false);
}
setContentView(R.layout.share_with);
diff --git a/src/main/java/de/pixart/messenger/ui/ShowFullscreenMessageActivity.java b/src/main/java/de/pixart/messenger/ui/ShowFullscreenMessageActivity.java
index 619ab2101..83928d0cd 100644
--- a/src/main/java/de/pixart/messenger/ui/ShowFullscreenMessageActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ShowFullscreenMessageActivity.java
@@ -1,6 +1,5 @@
package de.pixart.messenger.ui;
-import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -11,6 +10,7 @@ import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
@@ -39,7 +39,7 @@ import de.pixart.messenger.utils.ExifHelper;
import static de.pixart.messenger.persistance.FileBackend.close;
-public class ShowFullscreenMessageActivity extends Activity {
+public class ShowFullscreenMessageActivity extends AppCompatActivity {
Integer oldOrientation;
PhotoView mImage;
diff --git a/src/main/java/de/pixart/messenger/ui/ShowLocationActivity.java b/src/main/java/de/pixart/messenger/ui/ShowLocationActivity.java
index 2f844e107..2661589d8 100644
--- a/src/main/java/de/pixart/messenger/ui/ShowLocationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ShowLocationActivity.java
@@ -1,6 +1,5 @@
package de.pixart.messenger.ui;
-import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -12,6 +11,7 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
@@ -30,7 +30,7 @@ import de.pixart.messenger.services.EmojiService;
import static de.pixart.messenger.ui.SettingsActivity.USE_BUNDLED_EMOJIS;
-public class ShowLocationActivity extends Activity {
+public class ShowLocationActivity extends AppCompatActivity {
private Location location;
private String mLocationName;
@@ -39,9 +39,9 @@ public class ShowLocationActivity extends Activity {
super.onCreate(savedInstanceState);
boolean useBundledEmoji = getPreferences().getBoolean(USE_BUNDLED_EMOJIS, getResources().getBoolean(R.bool.use_bundled_emoji));
new EmojiService(this).init(useBundledEmoji);
- if (getActionBar() != null) {
- getActionBar().setHomeButtonEnabled(true);
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
setContentView(R.layout.activity_show_locaction);
diff --git a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
index c1cd8a015..dacc35a8d 100644
--- a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java
@@ -2,15 +2,7 @@ package de.pixart.messenger.ui;
import android.Manifest;
import android.annotation.SuppressLint;
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.AlertDialog;
import android.app.Dialog;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.app.ListFragment;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -18,11 +10,21 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.databinding.DataBindingUtil;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.app.ListFragment;
+import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -39,7 +41,6 @@ import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.CheckBox;
@@ -58,6 +59,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import de.pixart.messenger.Config;
import de.pixart.messenger.R;
+import de.pixart.messenger.databinding.ActivityStartConversationBinding;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Bookmark;
import de.pixart.messenger.entities.Contact;
@@ -78,13 +80,10 @@ import static de.pixart.messenger.ui.SettingsActivity.USE_BUNDLED_EMOJIS;
public class StartConversationActivity extends XmppActivity implements OnRosterUpdate, OnUpdateBlocklist {
- private final int REQUEST_SYNC_CONTACTS = 0x3b28cf;
- private final int REQUEST_CREATE_CONFERENCE = 0x3b39da;
+ private final int REQUEST_SYNC_CONTACTS = 0x28cf;
+ private final int REQUEST_CREATE_CONFERENCE = 0x39da;
public int conference_context_id;
public int contact_context_id;
- private Tab mContactsTab;
- private Tab mConferencesTab;
- private ViewPager mViewPager;
private ListPagerAdapter mListPagerAdapter;
private List<ListItem> contacts = new ArrayList<>();
private ListItemAdapter mContactsAdapter;
@@ -119,29 +118,30 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
return true;
}
};
- private TabListener mTabListener = new TabListener() {
+ private ActionBar.TabListener mTabListener = new ActionBar.TabListener() {
@Override
- public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
return;
}
@Override
- public void onTabSelected(Tab tab, FragmentTransaction ft) {
- mViewPager.setCurrentItem(tab.getPosition());
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
+ binding.startConversationViewPager.setCurrentItem(tab.getPosition());
onTabChanged();
}
@Override
- public void onTabReselected(Tab tab, FragmentTransaction ft) {
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
return;
}
};
private ViewPager.SimpleOnPageChangeListener mOnPageChangeListener = new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
- if (getActionBar() != null) {
- getActionBar().setSelectedNavigationItem(position);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setSelectedNavigationItem(position);
}
onTabChanged();
}
@@ -166,7 +166,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
private TextView.OnEditorActionListener mSearchDone = new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- int pos = getActionBar().getSelectedNavigationIndex();
+ int pos = getSupportActionBar().getSelectedNavigationIndex();
if (pos == 0) {
if (contacts.size() == 1) {
openConversationForContact((Contact) contacts.get(0));
@@ -198,6 +198,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
private String mInitialJid;
private Pair<Integer, Intent> mPostponedActivityResult;
private Toast mToast;
+ private ActivityStartConversationBinding binding;
private UiCallback<Conversation> mAdhocConferenceCallback = new UiCallback<Conversation>() {
@Override
public void success(final Conversation conversation) {
@@ -255,21 +256,25 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new EmojiService(this).init(useBundledEmoji());
- setContentView(R.layout.activity_start_conversation);
- mViewPager = findViewById(R.id.start_conversation_view_pager);
- ActionBar actionBar = getActionBar();
+ this.binding = DataBindingUtil.setContentView(this, R.layout.activity_start_conversation);
+ this.binding.fab.setOnClickListener((v) -> {
+ if (getSupportActionBar().getSelectedNavigationIndex() == 0) {
+ showCreateContactDialog(null, null);
+ } else {
+ showCreateConferenceDialog();
+ }
+ });
+ ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- mContactsTab = actionBar.newTab().setText(R.string.contacts)
- .setTabListener(mTabListener);
- mConferencesTab = actionBar.newTab().setText(R.string.conferences)
- .setTabListener(mTabListener);
+ ActionBar.Tab mContactsTab = actionBar.newTab().setText(R.string.contacts).setTabListener(mTabListener);
+ ActionBar.Tab mConferencesTab = actionBar.newTab().setText(R.string.conferences).setTabListener(mTabListener);
actionBar.addTab(mContactsTab);
actionBar.addTab(mConferencesTab);
- mViewPager.setOnPageChangeListener(mOnPageChangeListener);
- mListPagerAdapter = new ListPagerAdapter(getFragmentManager());
- mViewPager.setAdapter(mListPagerAdapter);
+ binding.startConversationViewPager.setOnPageChangeListener(mOnPageChangeListener);
+ mListPagerAdapter = new ListPagerAdapter(getSupportFragmentManager());
+ binding.startConversationViewPager.setAdapter(mListPagerAdapter);
mConferenceAdapter = new ListItemAdapter(this, conferences);
mContactsAdapter = new ListItemAdapter(this, contacts);
@@ -595,8 +600,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.start_conversation, menu);
- MenuItem menuCreateContact = menu.findItem(R.id.action_create_contact);
- MenuItem menuCreateConference = menu.findItem(R.id.action_conference);
MenuItem menuHideOffline = menu.findItem(R.id.action_hide_offline);
final MenuItem menuActionAccounts = menu.findItem(R.id.action_accounts);
if (xmppConnectionService.getAccounts().size() == 1 && !xmppConnectionService.multipleAccounts()) {
@@ -608,17 +611,11 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
mMenuSearchView = menu.findItem(R.id.action_search);
mMenuSearchView.setOnActionExpandListener(mOnActionExpandListener);
View mSearchView = mMenuSearchView.getActionView();
- mSearchEditText = mSearchView
- .findViewById(R.id.search_field);
+ mSearchEditText = mSearchView.findViewById(R.id.search_field);
mSearchEditText.addTextChangedListener(mSearchTextWatcher);
mSearchEditText.setOnEditorActionListener(mSearchDone);
- if (getActionBar().getSelectedNavigationIndex() == 0) {
- menuCreateConference.setVisible(false);
- } else {
- menuCreateContact.setVisible(false);
- }
if (mInitialJid != null) {
- mMenuSearchView.expandActionView();
+ MenuItemCompat.expandActionView(mMenuSearchView);
mSearchEditText.append(mInitialJid);
filter(mInitialJid);
}
@@ -628,15 +625,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case R.id.action_create_contact:
- showCreateContactDialog(null, null);
- return true;
case R.id.action_join_conference:
showJoinConferenceDialog(null);
return true;
- case R.id.action_create_conference:
- showCreateConferenceDialog();
- return true;
case R.id.action_scan_qr_code:
Intent intent = new Intent(this, UriHandlerActivity.class);
intent.setAction(UriHandlerActivity.ACTION_SCAN_QR_CODE);
@@ -752,7 +743,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
@Override
- public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
if (grantResults.length > 0)
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == REQUEST_SYNC_CONTACTS && xmppConnectionServiceBound) {
@@ -778,7 +769,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
}
final Intent intent = getIntent();
- final ActionBar ab = getActionBar();
+ final ActionBar ab = getSupportActionBar();
boolean init = intent != null && intent.getBooleanExtra("init", false);
boolean noConversations = xmppConnectionService.getConversations().size() == 0;
if ((init || noConversations) && ab != null) {
@@ -945,6 +936,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
private void onTabChanged() {
+ @DrawableRes final int fabDrawable;
+ if (getSupportActionBar().getSelectedNavigationIndex() == 0) {
+ fabDrawable = R.drawable.ic_person_add_white_24dp;
+ } else {
+ fabDrawable = R.drawable.ic_group_add_white_24dp;
+ }
+ binding.fab.setImageResource(fabDrawable);
invalidateOptionsMenu();
}
@@ -980,10 +978,12 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
@Override
- public void onViewCreated(final View view, final Bundle savedInstanceState) {
+ public void onViewCreated(@NonNull final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
registerForContextMenu(getListView());
getListView().setFastScrollEnabled(true);
+ getListView().setDivider(null);
+ getListView().setDividerHeight(0);
}
@Override
@@ -991,6 +991,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
final ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
final StartConversationActivity activity = (StartConversationActivity) getActivity();
+ if (activity == null) {
+ return;
+ }
activity.getMenuInflater().inflate(mResContextMenu, menu);
final AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
if (mResContextMenu == R.menu.conference_context) {
@@ -1019,6 +1022,9 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
@Override
public boolean onContextItemSelected(final MenuItem item) {
StartConversationActivity activity = (StartConversationActivity) getActivity();
+ if (activity == null) {
+ return true;
+ }
switch (item.getItemId()) {
case R.id.context_start_conversation:
activity.openConversationForContact();
@@ -1061,7 +1067,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
@Override
- public void destroyItem(ViewGroup container, int position, Object object) {
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
assert (0 <= position && position < fragments.length);
FragmentTransaction trans = fragmentManager.beginTransaction();
trans.remove(fragments[position]);
@@ -1070,7 +1076,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
@Override
- public Fragment instantiateItem(ViewGroup container, int position) {
+ public Fragment instantiateItem(@NonNull ViewGroup container, int position) {
Fragment fragment = getItem(position);
FragmentTransaction trans = fragmentManager.beginTransaction();
trans.add(container.getId(), fragment, "fragment:" + position);
@@ -1084,7 +1090,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
}
@Override
- public boolean isViewFromObject(View view, Object fragment) {
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object fragment) {
return ((Fragment) fragment).getView() == view;
}
@@ -1095,26 +1101,12 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU
if (position == 1) {
listFragment.setListAdapter(mConferenceAdapter);
listFragment.setContextMenu(R.menu.conference_context);
- listFragment.setOnListItemClickListener(new OnItemClickListener() {
-
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1,
- int position, long arg3) {
- openConversationForBookmark(position);
- }
- });
+ listFragment.setOnListItemClickListener((arg0, arg1, p, arg3) -> openConversationForBookmark(p));
} else {
listFragment.setListAdapter(mContactsAdapter);
listFragment.setContextMenu(R.menu.contact_context);
- listFragment.setOnListItemClickListener(new OnItemClickListener() {
-
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1,
- int position, long arg3) {
- openConversationForContact(position);
- }
- });
+ listFragment.setOnListItemClickListener((arg0, arg1, p, arg3) -> openConversationForContact(p));
}
fragments[position] = listFragment;
}
diff --git a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java
index 853b1b2a4..c36f0fcbc 100644
--- a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java
@@ -1,18 +1,16 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
import android.content.Intent;
+import android.databinding.DataBindingUtil;
import android.os.Bundle;
+import android.support.v7.app.ActionBar;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.Button;
import android.widget.CompoundButton;
-import android.widget.LinearLayout;
-import android.widget.TextView;
import android.widget.Toast;
import org.whispersystems.libsignal.IdentityKey;
@@ -29,6 +27,8 @@ import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.crypto.axolotl.AxolotlService;
import de.pixart.messenger.crypto.axolotl.FingerprintStatus;
+import de.pixart.messenger.databinding.ActivityTrustKeysBinding;
+import de.pixart.messenger.databinding.KeysCardBinding;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Conversation;
import de.pixart.messenger.utils.CryptoHelper;
@@ -43,21 +43,13 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
private Account mAccount;
private Conversation mConversation;
- private TextView keyErrorMessage;
- private LinearLayout keyErrorMessageCard;
- private TextView ownKeysTitle;
- private LinearLayout ownKeys;
- private LinearLayout ownKeysCard;
- private LinearLayout foreignKeys;
- private Button mSaveButton;
- private Button mCancelButton;
private AtomicBoolean mUseCameraHintShown = new AtomicBoolean(false);
private AxolotlService.FetchStatus lastFetchReport = AxolotlService.FetchStatus.SUCCESS;
private final Map<String, Boolean> ownKeysToTrust = new HashMap<>();
- private final Map<Jid, Map<String, Boolean>> foreignKeysToTrust = new HashMap<>();
+ private final Map<Jid,Map<String, Boolean>> foreignKeysToTrust = new HashMap<>();
private final OnClickListener mSaveButtonListener = new OnClickListener() {
@Override
@@ -74,9 +66,8 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
finish();
}
};
-
- private XmppUri mPendingFingerprintVerificationUri = null;
private Toast mUseCameraHintToast = null;
+ private ActivityTrustKeysBinding binding;
@Override
protected void refreshUiReal() {
@@ -87,9 +78,9 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_trust_keys);
+ this.binding = DataBindingUtil.setContentView(this,R.layout.activity_trust_keys);
this.contactJids = new ArrayList<>();
- for (String jid : getIntent().getStringArrayExtra("contacts")) {
+ for(String jid : getIntent().getStringArrayExtra("contacts")) {
try {
this.contactJids.add(Jid.fromString(jid));
} catch (InvalidJidException e) {
@@ -97,25 +88,17 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
}
- keyErrorMessageCard = findViewById(R.id.key_error_message_card);
- keyErrorMessage = findViewById(R.id.key_error_message);
- ownKeysTitle = findViewById(R.id.own_keys_title);
- ownKeys = findViewById(R.id.own_keys_details);
- ownKeysCard = findViewById(R.id.own_keys_card);
- foreignKeys = findViewById(R.id.foreign_keys);
- mCancelButton = findViewById(R.id.cancel_button);
- mCancelButton.setOnClickListener(mCancelButtonListener);
- mSaveButton = findViewById(R.id.save_button);
- mSaveButton.setOnClickListener(mSaveButtonListener);
-
-
- if (getActionBar() != null) {
- getActionBar().setHomeButtonEnabled(true);
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ binding.cancelButton.setOnClickListener(mCancelButtonListener);
+ binding.saveButton.setOnClickListener(mSaveButtonListener);
+
+
+ if (getSupportActionBar() != null) {
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState != null) {
- mUseCameraHintShown.set(savedInstanceState.getBoolean("camera_hint_shown", false));
+ mUseCameraHintShown.set(savedInstanceState.getBoolean("camera_hint_shown",false));
}
}
@@ -135,7 +118,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
private void showCameraToast() {
mUseCameraHintToast = Toast.makeText(this,R.string.use_camera_icon_to_scan_barcode,Toast.LENGTH_LONG);
- ActionBar actionBar = getActionBar();
+ ActionBar actionBar = getSupportActionBar();
mUseCameraHintToast.setGravity(Gravity.TOP | Gravity.END, 0 ,actionBar == null ? 0 : actionBar.getHeight());
mUseCameraHintToast.show();
}
@@ -187,13 +170,13 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
private void populateView() {
setTitle(getString(R.string.trust_omemo_fingerprints));
- ownKeys.removeAllViews();
- foreignKeys.removeAllViews();
+ binding.ownKeysDetails.removeAllViews();
+ binding.foreignKeys.removeAllViews();
boolean hasOwnKeys = false;
boolean hasForeignKeys = false;
- for (final String fingerprint : ownKeysToTrust.keySet()) {
+ for(final String fingerprint : ownKeysToTrust.keySet()) {
hasOwnKeys = true;
- addFingerprintRowWithListeners(ownKeys, mAccount, fingerprint, false,
+ addFingerprintRowWithListeners(binding.ownKeysDetails, mAccount, fingerprint, false,
FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint)), false, false,
new CompoundButton.OnCheckedChangeListener() {
@Override
@@ -208,84 +191,74 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
synchronized (this.foreignKeysToTrust) {
for (Map.Entry<Jid, Map<String, Boolean>> entry : foreignKeysToTrust.entrySet()) {
hasForeignKeys = true;
- final LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.keys_card, foreignKeys, false);
+ KeysCardBinding keysCardBinding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.keys_card, binding.foreignKeys,false);
+ //final LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.keys_card, foreignKeys, false);
final Jid jid = entry.getKey();
- final TextView header = layout.findViewById(R.id.foreign_keys_title);
- final LinearLayout keysContainer = layout.findViewById(R.id.foreign_keys_details);
- final TextView informNoKeys = layout.findViewById(R.id.no_keys_to_accept);
- header.setText(jid.toString());
- header.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- switchToContactDetails(mAccount.getRoster().getContact(jid));
- }
- });
+ keysCardBinding.foreignKeysTitle.setText(jid.toString());
+ keysCardBinding.foreignKeysTitle.setOnClickListener(v -> switchToContactDetails(mAccount.getRoster().getContact(jid)));
final Map<String, Boolean> fingerprints = entry.getValue();
for (final String fingerprint : fingerprints.keySet()) {
- addFingerprintRowWithListeners(keysContainer, mAccount, fingerprint, false,
+ addFingerprintRowWithListeners(keysCardBinding.foreignKeysDetails, mAccount, fingerprint, false,
FingerprintStatus.createActive(fingerprints.get(fingerprint)), false, false,
- new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- fingerprints.put(fingerprint, isChecked);
- lockOrUnlockAsNeeded();
- }
+ (buttonView, isChecked) -> {
+ fingerprints.put(fingerprint, isChecked);
+ lockOrUnlockAsNeeded();
}
);
}
if (fingerprints.size() == 0) {
- informNoKeys.setVisibility(View.VISIBLE);
+ keysCardBinding.noKeysToAccept.setVisibility(View.VISIBLE);
if (hasNoOtherTrustedKeys(jid)) {
if (!mAccount.getRoster().getContact(jid).mutualPresenceSubscription()) {
- informNoKeys.setText(R.string.error_no_keys_to_trust_presence);
+ keysCardBinding.noKeysToAccept.setText(R.string.error_no_keys_to_trust_presence);
} else {
- informNoKeys.setText(R.string.error_no_keys_to_trust_server_error);
+ keysCardBinding.noKeysToAccept.setText(R.string.error_no_keys_to_trust_server_error);
}
} else {
- informNoKeys.setText(getString(R.string.no_keys_just_confirm, mAccount.getRoster().getContact(jid).getDisplayName()));
+ keysCardBinding.noKeysToAccept.setText(getString(R.string.no_keys_just_confirm, mAccount.getRoster().getContact(jid).getDisplayName()));
}
} else {
- informNoKeys.setVisibility(View.GONE);
+ keysCardBinding.noKeysToAccept.setVisibility(View.GONE);
}
- foreignKeys.addView(layout);
+ binding.foreignKeys.addView(keysCardBinding.foreignKeysCard);
}
}
- if ((hasOwnKeys || foreignActuallyHasKeys()) && mUseCameraHintShown.compareAndSet(false, true)) {
+ if ((hasOwnKeys || foreignActuallyHasKeys()) && mUseCameraHintShown.compareAndSet(false,true)) {
showCameraToast();
}
- ownKeysTitle.setText(mAccount.getJid().toBareJid().toString());
- ownKeysCard.setVisibility(hasOwnKeys ? View.VISIBLE : View.GONE);
- foreignKeys.setVisibility(hasForeignKeys ? View.VISIBLE : View.GONE);
- if (hasPendingKeyFetches()) {
+ binding.ownKeysTitle.setText(mAccount.getJid().toBareJid().toString());
+ binding.ownKeysCard.setVisibility(hasOwnKeys ? View.VISIBLE : View.GONE);
+ binding.foreignKeys.setVisibility(hasForeignKeys ? View.VISIBLE : View.GONE);
+ if(hasPendingKeyFetches()) {
setFetching();
lock();
} else {
if (!hasForeignKeys && hasNoOtherTrustedKeys()) {
- keyErrorMessageCard.setVisibility(View.VISIBLE);
+ binding.keyErrorMessageCard.setVisibility(View.VISIBLE);
if (lastFetchReport == AxolotlService.FetchStatus.ERROR
|| mAccount.getAxolotlService().fetchMapHasErrors(contactJids)) {
if (anyWithoutMutualPresenceSubscription(contactJids)) {
- keyErrorMessage.setText(R.string.error_no_keys_to_trust_presence);
+ binding.keyErrorMessage.setText(R.string.error_no_keys_to_trust_presence);
} else {
- keyErrorMessage.setText(R.string.error_no_keys_to_trust_server_error);
+ binding.keyErrorMessage.setText(R.string.error_no_keys_to_trust_server_error);
}
} else {
- keyErrorMessage.setText(R.string.error_no_keys_to_trust);
+ binding.keyErrorMessage.setText(R.string.error_no_keys_to_trust);
}
- ownKeys.removeAllViews();
- ownKeysCard.setVisibility(View.GONE);
- foreignKeys.removeAllViews();
- foreignKeys.setVisibility(View.GONE);
+ binding.ownKeysDetails.removeAllViews();
+ binding.ownKeysCard.setVisibility(View.GONE);
+ binding.foreignKeys.removeAllViews();
+ binding.foreignKeys.setVisibility(View.GONE);
}
lockOrUnlockAsNeeded();
setDone();
}
}
- private boolean anyWithoutMutualPresenceSubscription(List<Jid> contactJids) {
- for (Jid jid : contactJids) {
+ private boolean anyWithoutMutualPresenceSubscription(List<Jid> contactJids){
+ for(Jid jid : contactJids) {
if (!mAccount.getRoster().getContact(jid).mutualPresenceSubscription()) {
return true;
}
@@ -309,9 +282,9 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
ownKeysToTrust.clear();
AxolotlService service = this.mAccount.getAxolotlService();
Set<IdentityKey> ownKeysSet = service.getKeysWithTrust(FingerprintStatus.createActiveUndecided());
- for (final IdentityKey identityKey : ownKeysSet) {
+ for(final IdentityKey identityKey : ownKeysSet) {
final String fingerprint = CryptoHelper.bytesToHex(identityKey.getPublicKey().serialize());
- if (!ownKeysToTrust.containsKey(fingerprint)) {
+ if(!ownKeysToTrust.containsKey(fingerprint)) {
ownKeysToTrust.put(fingerprint, false);
}
}
@@ -380,7 +353,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
switch (report) {
case ERROR:
- Toast.makeText(TrustKeysActivity.this, R.string.error_fetching_omemo_key, Toast.LENGTH_SHORT).show();
+ Toast.makeText(TrustKeysActivity.this,R.string.error_fetching_omemo_key,Toast.LENGTH_SHORT).show();
break;
case SUCCESS_TRUSTED:
Toast.makeText(TrustKeysActivity.this,R.string.blindly_trusted_omemo_keys,Toast.LENGTH_LONG).show();
@@ -416,7 +389,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
private void commitTrusts() {
- for (final String fingerprint : ownKeysToTrust.keySet()) {
+ for(final String fingerprint :ownKeysToTrust.keySet()) {
mAccount.getAxolotlService().setFingerprintTrust(
fingerprint,
FingerprintStatus.createActive(ownKeysToTrust.get(fingerprint)));
@@ -443,13 +416,13 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
private void unlock() {
- mSaveButton.setEnabled(true);
- mSaveButton.setTextColor(getPrimaryTextColor());
+ binding.saveButton.setEnabled(true);
+ binding.saveButton.setTextColor(getPrimaryTextColor());
}
private void lock() {
- mSaveButton.setEnabled(false);
- mSaveButton.setTextColor(getSecondaryTextColor());
+ binding.saveButton.setEnabled(false);
+ binding.saveButton.setTextColor(getSecondaryTextColor());
}
private void lockOrUnlockAsNeeded() {
@@ -467,10 +440,10 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
}
private void setDone() {
- mSaveButton.setText(getString(R.string.done));
+ binding.saveButton.setText(getString(R.string.done));
}
private void setFetching() {
- mSaveButton.setText(getString(R.string.fetching_keys));
+ binding.saveButton.setText(getString(R.string.fetching_keys));
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java b/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java
index 8a23741ef..f62454510 100644
--- a/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/UpdaterActivity.java
@@ -1,7 +1,7 @@
package de.pixart.messenger.ui;
import android.Manifest;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
diff --git a/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java b/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java
index 262be5bb0..09d4d26ac 100644
--- a/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/UriHandlerActivity.java
@@ -1,8 +1,8 @@
package de.pixart.messenger.ui;
-import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
+import android.support.v7.app.AppCompatActivity;
import java.util.Arrays;
import java.util.List;
@@ -13,7 +13,7 @@ import de.pixart.messenger.utils.zxing.IntentIntegrator;
import de.pixart.messenger.utils.zxing.IntentResult;
import de.pixart.messenger.xmpp.jid.Jid;
-public class UriHandlerActivity extends Activity {
+public class UriHandlerActivity extends AppCompatActivity {
public static final String ACTION_SCAN_QR_CODE = "scan_qr_code";
@Override
diff --git a/src/main/java/de/pixart/messenger/ui/VerifyOTRActivity.java b/src/main/java/de/pixart/messenger/ui/VerifyOTRActivity.java
index a64f39a03..ea9bcc5a8 100644
--- a/src/main/java/de/pixart/messenger/ui/VerifyOTRActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/VerifyOTRActivity.java
@@ -1,10 +1,10 @@
package de.pixart.messenger.ui;
-import android.app.ActionBar;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
+import android.support.v7.app.ActionBar;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
@@ -251,7 +251,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer
protected void updateView() {
if (this.mConversation != null && this.mConversation.hasValidOtrSession()) {
- final ActionBar actionBar = getActionBar();
+ final ActionBar actionBar = getSupportActionBar();
this.mVerificationExplain.setText(R.string.no_otr_session_found);
invalidateOptionsMenu();
switch (this.mode) {
diff --git a/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java b/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java
index 0e84d1d64..0c02183c6 100644
--- a/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/WelcomeActivity.java
@@ -1,9 +1,7 @@
package de.pixart.messenger.ui;
import android.Manifest;
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -13,6 +11,8 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Build;
import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -79,7 +79,7 @@ public class WelcomeActivity extends XmppActivity {
}
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome);
- final ActionBar ab = getActionBar();
+ final ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayShowHomeEnabled(false);
ab.setDisplayHomeAsUpEnabled(false);
@@ -336,7 +336,7 @@ public class WelcomeActivity extends XmppActivity {
}
}
- public static void launch(Activity activity) {
+ public static void launch(AppCompatActivity activity) {
Intent intent = new Intent(activity, WelcomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.startActivity(intent);
diff --git a/src/main/java/de/pixart/messenger/ui/XmppActivity.java b/src/main/java/de/pixart/messenger/ui/XmppActivity.java
index 79f528f93..7e0df64ca 100644
--- a/src/main/java/de/pixart/messenger/ui/XmppActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/XmppActivity.java
@@ -3,9 +3,7 @@ package de.pixart.messenger.ui;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
@@ -39,6 +37,8 @@ import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -83,7 +83,7 @@ import de.pixart.messenger.xmpp.OnUpdateBlocklist;
import de.pixart.messenger.xmpp.jid.InvalidJidException;
import de.pixart.messenger.xmpp.jid.Jid;
-public abstract class XmppActivity extends Activity {
+public abstract class XmppActivity extends AppCompatActivity {
protected static final int REQUEST_ANNOUNCE_PGP = 0x0101;
protected static final int REQUEST_INVITE_TO_CONVERSATION = 0x0102;
@@ -276,7 +276,7 @@ public abstract class XmppActivity extends Activity {
}
public void showInstallPgpDialog() {
- Builder builder = new AlertDialog.Builder(this);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.openkeychain_required));
builder.setIconAttribute(android.R.attr.alertDialogIcon);
builder.setMessage(getText(R.string.openkeychain_required_long));
@@ -437,7 +437,7 @@ public abstract class XmppActivity extends Activity {
setTheme(this.mTheme);
this.mUsingEnterKey = usingEnterKey();
mUseSubject = getPreferences().getBoolean("use_subject", getResources().getBoolean(R.bool.use_subject));
- final ActionBar ab = getActionBar();
+ final ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
@@ -565,8 +565,7 @@ public abstract class XmppActivity extends Activity {
}
protected void inviteToConversation(Conversation conversation) {
- Intent intent = new Intent(getApplicationContext(),
- ChooseContactActivity.class);
+ Intent intent = new Intent(this, ChooseContactActivity.class);
List<String> contacts = new ArrayList<>();
if (conversation.getMode() == Conversation.MODE_MULTI) {
for (MucOptions.User user : conversation.getMucOptions().getUsers(false)) {
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java
index 451e326e6..792d365ef 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java
@@ -134,7 +134,8 @@ public class AccountAdapter extends ArrayAdapter<Account> {
@Override
protected Bitmap doInBackground(Account... params) {
- return activity.avatarService().get(params[0], activity.getPixel(56), isCancelled());
+ this.account = params[0];
+ return activity.avatarService().get(this.account, activity.getPixel(56), isCancelled());
}
@Override
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java
index 162455732..3c2de008e 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java
@@ -357,7 +357,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
@Override
protected Bitmap doInBackground(Conversation... params) {
- return activity.avatarService().get(params[0], activity.getPixel(56));
+ this.conversation = params[0];
+ return activity.avatarService().get(this.conversation, activity.getPixel(56), isCancelled());
}
@Override
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java
index 8b4af00d8..2df1e5b0f 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java
@@ -1,8 +1,8 @@
package de.pixart.messenger.ui.adapter;
-import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
+import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.concurrent.RejectedExecutionException;
import de.pixart.messenger.R;
+import de.pixart.messenger.databinding.ContactBinding;
import de.pixart.messenger.entities.ListItem;
import de.pixart.messenger.ui.SettingsActivity;
import de.pixart.messenger.ui.XmppActivity;
@@ -60,15 +61,17 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
@Override
public View getView(int position, View view, ViewGroup parent) {
- LayoutInflater inflater = (LayoutInflater) getContext()
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ LayoutInflater inflater = activity.getLayoutInflater();
ListItem item = getItem(position);
+ ViewHolder viewHolder;
if (view == null) {
- view = inflater.inflate(R.layout.contact, parent, false);
+ ContactBinding binding = DataBindingUtil.inflate(inflater, R.layout.contact, parent, false);
+ viewHolder = ViewHolder.get(binding);
+ view = binding.getRoot();
+ } else {
+ viewHolder = (ViewHolder) view.getTag();
}
- ViewHolder viewHolder = ViewHolder.get(view);
-
List<ListItem.Tag> tags = item.getTags(activity);
if (tags.size() == 0 || !this.showDynamicTags) {
@@ -137,7 +140,8 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
@Override
protected Bitmap doInBackground(ListItem... params) {
- return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled());
+ this.item = params[0];
+ return activity.avatarService().get(this.item, activity.getPixel(56), isCancelled());
}
@Override
@@ -221,17 +225,13 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
private ViewHolder() {
}
- public static ViewHolder get(View layout) {
- ViewHolder viewHolder = (ViewHolder) layout.getTag();
- if (viewHolder == null) {
- viewHolder = new ViewHolder();
-
- viewHolder.name = layout.findViewById(R.id.contact_display_name);
- viewHolder.jid = layout.findViewById(R.id.contact_jid);
- viewHolder.avatar = layout.findViewById(R.id.contact_photo);
- viewHolder.tags = layout.findViewById(R.id.tags);
- layout.setTag(viewHolder);
- }
+ public static ViewHolder get(ContactBinding binding) {
+ ViewHolder viewHolder = new ViewHolder();
+ viewHolder.name = binding.contactDisplayName;
+ viewHolder.jid = binding.contactJid;
+ viewHolder.avatar = binding.contactPhoto;
+ viewHolder.tags = binding.tags;
+ binding.getRoot().setTag(viewHolder);
return viewHolder;
}
}
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
index ca6b02284..181bce607 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
@@ -1223,7 +1223,8 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
@Override
protected Bitmap doInBackground(Message... params) {
- return activity.avatarService().get(params[0], size, isCancelled());
+ this.message = params[0];
+ return activity.avatarService().get(this.message, size, isCancelled());
}
@Override
diff --git a/src/main/java/de/pixart/messenger/ui/widget/DisabledActionModeCallback.java b/src/main/java/de/pixart/messenger/ui/widget/DisabledActionModeCallback.java
new file mode 100644
index 000000000..5acf3a666
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/ui/widget/DisabledActionModeCallback.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.pixart.messenger.ui.widget;
+
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class DisabledActionModeCallback implements ActionMode.Callback {
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+
+ }
+} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java b/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java
index 3b9b50f1c..bb1f0536c 100644
--- a/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java
+++ b/src/main/java/de/pixart/messenger/ui/widget/EditMessage.java
@@ -5,7 +5,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
-import android.support.text.emoji.widget.EmojiEditText;
+import android.support.text.emoji.widget.EmojiAppCompatEditText;
import android.support.v13.view.inputmethod.EditorInfoCompat;
import android.support.v13.view.inputmethod.InputConnectionCompat;
import android.support.v13.view.inputmethod.InputContentInfoCompat;
@@ -19,15 +19,9 @@ import android.view.inputmethod.InputConnection;
import de.pixart.messenger.Config;
-public class EditMessage extends EmojiEditText {
+public class EditMessage extends EmojiAppCompatEditText {
- private static final InputFilter SPAN_FILTER = new InputFilter() {
-
- @Override
- public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
- return source instanceof Spanned ? source.toString() : source;
- }
- };
+ private static final InputFilter SPAN_FILTER = (source, start, end, dest, dstart, dend) -> source instanceof Spanned ? source.toString() : source;
protected Handler mTypingHandler = new Handler();
protected KeyboardListener keyboardListener;
diff --git a/src/main/java/de/pixart/messenger/ui/widget/Switch.java b/src/main/java/de/pixart/messenger/ui/widget/Switch.java
deleted file mode 100644
index 40d8f4c99..000000000
--- a/src/main/java/de/pixart/messenger/ui/widget/Switch.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package de.pixart.messenger.ui.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-
-import com.kyleduo.switchbutton.SwitchButton;
-
-public class Switch extends SwitchButton {
-
- private int mTouchSlop;
- private int mClickTimeout;
- private float mStartX;
- private float mStartY;
- private OnClickListener mOnClickListener;
-
- public Switch(Context context) {
- super(context);
- mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
- }
-
- public Switch(Context context, AttributeSet attrs) {
- super(context, attrs);
- mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
- }
-
- public Switch(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
- mClickTimeout = ViewConfiguration.getPressedStateDuration() + ViewConfiguration.getTapTimeout();
- }
-
- @Override
- public void setOnClickListener(OnClickListener onClickListener) {
- this.mOnClickListener = onClickListener;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!isEnabled()) {
- float deltaX = event.getX() - mStartX;
- float deltaY = event.getY() - mStartY;
- int action = event.getAction();
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mStartX = event.getX();
- mStartY = event.getY();
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- float time = event.getEventTime() - event.getDownTime();
- if (deltaX < mTouchSlop && deltaY < mTouchSlop && time < mClickTimeout) {
- if (mOnClickListener != null) {
- this.mOnClickListener.onClick(this);
- }
- }
- break;
- default:
- break;
- }
- return true;
- }
- return super.onTouchEvent(event);
- }
-}
diff --git a/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java b/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java
index efec5098b..9aacef24f 100644
--- a/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/ExceptionHelper.java
@@ -1,6 +1,6 @@
package de.pixart.messenger.utils;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
diff --git a/src/main/java/de/pixart/messenger/utils/UIHelper.java b/src/main/java/de/pixart/messenger/utils/UIHelper.java
index 451ec3aec..08e1d7dad 100644
--- a/src/main/java/de/pixart/messenger/utils/UIHelper.java
+++ b/src/main/java/de/pixart/messenger/utils/UIHelper.java
@@ -557,19 +557,4 @@ public class UIHelper {
return type;
}
}
-
- public static boolean showIconsInPopup(PopupMenu attachFilePopup) {
- try {
- Field field = attachFilePopup.getClass().getDeclaredField("mPopup");
- field.setAccessible(true);
- Object menuPopupHelper = field.get(attachFilePopup);
- Class<?> cls = Class.forName("com.android.internal.view.menu.MenuPopupHelper");
- Method method = cls.getDeclaredMethod("setForceShowIcon", new Class[]{boolean.class});
- method.setAccessible(true);
- method.invoke(menuPopupHelper, new Object[]{true});
- return true;
- } catch (Exception e) {
- return false;
- }
- }
}
diff --git a/src/main/java/de/pixart/messenger/utils/zxing/IntentIntegrator.java b/src/main/java/de/pixart/messenger/utils/zxing/IntentIntegrator.java
index dc5ba8ace..ebb92ae4c 100644
--- a/src/main/java/de/pixart/messenger/utils/zxing/IntentIntegrator.java
+++ b/src/main/java/de/pixart/messenger/utils/zxing/IntentIntegrator.java
@@ -17,7 +17,7 @@
package de.pixart.messenger.utils.zxing;
import android.app.Activity;
-import android.app.AlertDialog;
+import android.support.v7.app.AlertDialog;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
index 6bd4904bf..1025c5f1d 100644
--- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
+++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java
@@ -50,8 +50,8 @@ import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
-import de.duenndns.ssl.DomainHostnameVerifier;
-import de.duenndns.ssl.MemorizingTrustManager;
+import de.pixart.messenger.crypto.DomainHostnameVerifier;
+import de.pixart.messenger.services.MemorizingTrustManager;
import de.pixart.messenger.Config;
import de.pixart.messenger.crypto.XmppDomainVerifier;
import de.pixart.messenger.crypto.axolotl.AxolotlService;