diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 617a798fed..4d3f3ce6f0 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -1,6 +1,15 @@ apply plugin: "com.android.application" apply plugin: "kotlin-android" +repositories { + maven { + url 'https://www.jitpack.io' + content { + includeModule 'com.github.UnifiedPush', 'android-connector' + } + } +} + def verName = "10.9.1" def verCode = 1163 @@ -312,6 +321,8 @@ dependencies { implementation 'com.google.mlkit:language-id:17.0.5' // add for emoji implementation 'com.jaredrummler:truetypeparser-light:1.0.0' + // add for up + implementation 'com.github.UnifiedPush:android-connector:2.3.1' } apply plugin: "com.google.gms.google-services" diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index 0e663ade33..bf78c6a1f1 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -713,6 +713,14 @@ + + + + + + + + diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java index 5e10ec3130..c1f97c63cf 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ApplicationLoader.java @@ -65,6 +65,7 @@ import tw.nekomimi.nekogram.NekoXConfig; import tw.nekomimi.nekogram.parts.SignturesKt; import tw.nekomimi.nekogram.utils.FileUtil; +import xyz.nextalone.nagram.NaConfig; import static android.os.Build.VERSION.SDK_INT; @@ -363,6 +364,13 @@ private static void startPushServiceInternal() { if (enabled) { AndroidUtilities.runOnUIThread(() -> { try { + Log.d("TFOSS", "Starting push service..."); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && NaConfig.INSTANCE.getPushServiceTypeInAppDialog().Bool()) { + applicationContext.startForegroundService(new Intent(applicationContext, NotificationsService.class)); + } else { + applicationContext.startService(new Intent(applicationContext, NotificationsService.class)); + } + Log.d("TFOSS", "Trying to start push service every 10 minutes"); // Telegram-FOSS: unconditionally enable push service AlarmManager am = (AlarmManager) applicationContext.getSystemService(Context.ALARM_SERVICE); @@ -371,13 +379,6 @@ private static void startPushServiceInternal() { am.cancel(pendingIntent); am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10 * 60 * 1000, pendingIntent); - - Log.d("TFOSS", "Starting push service..."); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - applicationContext.startForegroundService(new Intent(applicationContext, NotificationsService.class)); - } else { - applicationContext.startService(new Intent(applicationContext, NotificationsService.class)); - } } catch (Throwable e) { Log.d("TFOSS", "Failed to start push service"); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java index b31be3383d..c4ec95a50d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationsService.java @@ -20,13 +20,15 @@ import androidx.core.app.NotificationCompat; +import xyz.nextalone.nagram.NaConfig; + public class NotificationsService extends Service { @Override public void onCreate() { super.onCreate(); ApplicationLoader.postInitApplication(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && NaConfig.INSTANCE.getPushServiceTypeInAppDialog().Bool()) { String CHANNEL_ID = "push_service_channel"; NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel channel = new NotificationChannel(CHANNEL_ID, LocaleController.getString("NekoXPushService", R.string.NekoXPushService), NotificationManager.IMPORTANCE_DEFAULT); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java b/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java index 4cb1dfc0dc..93f6ee8d3a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/PushListenerController.java @@ -22,13 +22,17 @@ import java.util.Locale; import java.util.concurrent.CountDownLatch; +import xyz.nextalone.nagram.NaConfig; + public class PushListenerController { public static final int PUSH_TYPE_FIREBASE = 2, + PUSH_TYPE_SIMPLE = 4, PUSH_TYPE_HUAWEI = 13; @Retention(RetentionPolicy.SOURCE) @IntDef({ PUSH_TYPE_FIREBASE, + PUSH_TYPE_SIMPLE, PUSH_TYPE_HUAWEI }) public @interface PushType {} @@ -56,7 +60,7 @@ public static void sendRegistrationToServer(@PushType int pushType, String token if (userConfig.getClientUserId() != 0) { final int currentAccount = a; if (sendStat) { - String tag = pushType == PUSH_TYPE_FIREBASE ? "fcm" : "hcm"; + String tag = pushType == PUSH_TYPE_FIREBASE ? "fcm" : (pushType == PUSH_TYPE_HUAWEI ? "hcm" : "up"); TLRPC.TL_help_saveAppLog req = new TLRPC.TL_help_saveAppLog(); TLRPC.TL_inputAppEvent event = new TLRPC.TL_inputAppEvent(); event.time = SharedConfig.pushStringGetTimeStart; @@ -84,7 +88,7 @@ public static void sendRegistrationToServer(@PushType int pushType, String token } public static void processRemoteMessage(@PushType int pushType, String data, long time) { - String tag = pushType == PUSH_TYPE_FIREBASE ? "FCM" : "HCM"; + String tag = pushType == PUSH_TYPE_FIREBASE ? "FCM" : (pushType == PUSH_TYPE_HUAWEI ? "HCM" : "UP"); if (BuildVars.LOGS_ENABLED) { FileLog.d(tag + " PRE START PROCESSING"); } @@ -1435,7 +1439,20 @@ public int getPushType() { public static IPushListenerServiceProvider getProvider() { if (instance != null) return instance; - instance = new GooglePushListenerServiceProvider(); + switch (NaConfig.INSTANCE.getPushServiceType().Int()) { + case 1: { + instance = new GooglePushListenerServiceProvider(); + break; + } + case 2: { + instance = new UnifiedPushListenerServiceProvider(); + break; + } + default: { + instance = new DummyPushProvider(); + break; + } + } return instance; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UnifiedPushListenerServiceProvider.java b/TMessagesProj/src/main/java/org/telegram/messenger/UnifiedPushListenerServiceProvider.java new file mode 100644 index 0000000000..ead106d76a --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UnifiedPushListenerServiceProvider.java @@ -0,0 +1,63 @@ +package org.telegram.messenger; + +import android.os.SystemClock; +import android.text.TextUtils; + +import org.unifiedpush.android.connector.UnifiedPush; + +import java.util.ArrayList; +import java.util.List; + +public class UnifiedPushListenerServiceProvider implements PushListenerController.IPushListenerServiceProvider { + public UnifiedPushListenerServiceProvider(){}; + + @Override + public boolean hasServices() { + return !UnifiedPush.getDistributors(ApplicationLoader.applicationContext, new ArrayList<>()).isEmpty(); + } + + @Override + public String getLogTitle() { + return "UnifiedPush"; + } + + @Override + public void onRequestPushToken() { + String currentPushString = SharedConfig.pushString; + if (!TextUtils.isEmpty(currentPushString)) { + if (BuildVars.DEBUG_PRIVATE_VERSION && BuildVars.LOGS_ENABLED) { + FileLog.d("UnifiedPush endpoint = " + currentPushString); + } + } else { + if (BuildVars.LOGS_ENABLED) { + FileLog.d("No UnifiedPush string found"); + } + } + Utilities.globalQueue.postRunnable(() -> { + try { + SharedConfig.pushStringGetTimeStart = SystemClock.elapsedRealtime(); + SharedConfig.saveConfig(); + if (UnifiedPush.getAckDistributor(ApplicationLoader.applicationContext) == null) { + List distributors = UnifiedPush.getDistributors(ApplicationLoader.applicationContext, new ArrayList<>()); + if (distributors.size() > 0) { + String distributor = distributors.get(0); + UnifiedPush.saveDistributor(ApplicationLoader.applicationContext, distributor); + } + } + UnifiedPush.registerApp( + ApplicationLoader.applicationContext, + "default", + new ArrayList<>(), + "Telegram Simple Push" + ); + } catch (Throwable e) { + FileLog.e(e); + } + }); + } + + @Override + public int getPushType() { + return PushListenerController.PUSH_TYPE_SIMPLE; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UnifiedPushReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/UnifiedPushReceiver.java new file mode 100644 index 0000000000..1faf51be87 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UnifiedPushReceiver.java @@ -0,0 +1,115 @@ +package org.telegram.messenger; + +import android.content.Context; +import android.os.SystemClock; + +import androidx.annotation.NonNull; + +import org.telegram.tgnet.ConnectionsManager; + +import org.unifiedpush.android.connector.MessagingReceiver; +import org.unifiedpush.android.connector.UnifiedPush; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.concurrent.CountDownLatch; + +import xyz.nextalone.nagram.NaConfig; + +public class UnifiedPushReceiver extends MessagingReceiver { + + private static long lastReceivedNotification = 0; + private static long numOfReceivedNotifications = 0; + + public static long getLastReceivedNotification() { + return lastReceivedNotification; + } + + public static long getNumOfReceivedNotifications() { + return numOfReceivedNotifications; + } + + @Override + public void onNewEndpoint(Context context, String endpoint, String instance){ + Utilities.globalQueue.postRunnable(() -> { + SharedConfig.pushStringGetTimeEnd = SystemClock.elapsedRealtime(); + + String savedDistributor = UnifiedPush.getSavedDistributor(context); + + if (savedDistributor.equals("io.heckel.ntfy")) { + PushListenerController.sendRegistrationToServer(PushListenerController.PUSH_TYPE_SIMPLE, endpoint); + return; + } + + try { + PushListenerController.sendRegistrationToServer(PushListenerController.PUSH_TYPE_SIMPLE, NaConfig.INSTANCE.getPushServiceTypeUnifiedGateway().String() + URLEncoder.encode(endpoint, "UTF-8")); + } catch (UnsupportedEncodingException e) { + FileLog.e(e); + } + }); + } + + @Override + public void onMessage(Context context, byte[] message, String instance){ + final long receiveTime = SystemClock.elapsedRealtime(); + final CountDownLatch countDownLatch = new CountDownLatch(1); + + lastReceivedNotification = SystemClock.elapsedRealtime(); + numOfReceivedNotifications++; + + AndroidUtilities.runOnUIThread(() -> { + if (BuildVars.LOGS_ENABLED) { + FileLog.d("UP PRE INIT APP"); + } + ApplicationLoader.postInitApplication(); + if (BuildVars.LOGS_ENABLED) { + FileLog.d("UP POST INIT APP"); + } + Utilities.stageQueue.postRunnable(() -> { + if (BuildVars.LOGS_ENABLED) { + FileLog.d("UP START PROCESSING"); + } + for (int a : SharedConfig.activeAccounts) { + if (UserConfig.getInstance(a).isClientActivated()) { + ConnectionsManager.onInternalPushReceived(a); + ConnectionsManager.getInstance(a).resumeNetworkMaybe(); + } + } + countDownLatch.countDown(); + }); + }); + Utilities.globalQueue.postRunnable(()-> { + try { + countDownLatch.await(); + } catch (Throwable ignore) { + + } + if (BuildVars.DEBUG_VERSION) { + FileLog.d("finished UP service, time = " + (SystemClock.elapsedRealtime() - receiveTime)); + } + }); + } + + @Override + public void onRegistrationFailed(Context context, String instance){ + if (BuildVars.LOGS_ENABLED) { + FileLog.d("Failed to get endpoint"); + } + SharedConfig.pushStringStatus = "__UNIFIEDPUSH_FAILED__"; + Utilities.globalQueue.postRunnable(() -> { + SharedConfig.pushStringGetTimeEnd = SystemClock.elapsedRealtime(); + + PushListenerController.sendRegistrationToServer(PushListenerController.PUSH_TYPE_SIMPLE, null); + }); + } + + @Override + public void onUnregistered(Context context, String instance){ + SharedConfig.pushStringStatus = "__UNIFIEDPUSH_FAILED__"; + Utilities.globalQueue.postRunnable(() -> { + SharedConfig.pushStringGetTimeEnd = SystemClock.elapsedRealtime(); + + PushListenerController.sendRegistrationToServer(PushListenerController.PUSH_TYPE_SIMPLE, null); + }); + } +} diff --git a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java index 00cb887f28..8d9475e213 100644 --- a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java +++ b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/settings/NekoGeneralSettingsActivity.java @@ -27,11 +27,13 @@ import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; import org.telegram.messenger.AndroidUtilities; +import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.BuildVars; import org.telegram.messenger.ContactsController; import org.telegram.messenger.LocaleController; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; +import org.telegram.messenger.NotificationsService; import org.telegram.messenger.R; import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig; @@ -236,6 +238,16 @@ public class NekoGeneralSettingsActivity extends BaseNekoXSettingsActivity { private final AbstractConfigCell displayPersianCalendarByLatinRow = cellGroup.appendCell(new ConfigCellTextCheck(NekoConfig.displayPersianCalendarByLatin)); private final AbstractConfigCell divider7 = cellGroup.appendCell(new ConfigCellDivider()); + private final AbstractConfigCell headerPushService = cellGroup.appendCell(new ConfigCellHeader(LocaleController.getString("Notifications", R.string.Notifications))); + private final AbstractConfigCell pushServiceTypeRow = cellGroup.appendCell(new ConfigCellSelectBox(null, NaConfig.INSTANCE.getPushServiceType(), new String[]{ + LocaleController.getString(R.string.PushServiceTypeInApp), + LocaleController.getString(R.string.PushServiceTypeFCM), + LocaleController.getString(R.string.PushServiceTypeUnified), + }, null)); + private final AbstractConfigCell pushServiceTypeInAppDialogRow = cellGroup.appendCell(new ConfigCellTextCheck(NaConfig.INSTANCE.getPushServiceTypeInAppDialog())); + private final AbstractConfigCell pushServiceTypeUnifiedGatewayRow = cellGroup.appendCell(new ConfigCellTextInput(null, NaConfig.INSTANCE.getPushServiceTypeUnifiedGateway(), null, null, (input) -> input.isEmpty() ? (String) NaConfig.INSTANCE.getPushServiceTypeUnifiedGateway().defaultValue : input)); + private final AbstractConfigCell divider8 = cellGroup.appendCell(new ConfigCellDivider()); + private final AbstractConfigCell headerAutoDownload = cellGroup.appendCell(new ConfigCellHeader(LocaleController.getString("AutoDownload"))); private final AbstractConfigCell win32Row = cellGroup.appendCell(new ConfigCellTextCheck(NekoConfig.disableAutoDownloadingWin32Executable)); private final AbstractConfigCell archiveRow = cellGroup.appendCell(new ConfigCellTextCheck(NekoConfig.disableAutoDownloadingArchive)); @@ -476,6 +488,13 @@ public void onItemClick(int id) { cell.setEnabled(true); } listAdapter.notifyItemChanged(cellGroup.rows.indexOf(translationProviderRow)); + } else if (key.equals(NaConfig.INSTANCE.getPushServiceType().getKey())) { + restartTooltip.showWithAction(0, UndoView.ACTION_NEED_RESATRT, null, null); + } else if (key.equals(NaConfig.INSTANCE.getPushServiceTypeInAppDialog().getKey())) { + ApplicationLoader.applicationContext.stopService(new Intent(ApplicationLoader.applicationContext, NotificationsService.class)); + ApplicationLoader.startPushService(); + } else if (key.equals(NaConfig.INSTANCE.getPushServiceTypeUnifiedGateway().getKey())) { + restartTooltip.showWithAction(0, UndoView.ACTION_NEED_RESATRT, null, null); } }; diff --git a/TMessagesProj/src/main/kotlin/xyz/nextalone/nagram/NaConfig.kt b/TMessagesProj/src/main/kotlin/xyz/nextalone/nagram/NaConfig.kt index 9df6a138a7..fe10945263 100644 --- a/TMessagesProj/src/main/kotlin/xyz/nextalone/nagram/NaConfig.kt +++ b/TMessagesProj/src/main/kotlin/xyz/nextalone/nagram/NaConfig.kt @@ -548,6 +548,24 @@ object NaConfig { ConfigItem.configTypeBool, false ) + val pushServiceType = + addConfig( + "PushServiceType", + ConfigItem.configTypeInt, + 1 + ) + val pushServiceTypeInAppDialog = + addConfig( + "PushServiceTypeInAppDialog", + ConfigItem.configTypeBool, + true + ) + val pushServiceTypeUnifiedGateway = + addConfig( + "PushServiceTypeUnifiedGateway", + ConfigItem.configTypeString, + "https://p2p.belloworld.it/" + ) private fun addConfig( k: String, diff --git a/TMessagesProj/src/main/res/values-zh-rCN/strings_na.xml b/TMessagesProj/src/main/res/values-zh-rCN/strings_na.xml index 293be34214..e9d451655a 100644 --- a/TMessagesProj/src/main/res/values-zh-rCN/strings_na.xml +++ b/TMessagesProj/src/main/res/values-zh-rCN/strings_na.xml @@ -126,4 +126,10 @@ Disable Flag Secure 标题居中 在输入框中显示快速回复按钮 + 通知推送服务 + 内置 + Google FCM + Unified Push + 显示常驻通知 + Unified Push Gateway diff --git a/TMessagesProj/src/main/res/values/strings_na.xml b/TMessagesProj/src/main/res/values/strings_na.xml index d7cc7802cc..ee733c6b0c 100644 --- a/TMessagesProj/src/main/res/values/strings_na.xml +++ b/TMessagesProj/src/main/res/values/strings_na.xml @@ -126,4 +126,10 @@ Disable Flag Secure Center title in action bar Show Quick Reply In Bot Commands + Push Service Type + In App + Google FCM + Unified Push + Show resident notifications + Unified Push Gateway