diff --git a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java index a894cab67..9ff492578 100644 --- a/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/PhoneHelper.java @@ -12,27 +12,51 @@ import android.provider.Settings; public class PhoneHelper { - @SuppressLint("HardwareIds") - public static String getAndroidId(Context context) { - return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); - } + @SuppressLint("HardwareIds") + public static String getAndroidId(Context context) { + return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); + } - public static Uri getProfilePictureUri(Context context) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { - return null; - } - final String[] projection = new String[]{Profile._ID, Profile.PHOTO_URI}; - final Cursor cursor; - try { - cursor = context.getContentResolver().query(Profile.CONTENT_URI, projection, null, null, null); - } catch (Throwable e) { - return null; - } - if (cursor == null) { - return null; - } - final String uri = cursor.moveToFirst() ? cursor.getString(1) : null; - cursor.close(); - return uri == null ? null : Uri.parse(uri); - } + public static Uri getProfilePictureUri(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) + != PackageManager.PERMISSION_GRANTED) { + return null; + } + final String[] projection = new String[] {Profile._ID, Profile.PHOTO_URI}; + final Cursor cursor; + try { + cursor = + context.getContentResolver() + .query(Profile.CONTENT_URI, projection, null, null, null); + } catch (Throwable e) { + return null; + } + if (cursor == null) { + return null; + } + final String uri = cursor.moveToFirst() ? cursor.getString(1) : null; + cursor.close(); + return uri == null ? null : Uri.parse(uri); + } + + public static boolean isEmulator() { + return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) + || Build.FINGERPRINT.startsWith("generic") + || Build.FINGERPRINT.startsWith("unknown") + || Build.HARDWARE.contains("goldfish") + || Build.HARDWARE.contains("ranchu") + || Build.MODEL.contains("google_sdk") + || Build.MODEL.contains("Emulator") + || Build.MODEL.contains("Android SDK built for x86") + || Build.MANUFACTURER.contains("Genymotion") + || Build.PRODUCT.contains("sdk_google") + || Build.PRODUCT.contains("google_sdk") + || Build.PRODUCT.contains("sdk") + || Build.PRODUCT.contains("sdk_x86") + || Build.PRODUCT.contains("sdk_gphone64_arm64") + || Build.PRODUCT.contains("vbox86p") + || Build.PRODUCT.contains("emulator") + || Build.PRODUCT.contains("simulator"); + } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index d0ea1349f..d4335db50 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -5,6 +5,7 @@ import static eu.siacs.conversations.utils.Random.SECURE_RANDOM; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.os.Build; import android.os.SystemClock; import android.security.KeyChain; import android.util.Base64; @@ -59,6 +60,7 @@ import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509KeyManager; import javax.net.ssl.X509TrustManager; +import eu.siacs.conversations.BuildConfig; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.XmppDomainVerifier; @@ -77,6 +79,7 @@ import eu.siacs.conversations.services.NotificationService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.Patterns; +import eu.siacs.conversations.utils.PhoneHelper; import eu.siacs.conversations.utils.Resolver; import eu.siacs.conversations.utils.SSLSocketHelper; import eu.siacs.conversations.utils.SocksSocketFactory; @@ -1292,6 +1295,14 @@ public class XmppConnection implements Runnable { if (!Strings.isNullOrEmpty(firstMessage)) { authenticate.addChild("initial-response").setContent(firstMessage); } + final Element userAgent = authenticate.addChild("user-agent"); + userAgent.setAttribute("id", account.getUuid()); + userAgent.addChild("software").setContent(mXmppConnectionService.getString(R.string.app_name)); + if (!PhoneHelper.isEmulator()) { + userAgent + .addChild("device") + .setContent(String.format("%s %s", Build.MANUFACTURER, Build.MODEL)); + } final Element inline = this.streamFeatures.findChild("inline", Namespace.SASL_2); final boolean inlineStreamManagement = inline != null && inline.hasChild("sm", "urn:xmpp:sm:3"); @@ -1330,9 +1341,7 @@ public class XmppConnection implements Runnable { private Element generateBindRequest(final Collection bindFeatures) { Log.d(Config.LOGTAG, "inline bind features: " + bindFeatures); final Element bind = new Element("bind", Namespace.BIND2); - final Element clientId = bind.addChild("client-id"); - clientId.setAttribute("tag", mXmppConnectionService.getString(R.string.app_name)); - clientId.setContent(account.getUuid()); + bind.addChild("tag").setContent(mXmppConnectionService.getString(R.string.app_name)); final Element features = bind.addChild("features"); if (bindFeatures.contains(Namespace.CARBONS)) { features.addChild("enable", Namespace.CARBONS); @@ -1343,10 +1352,6 @@ public class XmppConnection implements Runnable { return bind; } - private static Collection extractMechanisms(final Element stream) { - return Collections2.transform(stream.getChildren(), c -> c == null ? null : c.getContent()); - } - private void register() { final String preAuth = account.getKey(Account.KEY_PRE_AUTH_REGISTRATION_TOKEN); if (preAuth != null && features.invite()) {