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 --- 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 ++ 6 files changed, 373 insertions(+) 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 (limited to 'src/playstore') 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 -- cgit v1.2.3