From 7bb48465e21a8468a5a9ed61b81989903c8b36a4 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sat, 2 Nov 2019 15:44:31 +0100 Subject: rename build flavors --- build.gradle | 35 ++-- .../de/pixart/messenger/services/EmojiService.java | 26 +++ .../messenger/services/PushManagementService.java | 37 ++++ .../messenger/ui/widget/EmojiWrapperEditText.java | 17 ++ src/main/java/de/pixart/messenger/Config.java | 2 +- .../messenger/ui/widget/EmojiWrapperEditText.java | 17 -- src/playstore/AndroidManifest.xml | 32 ++++ .../de/pixart/messenger/services/EmojiService.java | 53 ++++++ .../messenger/services/MaintenanceReceiver.java | 38 ++++ .../messenger/services/PushManagementService.java | 194 +++++++++++++++++++++ .../messenger/services/PushMessageReceiver.java | 39 +++++ .../messenger/ui/widget/EmojiWrapperEditText.java | 17 ++ src/schulchat/res/values/about.xml | 51 ++++++ src/schulchat/res/values/defaults.xml | 81 +++++++++ .../de/pixart/messenger/services/EmojiService.java | 26 --- .../messenger/services/PushManagementService.java | 37 ---- src/standardPush/AndroidManifest.xml | 32 ---- .../de/pixart/messenger/services/EmojiService.java | 53 ------ .../messenger/services/MaintenanceReceiver.java | 38 ---- .../messenger/services/PushManagementService.java | 194 --------------------- .../messenger/services/PushMessageReceiver.java | 39 ----- 21 files changed, 608 insertions(+), 450 deletions(-) create mode 100644 src/git/java/de/pixart/messenger/services/EmojiService.java create mode 100644 src/git/java/de/pixart/messenger/services/PushManagementService.java create mode 100644 src/git/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java delete mode 100644 src/main/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java create mode 100644 src/playstore/AndroidManifest.xml create mode 100644 src/playstore/java/de/pixart/messenger/services/EmojiService.java create mode 100644 src/playstore/java/de/pixart/messenger/services/MaintenanceReceiver.java create mode 100644 src/playstore/java/de/pixart/messenger/services/PushManagementService.java create mode 100644 src/playstore/java/de/pixart/messenger/services/PushMessageReceiver.java create mode 100644 src/playstore/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java create mode 100644 src/schulchat/res/values/about.xml create mode 100644 src/schulchat/res/values/defaults.xml delete mode 100644 src/standard/java/de/pixart/messenger/services/EmojiService.java delete mode 100644 src/standard/java/de/pixart/messenger/services/PushManagementService.java delete mode 100644 src/standardPush/AndroidManifest.xml delete mode 100644 src/standardPush/java/de/pixart/messenger/services/EmojiService.java delete mode 100644 src/standardPush/java/de/pixart/messenger/services/MaintenanceReceiver.java delete mode 100644 src/standardPush/java/de/pixart/messenger/services/PushManagementService.java delete mode 100644 src/standardPush/java/de/pixart/messenger/services/PushMessageReceiver.java diff --git a/build.gradle b/build.gradle index 520f606b3..6226e9e9d 100644 --- a/build.gradle +++ b/build.gradle @@ -33,14 +33,14 @@ repositories { } configurations { - standardPushImplementation - standardImplementation - schulchatImplementation + playstoreImplementation + gitImplementation + playstoreschulchatImplementation } dependencies { implementation project(':libs:android-transcoder') - standardPushImplementation('com.google.firebase:firebase-messaging:20.0.0') { + playstoreImplementation('com.google.firebase:firebase-messaging:20.0.0') { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' @@ -66,8 +66,8 @@ dependencies { implementation 'androidx.exifinterface:exifinterface:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.emoji:emoji:1.0.0' - standardImplementation 'androidx.emoji:emoji-bundled:1.0.0' - implementation 'androidx.emoji:emoji-appcompat:1.0.0' + gitImplementation 'androidx.emoji:emoji-appcompat:1.0.0' + gitImplementation 'androidx.emoji:emoji-bundled:1.0.0' implementation 'androidx.exifinterface:exifinterface:1.0.0' implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' @@ -113,6 +113,7 @@ android { archivesBaseName += "-$versionName" applicationId "de.pixart.messenger" multiDexEnabled true + buildConfigField("String", "LOGTAG", '"Pix-Art_Messenger"') buildConfigField("String", "UPDATE_URL", '"https://xmpp.pix-art.de/Pix-Art_Messenger/update/"') resValue "string", "applicationId", applicationId resValue "string", "app_name", "Pix-Art Messenger" @@ -135,21 +136,29 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } - flavorDimensions("distribution") + flavorDimensions("mode", "distribution") productFlavors { - standardPush { - dimension "distribution" - } - standard { - dimension "distribution" + pixart { + dimension "mode" } schulchat { - dimension "distribution" + dimension "mode" applicationId = 'de.schulchat.messenger' + resValue "string", "applicationId", applicationId + resValue "string", "app_name", "Schulchat Messenger" + buildConfigField("String", "LOGTAG", '"Schulchat_Messenger"') versionCode = 1 versionName = '1.0.0' } + playstore { + dimension "distribution" + versionNameSuffix "+_playstore" + } + git { + dimension "distribution" + versionNameSuffix "+_git" + } } if (project.hasProperty('mStoreFile') && project.hasProperty('mStorePassword') && diff --git a/src/git/java/de/pixart/messenger/services/EmojiService.java b/src/git/java/de/pixart/messenger/services/EmojiService.java new file mode 100644 index 000000000..f76cf5a4b --- /dev/null +++ b/src/git/java/de/pixart/messenger/services/EmojiService.java @@ -0,0 +1,26 @@ +package de.pixart.messenger.services; + +import android.content.Context; +import android.os.Build; + +import androidx.emoji.bundled.BundledEmojiCompatConfig; +import androidx.emoji.text.EmojiCompat; + +public class EmojiService { + + private final Context context; + + public EmojiService(Context context) { + this.context = context; + } + + public void init(boolean useBundledEmoji) { + BundledEmojiCompatConfig config = new BundledEmojiCompatConfig(context); + //On recent Androids we assume to have the latest emojis + //there are some annoying bugs with emoji compat that make it a safer choice not to use it when possible + // a) the text preview has annoying glitches when the cut of text contains emojis (the emoji will be half visible) + // b) can trigger a hardware rendering bug https://issuetracker.google.com/issues/67102093 + config.setReplaceAll(useBundledEmoji && Build.VERSION.SDK_INT < Build.VERSION_CODES.O); + EmojiCompat.init(config); + } +} \ No newline at end of file diff --git a/src/git/java/de/pixart/messenger/services/PushManagementService.java b/src/git/java/de/pixart/messenger/services/PushManagementService.java new file mode 100644 index 000000000..9d4673fd3 --- /dev/null +++ b/src/git/java/de/pixart/messenger/services/PushManagementService.java @@ -0,0 +1,37 @@ +package de.pixart.messenger.services; + +import de.pixart.messenger.entities.Account; +import de.pixart.messenger.entities.Conversation; + +public class PushManagementService { + + protected final XmppConnectionService mXmppConnectionService; + + public PushManagementService(XmppConnectionService service) { + this.mXmppConnectionService = service; + } + + void registerPushTokenOnServer(Account account) { + //stub implementation. only affects playstore flavor + } + + void registerPushTokenOnServer(Conversation conversation) { + //stub implementation. only affects playstore flavor + } + + void unregisterChannel(Account account, String hash) { + //stub implementation. only affects playstore flavor + } + + void disablePushOnServer(Conversation conversation) { + //stub implementation. only affects playstore flavor + } + + public boolean available(Account account) { + return false; + } + + public boolean isStub() { + return true; + } +} diff --git a/src/git/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java b/src/git/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java new file mode 100644 index 000000000..7d4a06b28 --- /dev/null +++ b/src/git/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java @@ -0,0 +1,17 @@ +package de.pixart.messenger.ui.widget; + +import android.content.Context; +import androidx.emoji.widget.EmojiAppCompatEditText; +import android.util.AttributeSet; + +public class EmojiWrapperEditText extends EmojiAppCompatEditText { + + public EmojiWrapperEditText(Context context) { + super(context); + } + + public EmojiWrapperEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } + +} \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/Config.java b/src/main/java/de/pixart/messenger/Config.java index 72aacf397..2d0c4acb9 100644 --- a/src/main/java/de/pixart/messenger/Config.java +++ b/src/main/java/de/pixart/messenger/Config.java @@ -39,7 +39,7 @@ public final class Config { return (ENCRYPTION_MASK & (ENCRYPTION_MASK - 1)) != 0; } - public static final String LOGTAG = "Pix-Art_Messenger"; + public static final String LOGTAG = BuildConfig.LOGTAG; public static final Jid BUG_REPORTS = Jid.of("bugs@pix-art.de"); diff --git a/src/main/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java b/src/main/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java deleted file mode 100644 index 7d4a06b28..000000000 --- a/src/main/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java +++ /dev/null @@ -1,17 +0,0 @@ -package de.pixart.messenger.ui.widget; - -import android.content.Context; -import androidx.emoji.widget.EmojiAppCompatEditText; -import android.util.AttributeSet; - -public class EmojiWrapperEditText extends EmojiAppCompatEditText { - - public EmojiWrapperEditText(Context context) { - super(context); - } - - public EmojiWrapperEditText(Context context, AttributeSet attrs) { - super(context, attrs); - } - -} \ No newline at end of file diff --git a/src/playstore/AndroidManifest.xml b/src/playstore/AndroidManifest.xml new file mode 100644 index 000000000..a54f8bee1 --- /dev/null +++ b/src/playstore/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/playstore/java/de/pixart/messenger/services/EmojiService.java b/src/playstore/java/de/pixart/messenger/services/EmojiService.java new file mode 100644 index 000000000..0e5bfadd0 --- /dev/null +++ b/src/playstore/java/de/pixart/messenger/services/EmojiService.java @@ -0,0 +1,53 @@ +package de.pixart.messenger.services; + +import android.content.Context; +import android.os.Build; +import android.util.Log; + +import androidx.core.provider.FontRequest; +import androidx.emoji.text.EmojiCompat; +import androidx.emoji.text.FontRequestEmojiCompatConfig; + +import de.pixart.messenger.Config; +import de.pixart.messenger.R; + +public class EmojiService { + + private final EmojiCompat.InitCallback initCallback = new EmojiCompat.InitCallback() { + @Override + public void onInitialized() { + super.onInitialized(); + Log.d(Config.LOGTAG, "EmojiService succeeded in loading fonts"); + + } + + @Override + public void onFailed(Throwable throwable) { + super.onFailed(throwable); + Log.d(Config.LOGTAG, "EmojiService failed to load fonts", throwable); + } + }; + + private final Context context; + + public EmojiService(Context context) { + this.context = context; + } + + public void init(boolean useBundledEmoji) { + final FontRequest fontRequest = new FontRequest( + "com.google.android.gms.fonts", + "com.google.android.gms", + "Noto Color Emoji Compat", + R.array.font_certs); + FontRequestEmojiCompatConfig fontRequestEmojiCompatConfig = new FontRequestEmojiCompatConfig(context, fontRequest); + fontRequestEmojiCompatConfig.registerInitCallback(initCallback); + //On recent Androids we assume to have the latest emojis + //there are some annoying bugs with emoji compat that make it a safer choice not to use it when possible + // a) when using the ondemand emoji font (play store) flags don’t work + // b) the text preview has annoying glitches when the cut of text contains emojis (the emoji will be half visible) + // c) can trigger a hardware rendering bug https://issuetracker.google.com/issues/67102093 + fontRequestEmojiCompatConfig.setReplaceAll(useBundledEmoji && Build.VERSION.SDK_INT < Build.VERSION_CODES.O); + EmojiCompat.init(fontRequestEmojiCompatConfig); + } +} \ No newline at end of file diff --git a/src/playstore/java/de/pixart/messenger/services/MaintenanceReceiver.java b/src/playstore/java/de/pixart/messenger/services/MaintenanceReceiver.java new file mode 100644 index 000000000..31ed95a88 --- /dev/null +++ b/src/playstore/java/de/pixart/messenger/services/MaintenanceReceiver.java @@ -0,0 +1,38 @@ +package de.pixart.messenger.services; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import com.google.firebase.iid.FirebaseInstanceId; + +import java.io.IOException; + +import de.pixart.messenger.Config; +import de.pixart.messenger.utils.Compatibility; + +public class MaintenanceReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Log.d(Config.LOGTAG, "received intent in maintenance receiver"); + if ("de.pixart.messenger.RENEW_INSTANCE_ID".equals(intent.getAction())) { + renewInstanceToken(context); + + } + } + + private void renewInstanceToken(final Context context) { + new Thread(() -> { + try { + FirebaseInstanceId.getInstance().deleteInstanceId(); + final Intent intent = new Intent(context, XmppConnectionService.class); + intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH); + Compatibility.startService(context, intent); + } catch (IOException e) { + Log.d(Config.LOGTAG, "unable to renew instance token", e); + } + }).start(); + + } +} \ No newline at end of file diff --git a/src/playstore/java/de/pixart/messenger/services/PushManagementService.java b/src/playstore/java/de/pixart/messenger/services/PushManagementService.java new file mode 100644 index 000000000..a7054cf2f --- /dev/null +++ b/src/playstore/java/de/pixart/messenger/services/PushManagementService.java @@ -0,0 +1,194 @@ +package de.pixart.messenger.services; + +import android.util.Log; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.InstanceIdResult; + +import de.pixart.messenger.Config; +import de.pixart.messenger.R; +import de.pixart.messenger.entities.Account; +import de.pixart.messenger.entities.Conversation; +import de.pixart.messenger.utils.Namespace; +import de.pixart.messenger.utils.PhoneHelper; +import de.pixart.messenger.xml.Element; +import de.pixart.messenger.xmpp.XmppConnection; +import de.pixart.messenger.xmpp.forms.Data; +import de.pixart.messenger.xmpp.stanzas.IqPacket; +import rocks.xmpp.addr.Jid; + +public class PushManagementService { + + protected final XmppConnectionService mXmppConnectionService; + + PushManagementService(XmppConnectionService service) { + this.mXmppConnectionService = service; + } + + private static Data findResponseData(IqPacket response) { + final Element command = response.findChild("command", Namespace.COMMANDS); + final Element x = command == null ? null : command.findChild("x", Namespace.DATA); + return x == null ? null : Data.parse(x); + } + + private Jid getAppServer() { + return Jid.of(mXmppConnectionService.getString(R.string.app_server)); + } + + void registerPushTokenOnServer(final Account account) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": has push support"); + retrieveFcmInstanceToken(token -> { + final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); + final IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(getAppServer(), token, androidId); + mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> { + final Data data = findResponseData(response); + if (response.getType() == IqPacket.TYPE.RESULT && data != null) { + try { + String node = data.getValue("node"); + String secret = data.getValue("secret"); + Jid jid = Jid.of(data.getValue("jid")); + if (node != null && secret != null) { + enablePushOnServer(a, jid, node, secret); + } + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + } else { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": invalid response from app server"); + } + }); + }); + } + + public void unregisterChannel(final Account account, final String channel) { + final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); + final Jid appServer = getAppServer(); + final IqPacket packet = mXmppConnectionService.getIqGenerator().unregisterChannelOnAppServer(appServer, androidId, channel); + mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> { + if (response.getType() == IqPacket.TYPE.RESULT) { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully unregistered channel"); + } else if (response.getType() == IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": unable to unregister channel with hash " + channel); + } + }); + } + + void registerPushTokenOnServer(final Conversation conversation) { + Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": room " + conversation.getJid().asBareJid() + " has push support"); + retrieveFcmInstanceToken(token -> { + final Jid muc = conversation.getJid().asBareJid(); + final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); + final IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(getAppServer(), token, androidId, muc); + packet.setTo(muc); + mXmppConnectionService.sendIqPacket(conversation.getAccount(), packet, (a, response) -> { + final Data data = findResponseData(response); + if (response.getType() == IqPacket.TYPE.RESULT && data != null) { + try { + final String node = data.getValue("node"); + final String secret = data.getValue("secret"); + final Jid jid = Jid.of(data.getValue("jid")); + if (node != null && secret != null) { + enablePushOnServer(conversation, jid, node, secret); + } + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + } else { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": invalid response from app server"); + } + }); + }); + } + + private void enablePushOnServer(final Account account, final Jid appServer, final String node, final String secret) { + final IqPacket enable = mXmppConnectionService.getIqGenerator().enablePush(appServer, node, secret); + mXmppConnectionService.sendIqPacket(account, enable, (a, p) -> { + if (p.getType() == IqPacket.TYPE.RESULT) { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully enabled push on server"); + } else if (p.getType() == IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": enabling push on server failed"); + } + }); + } + + private void enablePushOnServer(final Conversation conversation, final Jid appServer, final String node, final String secret) { + final Jid muc = conversation.getJid().asBareJid(); + final IqPacket enable = mXmppConnectionService.getIqGenerator().enablePush(appServer, node, secret); + enable.setTo(muc); + mXmppConnectionService.sendIqPacket(conversation.getAccount(), enable, (a, p) -> { + if (p.getType() == IqPacket.TYPE.RESULT) { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully enabled push on " + muc); + if (conversation.setAttribute(Conversation.ATTRIBUTE_ALWAYS_NOTIFY, node)) { + mXmppConnectionService.updateConversation(conversation); + } + } else if (p.getType() == IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": enabling push on " + muc + " failed"); + } + }); + } + + public void disablePushOnServer(final Conversation conversation) { + final Jid muc = conversation.getJid().asBareJid(); + final String node = conversation.getAttribute(Conversation.ATTRIBUTE_PUSH_NODE); + if (node != null) { + final IqPacket disable = mXmppConnectionService.getIqGenerator().disablePush(getAppServer(), node); + disable.setTo(muc); + mXmppConnectionService.sendIqPacket(conversation.getAccount(), disable, (account, response) -> { + if (response.getType() == IqPacket.TYPE.ERROR) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to disable push for room " + muc); + } + }); + } else { + Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": room " + muc + " has no stored node. unable to disable push"); + } + } + + private void retrieveFcmInstanceToken(final OnGcmInstanceTokenRetrieved instanceTokenRetrieved) { + final FirebaseInstanceId firebaseInstanceId; + try { + firebaseInstanceId = FirebaseInstanceId.getInstance(); + } catch (IllegalStateException e) { + Log.d(Config.LOGTAG, "unable to get firebase instance token ", e); + return; + } + firebaseInstanceId.getInstanceId().addOnCompleteListener(task -> { + if (!task.isSuccessful()) { + Log.d(Config.LOGTAG, "unable to get Firebase instance token", task.getException()); + } + final InstanceIdResult result; + try { + result = task.getResult(); + } catch (Exception e) { + Log.d(Config.LOGTAG, "unable to get Firebase instance token due to bug in library ", e); + return; + } + if (result != null) { + instanceTokenRetrieved.onGcmInstanceTokenRetrieved(result.getToken()); + } + }); + + } + + + public boolean available(Account account) { + final XmppConnection connection = account.getXmppConnection(); + return connection != null + && connection.getFeatures().sm() + && connection.getFeatures().push() + && playServicesAvailable(); + } + + private boolean playServicesAvailable() { + return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(mXmppConnectionService) == ConnectionResult.SUCCESS; + } + + public boolean isStub() { + return false; + } + + interface OnGcmInstanceTokenRetrieved { + void onGcmInstanceTokenRetrieved(String token); + } +} \ No newline at end of file diff --git a/src/playstore/java/de/pixart/messenger/services/PushMessageReceiver.java b/src/playstore/java/de/pixart/messenger/services/PushMessageReceiver.java new file mode 100644 index 000000000..c6d9b96be --- /dev/null +++ b/src/playstore/java/de/pixart/messenger/services/PushMessageReceiver.java @@ -0,0 +1,39 @@ +package de.pixart.messenger.services; + +import android.content.Intent; +import android.util.Log; + +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; + +import java.util.Map; + +import de.pixart.messenger.Config; +import de.pixart.messenger.utils.Compatibility; + +public class PushMessageReceiver extends FirebaseMessagingService { + + @Override + public void onMessageReceived(RemoteMessage message) { + if (!EventReceiver.hasEnabledAccounts(this)) { + Log.d(Config.LOGTAG, "PushMessageReceiver ignored message because no accounts are enabled"); + return; + } + final Map data = message.getData(); + final Intent intent = new Intent(this, XmppConnectionService.class); + intent.setAction(XmppConnectionService.ACTION_FCM_MESSAGE_RECEIVED); + intent.putExtra("account", data.get("account")); + Compatibility.startService(this, intent); + } + + @Override + public void onNewToken(String token) { + if (!EventReceiver.hasEnabledAccounts(this)) { + Log.d(Config.LOGTAG, "PushMessageReceiver ignored new token because no accounts are enabled"); + return; + } + final Intent intent = new Intent(this, XmppConnectionService.class); + intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH); + Compatibility.startService(this, intent); + } +} \ No newline at end of file diff --git a/src/playstore/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java b/src/playstore/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java new file mode 100644 index 000000000..662669fa3 --- /dev/null +++ b/src/playstore/java/de/pixart/messenger/ui/widget/EmojiWrapperEditText.java @@ -0,0 +1,17 @@ +package de.pixart.messenger.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.appcompat.widget.AppCompatEditText; + +public class EmojiWrapperEditText extends AppCompatEditText { + + public EmojiWrapperEditText(Context context) { + super(context); + } + + public EmojiWrapperEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } +} \ No newline at end of file diff --git a/src/schulchat/res/values/about.xml b/src/schulchat/res/values/about.xml new file mode 100644 index 000000000..8cdc8db36 --- /dev/null +++ b/src/schulchat/res/values/about.xml @@ -0,0 +1,51 @@ + + + Schulchat Messenger + \n\nCopyright © 2014-2019 Christian Schneppe + \n\nhttps://schulchat.de + \n\nThis program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + \n\nThis program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + \n\nYou should have received a copy of the GNU General Public License + along with this program. If not, see https://www.gnu.org/licenses + + Libraries + \n\nhttps://www.bouncycastle.org\n(The MIT License (MIT)) + \n\nhttps://www.gnu.org/software/libidn\n(Apache License, Version 2.0) + \n\nhttps://github.com/ge0rg/MemorizingTrustManager\n(The MIT License (MIT)) + \n\nhttps://github.com/MiniDNS/minidns\n(WTFPL) + \n\nhttps://github.com/open-keychain/openkeychain-api-lib\n(Apache License, Version 2.0) + \n\nhttps://github.com/jitsi/otr4j\n(LGPL-3.0) + \n\nhttps://developer.android.com/tools/support-library\n(Apache License, Version 2.0) + \n\nhttps://github.com/google/material-design-icons\n(CC BY 4.0) + \n\nhttps://github.com/leolin310148/ShortcutBadger\n(Apache License, Version 2.0) + \n\nhttps://github.com/kyleduo/SwitchButton\n(Apache License, Version 2.0) + \n\nhttps://github.com/WhisperSystems/libaxolotl-java\n(GPLv3) + \n\nhttps://github.com/vinc3m1/RoundedImageView\n(Apache License, Version 2.0) + \n\nhttps://github.com/jdamcd/android-crop\n(Apache License, Version 2.0) + \n\nhttps://github.com/google/gson\n(Apache License, Version 2.0) + \n\nhttp://hc.apache.org/httpcomponents-client\n(Apache License, Version 2.0) + \n\nhttp://hc.apache.org/httpcomponents-core\n(Apache License, Version 2.0) + \n\nhttps://github.com/square/picasso\n(Apache License, Version 2.0) + \n\nhttps://github.com/davemorrissey/subsampling-scale-image-view\n(Apache License, Version 2.0) + \n\nhttps://github.com/koral--/android-gif-drawable\n(The MIT License (MIT)) + \n\nhttps://github.com/rtoshiro/FullscreenVideoView\n(Apache License, Version 2.0) + \n\nhttps://github.com/mangstadt/ez-vcard\n(FreeBSD) + \n\nhttps://github.com/googlesamples/easypermissions\n(Apache License, Version 2.0) + \n\nhttps://github.com/blazsolar/FlowLayout\n(Apache License, Version 2.0) + \n\nhttps://github.com/ypresto/android-transcoder\n(Apache License, Version 2.0) + \n\nhttp://www.eclipse.org/jetty/\n(Apache License, Version 2.0 and Eclipse Public License 1.0) + \n\nhttp://leafletjs.com/\n(BSD 2-Clause) + \n\nhttps://www.openstreetmap.org/\n(Open Database License) + \n\nhttp://xmpp.rocks/\n(The MIT License (MIT)) + \n\nhttps://github.com/drakeet/ToastCompat/\n(Apache License, Version 2.0) + \n\nhttps://github.com/leinardi/FloatingActionButtonSpeedDial/\n(Apache License, Version 2.0) + \n\nhttps://github.com/PonnamKarthik/RichLinkPreview\n(Apache License, Version 2.0) + \n\nhttps://github.com/AppIntro/AppIntro\n(Apache License, Version 2.0) + + \ No newline at end of file diff --git a/src/schulchat/res/values/defaults.xml b/src/schulchat/res/values/defaults.xml new file mode 100644 index 000000000..6d96c3de0 --- /dev/null +++ b/src/schulchat/res/values/defaults.xml @@ -0,0 +1,81 @@ + + + Computer + Mobile phone + Tablet + Web browser + Console + + true + false + false + false + true + true + true + true + false + true + false + true + true + true + true + true + false + false + true + false + true + true + false + false + false + true + true + true + false + false + false + true + false + true + false + true + true + false + true + true + false + false + true + true + true + false + false + true + 10485760 + 524288 + 0 + 0 + 144 + Phone + content://settings/system/notification_sound + auto + mid + mid + recent + default_off + auto + small + + + + + + + + + + + diff --git a/src/standard/java/de/pixart/messenger/services/EmojiService.java b/src/standard/java/de/pixart/messenger/services/EmojiService.java deleted file mode 100644 index f76cf5a4b..000000000 --- a/src/standard/java/de/pixart/messenger/services/EmojiService.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.pixart.messenger.services; - -import android.content.Context; -import android.os.Build; - -import androidx.emoji.bundled.BundledEmojiCompatConfig; -import androidx.emoji.text.EmojiCompat; - -public class EmojiService { - - private final Context context; - - public EmojiService(Context context) { - this.context = context; - } - - public void init(boolean useBundledEmoji) { - BundledEmojiCompatConfig config = new BundledEmojiCompatConfig(context); - //On recent Androids we assume to have the latest emojis - //there are some annoying bugs with emoji compat that make it a safer choice not to use it when possible - // a) the text preview has annoying glitches when the cut of text contains emojis (the emoji will be half visible) - // b) can trigger a hardware rendering bug https://issuetracker.google.com/issues/67102093 - config.setReplaceAll(useBundledEmoji && Build.VERSION.SDK_INT < Build.VERSION_CODES.O); - EmojiCompat.init(config); - } -} \ No newline at end of file diff --git a/src/standard/java/de/pixart/messenger/services/PushManagementService.java b/src/standard/java/de/pixart/messenger/services/PushManagementService.java deleted file mode 100644 index 9d4673fd3..000000000 --- a/src/standard/java/de/pixart/messenger/services/PushManagementService.java +++ /dev/null @@ -1,37 +0,0 @@ -package de.pixart.messenger.services; - -import de.pixart.messenger.entities.Account; -import de.pixart.messenger.entities.Conversation; - -public class PushManagementService { - - protected final XmppConnectionService mXmppConnectionService; - - public PushManagementService(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - void registerPushTokenOnServer(Account account) { - //stub implementation. only affects playstore flavor - } - - void registerPushTokenOnServer(Conversation conversation) { - //stub implementation. only affects playstore flavor - } - - void unregisterChannel(Account account, String hash) { - //stub implementation. only affects playstore flavor - } - - void disablePushOnServer(Conversation conversation) { - //stub implementation. only affects playstore flavor - } - - public boolean available(Account account) { - return false; - } - - public boolean isStub() { - return true; - } -} diff --git a/src/standardPush/AndroidManifest.xml b/src/standardPush/AndroidManifest.xml deleted file mode 100644 index a54f8bee1..000000000 --- a/src/standardPush/AndroidManifest.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/standardPush/java/de/pixart/messenger/services/EmojiService.java b/src/standardPush/java/de/pixart/messenger/services/EmojiService.java deleted file mode 100644 index 0e5bfadd0..000000000 --- a/src/standardPush/java/de/pixart/messenger/services/EmojiService.java +++ /dev/null @@ -1,53 +0,0 @@ -package de.pixart.messenger.services; - -import android.content.Context; -import android.os.Build; -import android.util.Log; - -import androidx.core.provider.FontRequest; -import androidx.emoji.text.EmojiCompat; -import androidx.emoji.text.FontRequestEmojiCompatConfig; - -import de.pixart.messenger.Config; -import de.pixart.messenger.R; - -public class EmojiService { - - private final EmojiCompat.InitCallback initCallback = new EmojiCompat.InitCallback() { - @Override - public void onInitialized() { - super.onInitialized(); - Log.d(Config.LOGTAG, "EmojiService succeeded in loading fonts"); - - } - - @Override - public void onFailed(Throwable throwable) { - super.onFailed(throwable); - Log.d(Config.LOGTAG, "EmojiService failed to load fonts", throwable); - } - }; - - private final Context context; - - public EmojiService(Context context) { - this.context = context; - } - - public void init(boolean useBundledEmoji) { - final FontRequest fontRequest = new FontRequest( - "com.google.android.gms.fonts", - "com.google.android.gms", - "Noto Color Emoji Compat", - R.array.font_certs); - FontRequestEmojiCompatConfig fontRequestEmojiCompatConfig = new FontRequestEmojiCompatConfig(context, fontRequest); - fontRequestEmojiCompatConfig.registerInitCallback(initCallback); - //On recent Androids we assume to have the latest emojis - //there are some annoying bugs with emoji compat that make it a safer choice not to use it when possible - // a) when using the ondemand emoji font (play store) flags don’t work - // b) the text preview has annoying glitches when the cut of text contains emojis (the emoji will be half visible) - // c) can trigger a hardware rendering bug https://issuetracker.google.com/issues/67102093 - fontRequestEmojiCompatConfig.setReplaceAll(useBundledEmoji && Build.VERSION.SDK_INT < Build.VERSION_CODES.O); - EmojiCompat.init(fontRequestEmojiCompatConfig); - } -} \ No newline at end of file diff --git a/src/standardPush/java/de/pixart/messenger/services/MaintenanceReceiver.java b/src/standardPush/java/de/pixart/messenger/services/MaintenanceReceiver.java deleted file mode 100644 index 31ed95a88..000000000 --- a/src/standardPush/java/de/pixart/messenger/services/MaintenanceReceiver.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.pixart.messenger.services; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import com.google.firebase.iid.FirebaseInstanceId; - -import java.io.IOException; - -import de.pixart.messenger.Config; -import de.pixart.messenger.utils.Compatibility; - -public class MaintenanceReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Log.d(Config.LOGTAG, "received intent in maintenance receiver"); - if ("de.pixart.messenger.RENEW_INSTANCE_ID".equals(intent.getAction())) { - renewInstanceToken(context); - - } - } - - private void renewInstanceToken(final Context context) { - new Thread(() -> { - try { - FirebaseInstanceId.getInstance().deleteInstanceId(); - final Intent intent = new Intent(context, XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH); - Compatibility.startService(context, intent); - } catch (IOException e) { - Log.d(Config.LOGTAG, "unable to renew instance token", e); - } - }).start(); - - } -} \ No newline at end of file diff --git a/src/standardPush/java/de/pixart/messenger/services/PushManagementService.java b/src/standardPush/java/de/pixart/messenger/services/PushManagementService.java deleted file mode 100644 index a7054cf2f..000000000 --- a/src/standardPush/java/de/pixart/messenger/services/PushManagementService.java +++ /dev/null @@ -1,194 +0,0 @@ -package de.pixart.messenger.services; - -import android.util.Log; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; -import com.google.firebase.iid.FirebaseInstanceId; -import com.google.firebase.iid.InstanceIdResult; - -import de.pixart.messenger.Config; -import de.pixart.messenger.R; -import de.pixart.messenger.entities.Account; -import de.pixart.messenger.entities.Conversation; -import de.pixart.messenger.utils.Namespace; -import de.pixart.messenger.utils.PhoneHelper; -import de.pixart.messenger.xml.Element; -import de.pixart.messenger.xmpp.XmppConnection; -import de.pixart.messenger.xmpp.forms.Data; -import de.pixart.messenger.xmpp.stanzas.IqPacket; -import rocks.xmpp.addr.Jid; - -public class PushManagementService { - - protected final XmppConnectionService mXmppConnectionService; - - PushManagementService(XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - private static Data findResponseData(IqPacket response) { - final Element command = response.findChild("command", Namespace.COMMANDS); - final Element x = command == null ? null : command.findChild("x", Namespace.DATA); - return x == null ? null : Data.parse(x); - } - - private Jid getAppServer() { - return Jid.of(mXmppConnectionService.getString(R.string.app_server)); - } - - void registerPushTokenOnServer(final Account account) { - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": has push support"); - retrieveFcmInstanceToken(token -> { - final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); - final IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(getAppServer(), token, androidId); - mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> { - final Data data = findResponseData(response); - if (response.getType() == IqPacket.TYPE.RESULT && data != null) { - try { - String node = data.getValue("node"); - String secret = data.getValue("secret"); - Jid jid = Jid.of(data.getValue("jid")); - if (node != null && secret != null) { - enablePushOnServer(a, jid, node, secret); - } - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - } else { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": invalid response from app server"); - } - }); - }); - } - - public void unregisterChannel(final Account account, final String channel) { - final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); - final Jid appServer = getAppServer(); - final IqPacket packet = mXmppConnectionService.getIqGenerator().unregisterChannelOnAppServer(appServer, androidId, channel); - mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> { - if (response.getType() == IqPacket.TYPE.RESULT) { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully unregistered channel"); - } else if (response.getType() == IqPacket.TYPE.ERROR) { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": unable to unregister channel with hash " + channel); - } - }); - } - - void registerPushTokenOnServer(final Conversation conversation) { - Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": room " + conversation.getJid().asBareJid() + " has push support"); - retrieveFcmInstanceToken(token -> { - final Jid muc = conversation.getJid().asBareJid(); - final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService); - final IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(getAppServer(), token, androidId, muc); - packet.setTo(muc); - mXmppConnectionService.sendIqPacket(conversation.getAccount(), packet, (a, response) -> { - final Data data = findResponseData(response); - if (response.getType() == IqPacket.TYPE.RESULT && data != null) { - try { - final String node = data.getValue("node"); - final String secret = data.getValue("secret"); - final Jid jid = Jid.of(data.getValue("jid")); - if (node != null && secret != null) { - enablePushOnServer(conversation, jid, node, secret); - } - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - } else { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": invalid response from app server"); - } - }); - }); - } - - private void enablePushOnServer(final Account account, final Jid appServer, final String node, final String secret) { - final IqPacket enable = mXmppConnectionService.getIqGenerator().enablePush(appServer, node, secret); - mXmppConnectionService.sendIqPacket(account, enable, (a, p) -> { - if (p.getType() == IqPacket.TYPE.RESULT) { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully enabled push on server"); - } else if (p.getType() == IqPacket.TYPE.ERROR) { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": enabling push on server failed"); - } - }); - } - - private void enablePushOnServer(final Conversation conversation, final Jid appServer, final String node, final String secret) { - final Jid muc = conversation.getJid().asBareJid(); - final IqPacket enable = mXmppConnectionService.getIqGenerator().enablePush(appServer, node, secret); - enable.setTo(muc); - mXmppConnectionService.sendIqPacket(conversation.getAccount(), enable, (a, p) -> { - if (p.getType() == IqPacket.TYPE.RESULT) { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully enabled push on " + muc); - if (conversation.setAttribute(Conversation.ATTRIBUTE_ALWAYS_NOTIFY, node)) { - mXmppConnectionService.updateConversation(conversation); - } - } else if (p.getType() == IqPacket.TYPE.ERROR) { - Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": enabling push on " + muc + " failed"); - } - }); - } - - public void disablePushOnServer(final Conversation conversation) { - final Jid muc = conversation.getJid().asBareJid(); - final String node = conversation.getAttribute(Conversation.ATTRIBUTE_PUSH_NODE); - if (node != null) { - final IqPacket disable = mXmppConnectionService.getIqGenerator().disablePush(getAppServer(), node); - disable.setTo(muc); - mXmppConnectionService.sendIqPacket(conversation.getAccount(), disable, (account, response) -> { - if (response.getType() == IqPacket.TYPE.ERROR) { - Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": unable to disable push for room " + muc); - } - }); - } else { - Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": room " + muc + " has no stored node. unable to disable push"); - } - } - - private void retrieveFcmInstanceToken(final OnGcmInstanceTokenRetrieved instanceTokenRetrieved) { - final FirebaseInstanceId firebaseInstanceId; - try { - firebaseInstanceId = FirebaseInstanceId.getInstance(); - } catch (IllegalStateException e) { - Log.d(Config.LOGTAG, "unable to get firebase instance token ", e); - return; - } - firebaseInstanceId.getInstanceId().addOnCompleteListener(task -> { - if (!task.isSuccessful()) { - Log.d(Config.LOGTAG, "unable to get Firebase instance token", task.getException()); - } - final InstanceIdResult result; - try { - result = task.getResult(); - } catch (Exception e) { - Log.d(Config.LOGTAG, "unable to get Firebase instance token due to bug in library ", e); - return; - } - if (result != null) { - instanceTokenRetrieved.onGcmInstanceTokenRetrieved(result.getToken()); - } - }); - - } - - - public boolean available(Account account) { - final XmppConnection connection = account.getXmppConnection(); - return connection != null - && connection.getFeatures().sm() - && connection.getFeatures().push() - && playServicesAvailable(); - } - - private boolean playServicesAvailable() { - return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(mXmppConnectionService) == ConnectionResult.SUCCESS; - } - - public boolean isStub() { - return false; - } - - interface OnGcmInstanceTokenRetrieved { - void onGcmInstanceTokenRetrieved(String token); - } -} \ No newline at end of file diff --git a/src/standardPush/java/de/pixart/messenger/services/PushMessageReceiver.java b/src/standardPush/java/de/pixart/messenger/services/PushMessageReceiver.java deleted file mode 100644 index c6d9b96be..000000000 --- a/src/standardPush/java/de/pixart/messenger/services/PushMessageReceiver.java +++ /dev/null @@ -1,39 +0,0 @@ -package de.pixart.messenger.services; - -import android.content.Intent; -import android.util.Log; - -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.RemoteMessage; - -import java.util.Map; - -import de.pixart.messenger.Config; -import de.pixart.messenger.utils.Compatibility; - -public class PushMessageReceiver extends FirebaseMessagingService { - - @Override - public void onMessageReceived(RemoteMessage message) { - if (!EventReceiver.hasEnabledAccounts(this)) { - Log.d(Config.LOGTAG, "PushMessageReceiver ignored message because no accounts are enabled"); - return; - } - final Map data = message.getData(); - final Intent intent = new Intent(this, XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_FCM_MESSAGE_RECEIVED); - intent.putExtra("account", data.get("account")); - Compatibility.startService(this, intent); - } - - @Override - public void onNewToken(String token) { - if (!EventReceiver.hasEnabledAccounts(this)) { - Log.d(Config.LOGTAG, "PushMessageReceiver ignored new token because no accounts are enabled"); - return; - } - final Intent intent = new Intent(this, XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH); - Compatibility.startService(this, intent); - } -} \ No newline at end of file -- cgit v1.2.3