get rid of customizable resources

This commit is contained in:
Daniel Gultsch 2018-02-27 20:33:21 +01:00
parent fcbbb552f4
commit b393f54a03
8 changed files with 199 additions and 259 deletions

View file

@ -42,6 +42,7 @@ public class Account extends AbstractEntity {
public static final String PORT = "port";
public static final String STATUS = "status";
public static final String STATUS_MESSAGE = "status_message";
public static final String RESOURCE = "resource";
public static final String PINNED_MECHANISM_KEY = "pinned_mechanism";
@ -229,6 +230,7 @@ public class Account extends AbstractEntity {
protected String rosterVersion;
protected State status = State.OFFLINE;
protected final JSONObject keys;
protected String resource;
protected String avatar;
protected String displayName = null;
protected String hostname = null;
@ -238,7 +240,6 @@ public class Account extends AbstractEntity {
private PgpDecryptionService pgpDecryptionService = null;
private XmppConnection xmppConnection = null;
private long mEndGracePeriod = 0L;
private String otrFingerprint;
private final Roster roster = new Roster(this);
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
private final Collection<Jid> blocklist = new CopyOnWriteArraySet<>();
@ -256,9 +257,6 @@ public class Account extends AbstractEntity {
final Presence.Status status, String statusMessage) {
this.uuid = uuid;
this.jid = jid;
if (jid.isBareJid()) {
this.setResource("mobile");
}
this.password = password;
this.options = options;
this.rosterVersion = rosterVersion;
@ -280,8 +278,10 @@ public class Account extends AbstractEntity {
public static Account fromCursor(final Cursor cursor) {
Jid jid = null;
try {
jid = Jid.fromParts(cursor.getString(cursor.getColumnIndex(USERNAME)),
cursor.getString(cursor.getColumnIndex(SERVER)), "mobile");
jid = Jid.fromParts(
cursor.getString(cursor.getColumnIndex(USERNAME)),
cursor.getString(cursor.getColumnIndex(SERVER)),
cursor.getString(cursor.getColumnIndex(RESOURCE)));
} catch (final InvalidJidException ignored) {
}
return new Account(cursor.getString(cursor.getColumnIndex(UUID)),
@ -317,6 +317,7 @@ public class Account extends AbstractEntity {
}
public boolean setJid(final Jid next) {
final Jid previousFull = this.jid;
final Jid prev = this.jid != null ? this.jid.toBareJid() : null;
final boolean changed = prev == null || (next != null && !prev.equals(next.toBareJid()));
if (changed) {
@ -328,7 +329,7 @@ public class Account extends AbstractEntity {
}
}
this.jid = next;
return changed;
return next != null && next.equals(previousFull);
}
public Jid getServer() {
@ -483,6 +484,7 @@ public class Account extends AbstractEntity {
values.put(PORT, port);
values.put(STATUS, presenceStatus.toShowString());
values.put(STATUS_MESSAGE, presenceStatusMessage);
values.put(RESOURCE,jid.getResourcepart());
return values;
}

View file

@ -62,7 +62,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
private static DatabaseBackend instance = null;
private static final String DATABASE_NAME = "history";
private static final int DATABASE_VERSION = 39;
private static final int DATABASE_VERSION = 40;
private static String CREATE_CONTATCS_STATEMENT = "create table "
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
@ -184,6 +184,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
+ Account.AVATAR + " TEXT, "
+ Account.KEYS + " TEXT, "
+ Account.HOSTNAME + " TEXT, "
+ Account.RESOURCE + " TEXT,"
+ Account.PORT + " NUMBER DEFAULT 5222)");
db.execSQL("create table " + Conversation.TABLENAME + " ("
+ Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME
@ -305,6 +306,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.STATUS + " TEXT");
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.STATUS_MESSAGE + " TEXT");
}
if (oldVersion < 40 && newVersion >= 40) {
db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.RESOURCE + " TEXT");
}
/* Any migrations that alter the Account table need to happen BEFORE this migration, as it
* depends on account de-serialization.
*/

View file

@ -1125,17 +1125,6 @@ public class XmppConnectionService extends Service {
}
public XmppConnection createConnection(final Account account) {
final SharedPreferences sharedPref = getPreferences();
String resource;
try {
resource = sharedPref.getString("resource", getString(R.string.default_resource)).toLowerCase(Locale.ENGLISH);
if (resource.trim().isEmpty()) {
throw new Exception();
}
} catch (Exception e) {
resource = "conversations";
}
account.setResource(resource);
final XmppConnection connection = new XmppConnection(account, this);
connection.setOnMessagePacketReceivedListener(this.mMessageParser);
connection.setOnStatusChangedListener(this.statusListener);

View file

@ -1,5 +1,6 @@
package eu.siacs.conversations.ui;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.app.FragmentManager;
import android.content.DialogInterface;
@ -68,7 +69,7 @@ public class SettingsActivity extends XmppActivity implements
this.mTheme = findTheme();
setTheme(this.mTheme);
getWindow().getDecorView().setBackgroundColor(Color.get(this,R.attr.color_background_primary));
getWindow().getDecorView().setBackgroundColor(Color.get(this, R.attr.color_background_primary));
}
@ -81,15 +82,6 @@ public class SettingsActivity extends XmppActivity implements
public void onStart() {
super.onStart();
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource");
if (resources != null) {
ArrayList<CharSequence> entries = new ArrayList<>(Arrays.asList(resources.getEntries()));
if (!entries.contains(Build.MODEL)) {
entries.add(0, Build.MODEL);
resources.setEntries(entries.toArray(new CharSequence[entries.size()]));
resources.setEntryValues(entries.toArray(new CharSequence[entries.size()]));
}
}
if (Config.FORCE_ORBOT) {
PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options");
@ -281,37 +273,31 @@ public class SettingsActivity extends XmppActivity implements
}
}
final boolean[] checkedItems = new boolean[accounts.size()];
builder.setMultiChoiceItems(accounts.toArray(new CharSequence[accounts.size()]), checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checkedItems[which] = isChecked;
final AlertDialog alertDialog = (AlertDialog) dialog;
for (boolean item : checkedItems) {
if (item) {
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
return;
}
builder.setMultiChoiceItems(accounts.toArray(new CharSequence[accounts.size()]), checkedItems, (dialog, which, isChecked) -> {
checkedItems[which] = isChecked;
final AlertDialog alertDialog = (AlertDialog) dialog;
for (boolean item : checkedItems) {
if (item) {
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
return;
}
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
}
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
});
builder.setNegativeButton(R.string.cancel, null);
builder.setPositiveButton(R.string.delete_selected_keys, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
for (int i = 0; i < checkedItems.length; ++i) {
if (checkedItems[i]) {
try {
Jid jid = Jid.fromString(accounts.get(i).toString());
Account account = xmppConnectionService.findAccountByJid(jid);
if (account != null) {
account.getAxolotlService().regenerateKeys(true);
}
} catch (InvalidJidException e) {
//
builder.setPositiveButton(R.string.delete_selected_keys, (dialog, which) -> {
for (int i = 0; i < checkedItems.length; ++i) {
if (checkedItems[i]) {
try {
Jid jid = Jid.fromString(accounts.get(i).toString());
Account account = xmppConnectionService.findAccountByJid(jid);
if (account != null) {
account.getAxolotlService().regenerateKeys(true);
}
} catch (InvalidJidException e) {
//
}
}
}
});
@ -338,23 +324,7 @@ public class SettingsActivity extends XmppActivity implements
TREAT_VIBRATE_AS_SILENT,
MANUALLY_CHANGE_PRESENCE,
BROADCAST_LAST_ACTIVITY);
if (name.equals("resource")) {
String resource = preferences.getString("resource", "mobile")
.toLowerCase(Locale.US);
if (xmppConnectionServiceBound) {
for (Account account : xmppConnectionService.getAccounts()) {
if (account.setResource(resource)) {
if (account.isEnabled()) {
XmppConnection connection = account.getXmppConnection();
if (connection != null) {
connection.resetStreamId();
}
xmppConnectionService.reconnectAccountInBackground(account);
}
}
}
}
} else if (name.equals(KEEP_FOREGROUND_SERVICE)) {
if (name.equals(KEEP_FOREGROUND_SERVICE)) {
xmppConnectionService.toggleForegroundService();
} else if (resendPresence.contains(name)) {
if (xmppConnectionServiceBound) {
@ -383,7 +353,7 @@ public class SettingsActivity extends XmppActivity implements
}
@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_WRITE_LOGS) {
@ -399,12 +369,7 @@ public class SettingsActivity extends XmppActivity implements
}
private void displayToast(final String msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
runOnUiThread(() -> Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show());
}
private void reconnectAccounts() {

View file

@ -50,6 +50,7 @@ import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.DomainHostnameVerifier;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
@ -102,94 +103,6 @@ public class XmppConnection implements Runnable {
private static final int PACKET_IQ = 0;
private static final int PACKET_MESSAGE = 1;
private static final int PACKET_PRESENCE = 2;
protected final Account account;
private Socket socket;
private XmlReader tagReader;
private TagWriter tagWriter = new TagWriter();
private final Features features = new Features(this);
private boolean shouldAuthenticate = true;
private boolean inSmacksSession = false;
private boolean isBound = false;
private Element streamFeatures;
private final HashMap<Jid, ServiceDiscoveryResult> disco = new HashMap<>();
private String streamId = null;
private int smVersion = 3;
private final SparseArray<AbstractAcknowledgeableStanza> mStanzaQueue = new SparseArray<>();
private int stanzasReceived = 0;
private int stanzasSent = 0;
private long lastPacketReceived = 0;
private long lastPingSent = 0;
private long lastConnect = 0;
private long lastSessionStarted = 0;
private long lastDiscoStarted = 0;
private AtomicInteger mPendingServiceDiscoveries = new AtomicInteger(0);
private AtomicBoolean mWaitForDisco = new AtomicBoolean(true);
private AtomicBoolean mWaitingForSmCatchup = new AtomicBoolean(false);
private AtomicInteger mSmCatchupMessageCounter = new AtomicInteger(0);
private boolean mInteractive = false;
private int attempt = 0;
private final Hashtable<String, Pair<IqPacket, OnIqPacketReceived>> packetCallbacks = new Hashtable<>();
private OnPresencePacketReceived presenceListener = null;
private OnJinglePacketReceived jingleListener = null;
private OnIqPacketReceived unregisteredIqListener = null;
private OnMessagePacketReceived messageListener = null;
private OnStatusChanged statusListener = null;
private OnBindListener bindListener = null;
private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
private OnMessageAcknowledged acknowledgedListener = null;
private final XmppConnectionService mXmppConnectionService;
private SaslMechanism saslMechanism;
private URL redirectionUrl = null;
private String verifiedHostname = null;
private Thread mThread;
private CountDownLatch mStreamCountDownLatch;
private class MyKeyManager implements X509KeyManager {
@Override
public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
return account.getPrivateKeyAlias();
}
@Override
public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
return null;
}
@Override
public X509Certificate[] getCertificateChain(String alias) {
Log.d(Config.LOGTAG, "getting certificate chain");
try {
return KeyChain.getCertificateChain(mXmppConnectionService, alias);
} catch (Exception e) {
Log.d(Config.LOGTAG, e.getMessage());
return new X509Certificate[0];
}
}
@Override
public String[] getClientAliases(String s, Principal[] principals) {
final String alias = account.getPrivateKeyAlias();
return alias != null ? new String[]{alias} : new String[0];
}
@Override
public String[] getServerAliases(String s, Principal[] principals) {
return new String[0];
}
@Override
public PrivateKey getPrivateKey(String alias) {
try {
return KeyChain.getPrivateKey(mXmppConnectionService, alias);
} catch (Exception e) {
return null;
}
}
}
public final OnIqPacketReceived registrationResponseListener = new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
@ -217,6 +130,47 @@ public class XmppConnection implements Runnable {
}
}
};
protected final Account account;
private final Features features = new Features(this);
private final HashMap<Jid, ServiceDiscoveryResult> disco = new HashMap<>();
private final SparseArray<AbstractAcknowledgeableStanza> mStanzaQueue = new SparseArray<>();
private final Hashtable<String, Pair<IqPacket, OnIqPacketReceived>> packetCallbacks = new Hashtable<>();
private final ArrayList<OnAdvancedStreamFeaturesLoaded> advancedStreamFeaturesLoadedListeners = new ArrayList<>();
private final XmppConnectionService mXmppConnectionService;
private Socket socket;
private XmlReader tagReader;
private TagWriter tagWriter = new TagWriter();
private boolean shouldAuthenticate = true;
private boolean inSmacksSession = false;
private boolean isBound = false;
private Element streamFeatures;
private String streamId = null;
private int smVersion = 3;
private int stanzasReceived = 0;
private int stanzasSent = 0;
private long lastPacketReceived = 0;
private long lastPingSent = 0;
private long lastConnect = 0;
private long lastSessionStarted = 0;
private long lastDiscoStarted = 0;
private AtomicInteger mPendingServiceDiscoveries = new AtomicInteger(0);
private AtomicBoolean mWaitForDisco = new AtomicBoolean(true);
private AtomicBoolean mWaitingForSmCatchup = new AtomicBoolean(false);
private AtomicInteger mSmCatchupMessageCounter = new AtomicInteger(0);
private boolean mInteractive = false;
private int attempt = 0;
private OnPresencePacketReceived presenceListener = null;
private OnJinglePacketReceived jingleListener = null;
private OnIqPacketReceived unregisteredIqListener = null;
private OnMessagePacketReceived messageListener = null;
private OnStatusChanged statusListener = null;
private OnBindListener bindListener = null;
private OnMessageAcknowledged acknowledgedListener = null;
private SaslMechanism saslMechanism;
private URL redirectionUrl = null;
private String verifiedHostname = null;
private Thread mThread;
private CountDownLatch mStreamCountDownLatch;
public XmppConnection(final Account account, final XmppConnectionService service) {
this.account = account;
@ -479,19 +433,6 @@ public class XmppConnection implements Runnable {
return tag != null && tag.isStart("stream");
}
private static class TlsFactoryVerifier {
private final SSLSocketFactory factory;
private final DomainHostnameVerifier verifier;
public TlsFactoryVerifier(final SSLSocketFactory factory, final DomainHostnameVerifier verifier) throws IOException {
this.factory = factory;
this.verifier = verifier;
if (factory == null || verifier == null) {
throw new IOException("could not setup ssl");
}
}
}
private TlsFactoryVerifier getTlsFactoryVerifier() throws NoSuchAlgorithmException, KeyManagementException, IOException {
final SSLContext sc = SSLSocketHelper.getSSLContext();
MemorizingTrustManager trustManager = this.mXmppConnectionService.getMemorizingTrustManager();
@ -836,7 +777,6 @@ public class XmppConnection implements Runnable {
tagWriter.writeTag(startTLS);
}
private void switchOverToTls(final Tag currentTag) throws XmlPullParserException, IOException {
tagReader.readTag();
try {
@ -1069,55 +1009,52 @@ public class XmppConnection implements Runnable {
return;
}
clearIqCallbacks();
if (account.getJid().isBareJid()) {
account.setResource(this.createNewResource());
}
final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
final String resource = Config.USE_RANDOM_RESOURCE_ON_EVERY_BIND ? nextRandomId() : account.getResource();
iq.addChild("bind", Namespace.BIND).addChild("resource").setContent(resource);
this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(final Account account, final IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
return;
}
final Element bind = packet.findChild("bind");
if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) {
isBound = true;
final Element jid = bind.findChild("jid");
if (jid != null && jid.getContent() != null) {
try {
Jid assignedJid = Jid.fromString(jid.getContent());
if (!account.getJid().getDomainpart().equals(assignedJid.getDomainpart())) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server tried to re-assign domain to "+assignedJid.getDomainpart());
throw new StateChangingError(Account.State.BIND_FAILURE);
}
if (account.setJid(assignedJid)) {
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": bare jid changed during bind. updating database");
mXmppConnectionService.databaseBackend.updateAccount(account);
}
if (streamFeatures.hasChild("session")
&& !streamFeatures.findChild("session").hasChild("optional")) {
sendStartSession();
} else {
sendPostBindInitialization();
}
return;
} catch (final InvalidJidException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server reported invalid jid (" + jid.getContent() + ") on bind");
this.sendUnmodifiedIqPacket(iq, (account, packet) -> {
if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
return;
}
final Element bind = packet.findChild("bind");
if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) {
isBound = true;
final Element jid = bind.findChild("jid");
if (jid != null && jid.getContent() != null) {
try {
Jid assignedJid = Jid.fromString(jid.getContent());
if (!account.getJid().getDomainpart().equals(assignedJid.getDomainpart())) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server tried to re-assign domain to "+assignedJid.getDomainpart());
throw new StateChangingError(Account.State.BIND_FAILURE);
}
} else {
Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure. (no jid)");
if (account.setJid(assignedJid)) {
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": jid changed during bind. updating database");
mXmppConnectionService.databaseBackend.updateAccount(account);
}
if (streamFeatures.hasChild("session")
&& !streamFeatures.findChild("session").hasChild("optional")) {
sendStartSession();
} else {
sendPostBindInitialization();
}
return;
} catch (final InvalidJidException e) {
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server reported invalid jid (" + jid.getContent() + ") on bind");
}
} else {
Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString());
Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure. (no jid)");
}
final Element error = packet.findChild("error");
final String resource = account.getResource().split("\\.")[0];
if (packet.getType() == IqPacket.TYPE.ERROR && error != null && error.hasChild("conflict")) {
account.setResource(resource + "." + nextRandomId());
} else {
account.setResource(resource);
}
throw new StateChangingError(Account.State.BIND_FAILURE);
} else {
Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString());
}
final Element error = packet.findChild("error");
if (packet.getType() == IqPacket.TYPE.ERROR && error != null && error.hasChild("conflict")) {
account.setResource(createNewResource());
}
throw new StateChangingError(Account.State.BIND_FAILURE);
},true);
}
@ -1337,18 +1274,14 @@ public class XmppConnection implements Runnable {
});
}
private void processStreamError(final Tag currentTag)
throws XmlPullParserException, IOException {
private void processStreamError(final Tag currentTag) throws XmlPullParserException, IOException {
final Element streamError = tagReader.readElement(currentTag);
if (streamError == null) {
return;
}
if (streamError.hasChild("conflict")) {
final String resource = account.getResource().split("\\.")[0];
account.setResource(resource + "." + nextRandomId());
Log.d(Config.LOGTAG,
account.getJid().toBareJid() + ": switching resource due to conflict ("
+ account.getResource() + ")");
account.setResource(createNewResource());
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": switching resource due to conflict (" + account.getResource() + ")");
throw new IOException();
} else if (streamError.hasChild("host-unknown")) {
throw new StateChangingException(Account.State.HOST_UNKNOWN);
@ -1370,8 +1303,16 @@ public class XmppConnection implements Runnable {
tagWriter.writeTag(stream);
}
private String createNewResource() {
return mXmppConnectionService.getString(R.string.app_name)+'.'+nextRandomId(true);
}
private String nextRandomId() {
return CryptoHelper.random(10, mXmppConnectionService.getRNG());
return nextRandomId(false);
}
private String nextRandomId(boolean s) {
return CryptoHelper.random(s ? 3 : 9, mXmppConnectionService.getRNG());
}
public String sendIqPacket(final IqPacket packet, final OnIqPacketReceived callback) {
@ -1662,6 +1603,75 @@ public class XmppConnection implements Runnable {
return Identity.UNKNOWN;
}
private IqGenerator getIqGenerator() {
return mXmppConnectionService.getIqGenerator();
}
public enum Identity {
FACEBOOK,
SLACK,
EJABBERD,
PROSODY,
NIMBUZZ,
UNKNOWN
}
private static class TlsFactoryVerifier {
private final SSLSocketFactory factory;
private final DomainHostnameVerifier verifier;
public TlsFactoryVerifier(final SSLSocketFactory factory, final DomainHostnameVerifier verifier) throws IOException {
this.factory = factory;
this.verifier = verifier;
if (factory == null || verifier == null) {
throw new IOException("could not setup ssl");
}
}
}
private class MyKeyManager implements X509KeyManager {
@Override
public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
return account.getPrivateKeyAlias();
}
@Override
public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
return null;
}
@Override
public X509Certificate[] getCertificateChain(String alias) {
Log.d(Config.LOGTAG, "getting certificate chain");
try {
return KeyChain.getCertificateChain(mXmppConnectionService, alias);
} catch (Exception e) {
Log.d(Config.LOGTAG, e.getMessage());
return new X509Certificate[0];
}
}
@Override
public String[] getClientAliases(String s, Principal[] principals) {
final String alias = account.getPrivateKeyAlias();
return alias != null ? new String[]{alias} : new String[0];
}
@Override
public String[] getServerAliases(String s, Principal[] principals) {
return new String[0];
}
@Override
public PrivateKey getPrivateKey(String alias) {
try {
return KeyChain.getPrivateKey(mXmppConnectionService, alias);
} catch (Exception e) {
return null;
}
}
}
private class StateChangingError extends Error {
private final Account.State state;
@ -1678,15 +1688,6 @@ public class XmppConnection implements Runnable {
}
}
public enum Identity {
FACEBOOK,
SLACK,
EJABBERD,
PROSODY,
NIMBUZZ,
UNKNOWN
}
public class Features {
XmppConnection connection;
private boolean carbonsEnabled = false;
@ -1818,8 +1819,4 @@ public class XmppConnection implements Runnable {
return hasDiscoFeature(account.getJid().toBareJid(), Namespace.STANZA_IDS);
}
}
private IqGenerator getIqGenerator() {
return mXmppConnectionService.getIqGenerator();
}
}

View file

@ -1,13 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="resources">
<item>Mobile</item>
<item>Phone</item>
<item>Tablet</item>
<item>@string/app_name</item>
<item>Android</item>
</string-array>
<string-array name="themes">
<item>@string/pref_theme_light</item>
<item>@string/pref_theme_dark</item>

View file

@ -100,8 +100,6 @@
<string name="no_pgp_keys">No OpenPGP Keys found</string>
<string name="contacts_have_no_pgp_keys">Conversations is unable to encrypt your messages because your contacts are not announcing their public key.\n\n<small>Please ask your contacts to setup OpenPGP.</small></string>
<string name="pref_general">General</string>
<string name="pref_xmpp_resource">XMPP resource</string>
<string name="pref_xmpp_resource_summary">The name this client identifies itself with</string>
<string name="pref_accept_files">Accept files</string>
<string name="pref_accept_files_summary">Automatically accept files smaller than…</string>
<string name="pref_attachments">Attachments</string>

View file

@ -9,14 +9,6 @@
android:key="grant_new_contacts"
android:summary="@string/pref_grant_presence_updates_summary"
android:title="@string/pref_grant_presence_updates"/>
<ListPreference
android:defaultValue="@string/default_resource"
android:entries="@array/resources"
android:entryValues="@array/resources"
android:key="resource"
android:summary="@string/pref_xmpp_resource_summary"
android:title="@string/pref_xmpp_resource"/>
<PreferenceScreen
android:key="huawei"
android:title="@string/huawei_protected_apps"