get rid of customizable resources
This commit is contained in:
parent
fcbbb552f4
commit
b393f54a03
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue