Skip to content

Commit 69b8aba

Browse files
committed
Full HMS support
This significantly improves notifications reliability on HMS devices without Google Play Services, but only in the special app build (`tgx.extension=hms`). Google Play Services are always preferred over HMS when available.
1 parent 557007a commit 69b8aba

31 files changed

+405
-337
lines changed
File renamed without changes.

app/build.gradle.kts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ data class PullRequest (
5959

6060
apply(from = "${rootProject.projectDir}/properties.gradle.kts")
6161
val extensionName = extra["extension"] as String
62-
val isHuawei = extra["huawei"] == true
62+
val isHuaweiBuild = extra["huawei"] == true
6363

6464
android {
6565
namespace = "org.thunderdog.challegram"
@@ -68,6 +68,8 @@ android {
6868
val jniVersion = versions.getProperty("version.jni")
6969
val leveldbVersion = versions.getProperty("version.leveldb")
7070

71+
buildConfigString("TGX_EXTENSION", extensionName)
72+
7173
buildConfigString("JNI_VERSION", jniVersion)
7274
buildConfigString("LEVELDB_VERSION", leveldbVersion)
7375

@@ -291,7 +293,7 @@ android {
291293
create(variant.flavor) {
292294
dimension = "abi"
293295
versionCode = (abi + 1)
294-
minSdk = if (isHuawei) {
296+
minSdk = if (isHuaweiBuild) {
295297
maxOf(variant.minSdkVersion, Config.MIN_SDK_VERSION_HUAWEI)
296298
} else {
297299
variant.minSdkVersion
@@ -325,7 +327,7 @@ android {
325327
val versionCodeOverride = versionCode * 1000 + abi * 10
326328
val versionNameOverride = "${versionName}.${defaultConfig.versionCode}${if (extra.has("app_version_suffix")) extra["app_version_suffix"] else ""}-${abiVariant.displayName}${if (extra.has("app_name_suffix")) "-" + extra["app_name_suffix"] else ""}${if (buildType.isDebuggable) "-debug" else ""}"
327329
val outputFileNamePrefix = properties.getProperty("app.file", projectName.replace(" ", "-").replace("#", ""))
328-
val fileName = "${outputFileNamePrefix}-${versionNameOverride.replace("-universal(?=-|\$)", "")}"
330+
val fileName = "${outputFileNamePrefix}-${versionNameOverride.replace("-universal(?=-|\$)", "")}${if (extensionName != "none") "-${extensionName}" else ""}"
329331

330332
buildConfigField("int", "ORIGINAL_VERSION_CODE", versionCode.toString())
331333
buildConfigField("int", "ABI", abi.toString())
@@ -465,4 +467,7 @@ dependencies {
465467

466468
if (!isExperimentalBuild) {
467469
apply(plugin = "com.google.gms.google-services")
470+
if (isHuaweiBuild) {
471+
apply(plugin = "com.huawei.agconnect")
472+
}
468473
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.thunderdog.challegram.push
2+
3+
import android.content.Context
4+
import com.google.android.gms.tasks.OnFailureListener
5+
import com.google.android.gms.tasks.OnSuccessListener
6+
import com.google.firebase.FirebaseApp
7+
import com.google.firebase.messaging.FirebaseMessaging
8+
import me.vkryl.core.isEmpty
9+
import org.drinkless.tdlib.TdApi.DeviceTokenFirebaseCloudMessaging
10+
import tgx.bridge.DeviceTokenRetriever
11+
import tgx.bridge.PushManagerBridge
12+
import tgx.bridge.TokenRetrieverListener
13+
import java.util.regex.Pattern
14+
15+
class FirebaseDeviceTokenRetriever : DeviceTokenRetriever("firebase") {
16+
override fun performInitialization(context: Context): Boolean {
17+
try {
18+
PushManagerBridge.log("FirebaseApp is initializing...")
19+
if (FirebaseApp.initializeApp(context) != null) {
20+
PushManagerBridge.log("FirebaseApp initialization finished successfully")
21+
return true
22+
} else {
23+
PushManagerBridge.log("FirebaseApp initialization failed")
24+
}
25+
} catch (e: Throwable) {
26+
PushManagerBridge.error("FirebaseApp initialization failed with error", e)
27+
}
28+
return false
29+
}
30+
31+
override fun fetchDeviceToken(context: Context, listener: TokenRetrieverListener) {
32+
try {
33+
PushManagerBridge.log("FirebaseMessaging: requesting token...")
34+
FirebaseMessaging.getInstance().token.addOnSuccessListener(OnSuccessListener { token ->
35+
PushManagerBridge.log("FirebaseMessaging: successfully fetched token: \"%s\"", token)
36+
listener.onTokenRetrievalSuccess(DeviceTokenFirebaseCloudMessaging(token, true))
37+
}).addOnFailureListener(OnFailureListener { e: Exception? ->
38+
val errorName = extractFirebaseErrorName(e!!)
39+
PushManagerBridge.error(
40+
"FirebaseMessaging: token fetch failed ($errorName)",
41+
e
42+
)
43+
listener.onTokenRetrievalError(errorName, e)
44+
})
45+
} catch (e: Throwable) {
46+
PushManagerBridge.error("FirebaseMessaging: token fetch failed with error", e)
47+
listener.onTokenRetrievalError("FIREBASE_REQUEST_ERROR", e)
48+
}
49+
}
50+
51+
companion object {
52+
fun extractFirebaseErrorName(e: Throwable): String {
53+
val message: String = e.message!!
54+
if (!isEmpty(message)) {
55+
val matcher = Pattern.compile("(?<=: )[A-Z_]+$").matcher(message)
56+
if (matcher.find()) {
57+
return matcher.group()
58+
}
59+
}
60+
return e.javaClass.getSimpleName()
61+
}
62+
}
63+
}

app/src/google/java/org/thunderdog/challegram/push/FirebaseTokenRetriever.java

Lines changed: 0 additions & 99 deletions
This file was deleted.

app/src/google/java/org/thunderdog/challegram/push/TokenRetrieverFactory.java

Lines changed: 0 additions & 25 deletions
This file was deleted.

app/src/google/java/org/thunderdog/challegram/service/FirebaseListenerService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@
3131
import java.util.HashMap;
3232
import java.util.Map;
3333

34-
import tgx.bridge.PushReceiverBridge;
34+
import tgx.bridge.PushManagerBridge;
3535

3636
public final class FirebaseListenerService extends FirebaseMessagingService {
3737
@Override
3838
public void onNewToken (@NonNull String newToken) {
39-
PushReceiverBridge.onNewToken(this, new TdApi.DeviceTokenFirebaseCloudMessaging(newToken, true));
39+
PushManagerBridge.onNewToken(this, new TdApi.DeviceTokenFirebaseCloudMessaging(newToken, true));
4040
}
4141

4242
@Override
4343
public void onMessageReceived (@NonNull RemoteMessage remoteMessage) {
4444
final Map<String, Object> payload = makePayload(remoteMessage);
4545
final long sentTime = remoteMessage.getSentTime();
4646
final int ttl = remoteMessage.getTtl();
47-
PushReceiverBridge.onMessageReceived(this, payload, sentTime, ttl);
47+
PushManagerBridge.onMessageReceived(this, payload, sentTime, ttl);
4848
}
4949

5050
@Override

app/src/main/java/org/thunderdog/challegram/BaseApplication.kt

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,47 @@
1414
*/
1515
package org.thunderdog.challegram
1616

17+
import android.content.Context
1718
import androidx.multidex.MultiDexApplication
1819
import androidx.work.Configuration
1920
import com.google.firebase.messaging.FirebaseMessaging
21+
import org.thunderdog.challegram.push.FirebaseDeviceTokenRetriever
2022
import org.thunderdog.challegram.service.PushHandler
23+
import org.thunderdog.challegram.telegram.TdlibNotificationUtils
2124
import org.thunderdog.challegram.tool.UI
22-
import tgx.bridge.PushReceiverBridge
25+
import tgx.bridge.DeviceTokenRetriever
26+
import tgx.bridge.PushManagerBridge
27+
import tgx.bridge.DeviceTokenRetrieverFactory
2328
import tgx.extension.TelegramXExtension
2429

2530
class BaseApplication : MultiDexApplication(), Configuration.Provider {
2631
override fun onCreate() {
2732
super.onCreate()
2833

29-
PushReceiverBridge.registerReceiver(PushHandler())
30-
UI.initApp(applicationContext)
34+
var googlePlayServicesAvailable = U.isGooglePlayServicesAvailable(applicationContext)
35+
if (BuildConfig.DEBUG && TelegramXExtension.name == "hms") {
36+
// Test HMS
37+
googlePlayServicesAvailable = false
38+
}
39+
PushManagerBridge.initialize(
3140

32-
val googlePlayServicesAvailable = U.isGooglePlayServicesAvailable(applicationContext)
41+
PushHandler(),
42+
object : DeviceTokenRetrieverFactory {
43+
override fun onCreateNewTokenRetriever(context: Context): DeviceTokenRetriever =
44+
TelegramXExtension.createNewTokenRetriever(context, googlePlayServicesAvailable).takeIf {
45+
!BuildConfig.EXPERIMENTAL
46+
} ?:
47+
FirebaseDeviceTokenRetriever()
48+
}
49+
)
50+
51+
UI.initApp(applicationContext)
3352

34-
TelegramXExtension.configure(this, googlePlayServicesAvailable)
35-
if (TelegramXExtension.shouldDisableFirebaseMessaging(googlePlayServicesAvailable)) {
36-
FirebaseMessaging.getInstance().isAutoInitEnabled = false
53+
if (!BuildConfig.EXPERIMENTAL) {
54+
TelegramXExtension.configure(this, TdlibNotificationUtils.getDeviceTokenRetriever())
55+
if (!TdlibNotificationUtils.isFirebaseTokenRetriever()) {
56+
FirebaseMessaging.getInstance().isAutoInitEnabled = false
57+
}
3758
}
3859
}
3960

app/src/main/java/org/thunderdog/challegram/U.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,6 +2540,7 @@ public static String getUsefulMetadata (@Nullable Tdlib tdlib) {
25402540
String appLocale = Lang.locale().toString();
25412541
String metadata = Lang.getAppBuildAndVersion(tdlib) + " (" + BuildConfig.COMMIT + ")\n" +
25422542
(!buildInfo.getPullRequests().isEmpty() ? "PRs: " + buildInfo.pullRequestsList() + "\n" : "") +
2543+
(!"none".equals(BuildConfig.TGX_EXTENSION) ? "Extension: " + BuildConfig.TGX_EXTENSION + "\n" : "") +
25432544
"TDLib: " + Td.tdlibVersion() + " (tdlib/td@" + Td.tdlibCommitHash() + ")\n" +
25442545
"tgcalls: TGX-Android/tgcalls@" + BuildConfig.TGCALLS_COMMIT + "\n" +
25452546
"WebRTC: TGX-Android/webrtc@" + BuildConfig.WEBRTC_COMMIT + "\n" +

app/src/main/java/org/thunderdog/challegram/service/PushHandler.java

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)