mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 03:29:28 +01:00
changes to enable unified push notifications in generic build.
Signed-off-by: gavine99 <github@xymail.tk>
This commit is contained in:
parent
224eb3d0e8
commit
875663c606
@ -13,7 +13,8 @@
|
|||||||
alt="Get it on F-Droid"
|
alt="Get it on F-Droid"
|
||||||
height="80">](https://f-droid.org/packages/com.nextcloud.talk2/)
|
height="80">](https://f-droid.org/packages/com.nextcloud.talk2/)
|
||||||
|
|
||||||
Please note that Notifications won't work with the F-Droid version due to missing Google Play Services.
|
Please note that the F-Droid version uses UnifiedPush notifications and the Play Store version uses Google Play
|
||||||
|
Services notifications.
|
||||||
|
|
||||||
|||||||
|
|||||||
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
@ -63,7 +64,8 @@ Easy starting points are also reviewing [pull requests](https://github.com/nextc
|
|||||||
So you would like to contribute by testing? Awesome, we appreciate that very much.
|
So you would like to contribute by testing? Awesome, we appreciate that very much.
|
||||||
|
|
||||||
To report a bug for the alpha or beta version, just create an issue on github like you would for the stable version and
|
To report a bug for the alpha or beta version, just create an issue on github like you would for the stable version and
|
||||||
provide the version number. Please remember that Google Services are necessary to receive push notifications.
|
provide the version number. Please remember that Google Services are necessary to receive push notifications in the
|
||||||
|
Play Store version whereas the F-Droid version uses UnifiedPush notifications.
|
||||||
|
|
||||||
#### Beta versions (Release Candidates) :package:
|
#### Beta versions (Release Candidates) :package:
|
||||||
|
|
||||||
|
@ -306,6 +306,10 @@ dependencies {
|
|||||||
implementation 'com.github.nextcloud.android-common:ui:0.23.2'
|
implementation 'com.github.nextcloud.android-common:ui:0.23.2'
|
||||||
implementation 'com.github.nextcloud-deps:android-talk-webrtc:132.6834.0'
|
implementation 'com.github.nextcloud-deps:android-talk-webrtc:132.6834.0'
|
||||||
|
|
||||||
|
// unified push library for generic flavour
|
||||||
|
genericImplementation 'org.unifiedpush.android:connector:3.0.7'
|
||||||
|
genericImplementation 'org.unifiedpush.android:connector-ui:1.1.0'
|
||||||
|
|
||||||
gplayImplementation 'com.google.android.gms:play-services-base:18.6.0'
|
gplayImplementation 'com.google.android.gms:play-services-base:18.6.0'
|
||||||
gplayImplementation "com.google.firebase:firebase-messaging:24.1.1"
|
gplayImplementation "com.google.firebase:firebase-messaging:24.1.1"
|
||||||
|
|
||||||
|
21
app/src/generic/AndroidManifest.xml
Normal file
21
app/src/generic/AndroidManifest.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
~ Nextcloud Talk - Android Client
|
||||||
|
~
|
||||||
|
~ SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
|
~ SPDX-FileCopyrightText: 2021-2023 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
~ SPDX-FileCopyrightText: 2017-2019 Mario Danic <mario@lovelyhq.com>
|
||||||
|
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<service android:name=".UnifiedPush"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="org.unifiedpush.android.connector.PUSH_EVENT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
143
app/src/generic/java/com/nextcloud/talk/UnifiedPush.kt
Normal file
143
app/src/generic/java/com/nextcloud/talk/UnifiedPush.kt
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk - Android Client
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Your Name <your@email.com>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.nextcloud.talk
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.work.Data
|
||||||
|
import androidx.work.OneTimeWorkRequest
|
||||||
|
import androidx.work.OutOfQuotaPolicy
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import com.nextcloud.talk.activities.MainActivity
|
||||||
|
import com.nextcloud.talk.jobs.NotificationWorker
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
|
import com.nextcloud.talk.utils.power.PowerManagerUtils
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.unifiedpush.android.connector.FailedReason
|
||||||
|
import org.unifiedpush.android.connector.PushService
|
||||||
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
|
import org.unifiedpush.android.connector.data.PushEndpoint
|
||||||
|
import org.unifiedpush.android.connector.data.PushMessage
|
||||||
|
import org.unifiedpush.android.connector.ui.SelectDistributorDialogsBuilder
|
||||||
|
import org.unifiedpush.android.connector.ui.UnifiedPushFunctions
|
||||||
|
|
||||||
|
class UnifiedPush : PushService() {
|
||||||
|
companion object {
|
||||||
|
private val TAG: String? = UnifiedPush::class.java.simpleName
|
||||||
|
|
||||||
|
private const val MESSAGE_RECEIVED_WAKE_LOCK_TIMEOUT = (60 * 1000L)
|
||||||
|
|
||||||
|
fun getNumberOfDistributorsAvailable(context: Context) =
|
||||||
|
UnifiedPush.getDistributors(context).size
|
||||||
|
|
||||||
|
fun registerForPushMessaging(context: Context, accountName: String, forceChoose: Boolean): Boolean {
|
||||||
|
var retVal = false
|
||||||
|
|
||||||
|
object : SelectDistributorDialogsBuilder(
|
||||||
|
context,
|
||||||
|
object : UnifiedPushFunctions {
|
||||||
|
override fun tryUseDefaultDistributor(callback: (Boolean) -> Unit) =
|
||||||
|
UnifiedPush.tryUseDefaultDistributor(context, callback).also {
|
||||||
|
Log.d(TAG, "tryUseDefaultDistributor()")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAckDistributor(): String? =
|
||||||
|
UnifiedPush.getAckDistributor(context).also {
|
||||||
|
Log.d(TAG, "getAckDistributor() = $it")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDistributors(): List<String> =
|
||||||
|
UnifiedPush.getDistributors(context).also {
|
||||||
|
Log.d(TAG, "getDistributors() = $it")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun register(instance: String) =
|
||||||
|
UnifiedPush.register(context, instance).also {
|
||||||
|
Log.d(TAG, "register($instance)")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun saveDistributor(distributor: String) =
|
||||||
|
UnifiedPush.saveDistributor(context, distributor).also {
|
||||||
|
Log.d(TAG, "saveDistributor($distributor)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
override fun onManyDistributorsFound(distributors: List<String>) =
|
||||||
|
Log.d(TAG, "onManyDistributorsFound($distributors)").run {
|
||||||
|
// true return indicates to calling activity that it should wait whilst dialog is shown
|
||||||
|
retVal = true
|
||||||
|
super.onManyDistributorsFound(distributors)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDistributorSelected(distributor: String) =
|
||||||
|
super.onDistributorSelected(distributor).also {
|
||||||
|
// send message to main activity that it can move on after waiting
|
||||||
|
EventBus.getDefault().post(MainActivity.ProceedToConversationsListMessageEvent())
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
|
instances = listOf(accountName)
|
||||||
|
mayUseCurrent = !forceChoose
|
||||||
|
mayUseDefault = !forceChoose
|
||||||
|
}.run()
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterForPushMessaging(context: Context, accountName: String) =
|
||||||
|
// try and unregister with unified push distributor
|
||||||
|
UnifiedPush.unregister(context, accountName).also {
|
||||||
|
Log.d(TAG, "unregisterForPushMessaging($accountName)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMessage(message: PushMessage, instance: String) {
|
||||||
|
// wake lock to get the notification background job to execute more promptly since it will take eons to run
|
||||||
|
// if phone is dozing. default client ring time is 45 seconds so it should be more than that
|
||||||
|
PowerManagerUtils().acquireTimedPartialLock(MESSAGE_RECEIVED_WAKE_LOCK_TIMEOUT)
|
||||||
|
|
||||||
|
Log.d(TAG, "onMessage()")
|
||||||
|
|
||||||
|
val messageString = message.content.toString(Charsets.UTF_8)
|
||||||
|
|
||||||
|
if (messageString.isNotEmpty() && instance.isNotEmpty()) {
|
||||||
|
val messageData = Data.Builder()
|
||||||
|
.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, messageString)
|
||||||
|
.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, instance)
|
||||||
|
.putInt(
|
||||||
|
BundleKeys.KEY_NOTIFICATION_BACKEND_TYPE,
|
||||||
|
NotificationWorker.Companion.BackendType.UNIFIED_PUSH.value
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
val notificationWork =
|
||||||
|
OneTimeWorkRequest.Builder(NotificationWorker::class.java).setInputData(messageData)
|
||||||
|
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||||
|
.build()
|
||||||
|
WorkManager.getInstance(this).enqueue(notificationWork)
|
||||||
|
|
||||||
|
Log.d(TAG, "expedited NotificationWorker queued")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewEndpoint(endpoint: PushEndpoint, instance: String) {
|
||||||
|
Log.d(TAG, "onNewEndpoint(${endpoint.url}, $instance)")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRegistrationFailed(reason: FailedReason, instance: String) =
|
||||||
|
// the registration is not possible, eg. no network
|
||||||
|
// force unregister to make sure cleaned up. re-register will be re-attempted next time
|
||||||
|
UnifiedPush.unregister(this, instance).also {
|
||||||
|
Log.d(TAG, "onRegistrationFailed(${reason.name}, $instance)")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUnregistered(instance: String) =
|
||||||
|
// this application is unregistered by the distributor from receiving push messages
|
||||||
|
// force unregister to make sure cleaned up. re-register will be re-attempted next time
|
||||||
|
UnifiedPush.unregister(this, instance).also {
|
||||||
|
Log.d(TAG, "onUnregistered($instance)")
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Nextcloud Talk - Android Client
|
|
||||||
*
|
|
||||||
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
|
|
||||||
* SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
package com.nextcloud.talk.utils;
|
|
||||||
|
|
||||||
|
|
||||||
import com.nextcloud.talk.interfaces.ClosedInterface;
|
|
||||||
|
|
||||||
public class ClosedInterfaceImpl implements ClosedInterface {
|
|
||||||
@Override
|
|
||||||
public void providerInstallerInstallIfNeededAsync() {
|
|
||||||
// does absolutely nothing :)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isGooglePlayServicesAvailable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUpPushTokenRegistration() {
|
|
||||||
// no push notifications for generic build variant
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Nextcloud Talk - Android Client
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Marcel Hibbe <dev@mhibbe.de>
|
||||||
|
* SPDX-FileCopyrightText: 2017-2018 Mario Danic <mario@lovelyhq.com>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
package com.nextcloud.talk.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.nextcloud.talk.UnifiedPush.Companion.getNumberOfDistributorsAvailable
|
||||||
|
import com.nextcloud.talk.UnifiedPush.Companion.registerForPushMessaging
|
||||||
|
import com.nextcloud.talk.UnifiedPush.Companion.unregisterForPushMessaging
|
||||||
|
import com.nextcloud.talk.interfaces.ClosedInterface
|
||||||
|
|
||||||
|
class ClosedInterfaceImpl : ClosedInterface {
|
||||||
|
override fun providerInstallerInstallIfNeededAsync() { /* nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isPushMessagingServiceAvailable(context: Context): Boolean {
|
||||||
|
return (getNumberOfDistributorsAvailable(context) > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushMessagingProvider(): String {
|
||||||
|
return "unifiedpush"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerWithServer(context: Context, username: String?, forceChoose: Boolean): Boolean {
|
||||||
|
// unified push available in generic build
|
||||||
|
if (username == null) return false
|
||||||
|
return registerForPushMessaging(context, username, forceChoose)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterWithServer(context: Context, username: String?) {
|
||||||
|
// unified push available in generic build
|
||||||
|
if (username == null) return
|
||||||
|
unregisterForPushMessaging(context, username)
|
||||||
|
}
|
||||||
|
}
|
@ -50,6 +50,10 @@ class NCFirebaseMessagingService : FirebaseMessagingService() {
|
|||||||
val messageData = Data.Builder()
|
val messageData = Data.Builder()
|
||||||
.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, subject)
|
.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, subject)
|
||||||
.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, signature)
|
.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, signature)
|
||||||
|
.putInt(
|
||||||
|
BundleKeys.KEY_NOTIFICATION_BACKEND_TYPE,
|
||||||
|
NotificationWorker.Companion.BackendType.FIREBASE_CLOUD_MESSAGING.value
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
val notificationWork =
|
val notificationWork =
|
||||||
OneTimeWorkRequest.Builder(NotificationWorker::class.java).setInputData(messageData)
|
OneTimeWorkRequest.Builder(NotificationWorker::class.java).setInputData(messageData)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.nextcloud.talk.utils
|
package com.nextcloud.talk.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
@ -26,7 +27,13 @@ import java.util.concurrent.TimeUnit
|
|||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class ClosedInterfaceImpl : ClosedInterface, ProviderInstaller.ProviderInstallListener {
|
class ClosedInterfaceImpl : ClosedInterface, ProviderInstaller.ProviderInstallListener {
|
||||||
|
|
||||||
override val isGooglePlayServicesAvailable: Boolean = isGPlayServicesAvailable()
|
override fun isPushMessagingServiceAvailable(context: Context): Boolean {
|
||||||
|
return isGPlayServicesAvailable()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun pushMessagingProvider(): String {
|
||||||
|
return "gplay"
|
||||||
|
}
|
||||||
|
|
||||||
override fun providerInstallerInstallIfNeededAsync() {
|
override fun providerInstallerInstallIfNeededAsync() {
|
||||||
NextcloudTalkApplication.sharedApplication?.let {
|
NextcloudTalkApplication.sharedApplication?.let {
|
||||||
@ -49,7 +56,7 @@ class ClosedInterfaceImpl : ClosedInterface, ProviderInstaller.ProviderInstallLi
|
|||||||
val api = GoogleApiAvailability.getInstance()
|
val api = GoogleApiAvailability.getInstance()
|
||||||
val code =
|
val code =
|
||||||
NextcloudTalkApplication.sharedApplication?.let {
|
NextcloudTalkApplication.sharedApplication?.let {
|
||||||
api.isGooglePlayServicesAvailable(it.applicationContext)
|
api.isPushMessagingAvailable(it.applicationContext)
|
||||||
}
|
}
|
||||||
return if (code == ConnectionResult.SUCCESS) {
|
return if (code == ConnectionResult.SUCCESS) {
|
||||||
true
|
true
|
||||||
@ -59,11 +66,17 @@ class ClosedInterfaceImpl : ClosedInterface, ProviderInstaller.ProviderInstallLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setUpPushTokenRegistration() {
|
override fun registerWithServer(context: Context, username: String?, forceChoose: Boolean): Boolean {
|
||||||
val firebasePushTokenWorker = OneTimeWorkRequest.Builder(GetFirebasePushTokenWorker::class.java).build()
|
val firebasePushTokenWorker = OneTimeWorkRequest.Builder(GetFirebasePushTokenWorker::class.java).build()
|
||||||
WorkManager.getInstance().enqueue(firebasePushTokenWorker)
|
WorkManager.getInstance().enqueue(firebasePushTokenWorker)
|
||||||
|
|
||||||
setUpPeriodicTokenRefreshFromFCM()
|
setUpPeriodicTokenRefreshFromFCM()
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterWithServer(context: Context, username: String?) {
|
||||||
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpPeriodicTokenRefreshFromFCM() {
|
private fun setUpPeriodicTokenRefreshFromFCM() {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
package com.nextcloud.talk.account
|
package com.nextcloud.talk.account
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -235,6 +236,9 @@ class AccountVerificationActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun storeProfile(displayName: String?, userId: String, capabilitiesOverall: CapabilitiesOverall) {
|
private fun storeProfile(displayName: String?, userId: String, capabilitiesOverall: CapabilitiesOverall) {
|
||||||
|
// for capture by lambda used by subscribe() below
|
||||||
|
val activityContext: Context = this
|
||||||
|
|
||||||
userManager.storeProfile(
|
userManager.storeProfile(
|
||||||
username,
|
username,
|
||||||
UserManager.UserAttributes(
|
UserManager.UserAttributes(
|
||||||
@ -260,8 +264,8 @@ class AccountVerificationActivity : BaseActivity() {
|
|||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onSuccess(user: User) {
|
override fun onSuccess(user: User) {
|
||||||
internalAccountId = user.id!!
|
internalAccountId = user.id!!
|
||||||
if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) {
|
if (ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)) {
|
||||||
ClosedInterfaceImpl().setUpPushTokenRegistration()
|
ClosedInterfaceImpl().registerWithServer(activityContext, user.username, false)
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Skipping push registration.")
|
Log.w(TAG, "Skipping push registration.")
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
|
@ -46,10 +46,14 @@ import io.reactivex.SingleObserver
|
|||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class MainActivity : BaseActivity(), ActionBarProvider {
|
class MainActivity : BaseActivity(), ActionBarProvider {
|
||||||
|
class ProceedToConversationsListMessageEvent
|
||||||
|
|
||||||
lateinit var binding: ActivityMainBinding
|
lateinit var binding: ActivityMainBinding
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -76,9 +80,7 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Set the default theme to replace the launch screen theme.
|
// Set the default theme to replace the launch screen theme.
|
||||||
setTheme(R.style.AppTheme)
|
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
|
||||||
|
|
||||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
|
|
||||||
@ -138,6 +140,11 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onMessageEvent(event: ProceedToConversationsListMessageEvent) {
|
||||||
|
openConversationList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun openConversationList() {
|
private fun openConversationList() {
|
||||||
val intent = Intent(this, ConversationsListActivity::class.java)
|
val intent = Intent(this, ConversationsListActivity::class.java)
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
@ -255,6 +262,8 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
appPreferences.isDbRoomMigrated = true
|
appPreferences.isDbRoomMigrated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for capture by lambda used by subscribe() below
|
||||||
|
val activityContext: Context = this
|
||||||
userManager.users.subscribe(object : SingleObserver<List<User>> {
|
userManager.users.subscribe(object : SingleObserver<List<User>> {
|
||||||
override fun onSubscribe(d: Disposable) {
|
override fun onSubscribe(d: Disposable) {
|
||||||
// unused atm
|
// unused atm
|
||||||
@ -262,10 +271,17 @@ class MainActivity : BaseActivity(), ActionBarProvider {
|
|||||||
|
|
||||||
override fun onSuccess(users: List<User>) {
|
override fun onSuccess(users: List<User>) {
|
||||||
if (users.isNotEmpty()) {
|
if (users.isNotEmpty()) {
|
||||||
ClosedInterfaceImpl().setUpPushTokenRegistration()
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
|
if (
|
||||||
|
!ClosedInterfaceImpl().registerWithServer(
|
||||||
|
activityContext,
|
||||||
|
users.first().username,
|
||||||
|
false)
|
||||||
|
) {
|
||||||
|
// if push registration does not need to show a dialog, open the conversation list now
|
||||||
openConversationList()
|
openConversationList()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
launchServerSelection()
|
launchServerSelection()
|
||||||
|
@ -280,7 +280,7 @@ class ConversationsListActivity :
|
|||||||
// handle notification permission on API level >= 33
|
// handle notification permission on API level >= 33
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
||||||
!platformPermissionUtil.isPostNotificationsPermissionGranted() &&
|
!platformPermissionUtil.isPostNotificationsPermissionGranted() &&
|
||||||
ClosedInterfaceImpl().isGooglePlayServicesAvailable
|
ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)
|
||||||
) {
|
) {
|
||||||
requestPermissions(
|
requestPermissions(
|
||||||
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
|
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
|
||||||
@ -1724,7 +1724,7 @@ class ConversationsListActivity :
|
|||||||
Log.d(TAG, "Notification permission was granted")
|
Log.d(TAG, "Notification permission was granted")
|
||||||
|
|
||||||
if (!PowerManagerUtils().isIgnoringBatteryOptimizations() &&
|
if (!PowerManagerUtils().isIgnoringBatteryOptimizations() &&
|
||||||
ClosedInterfaceImpl().isGooglePlayServicesAvailable
|
ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)
|
||||||
) {
|
) {
|
||||||
val dialogText = String.format(
|
val dialogText = String.format(
|
||||||
context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text),
|
context.resources.getString(R.string.nc_ignore_battery_optimization_dialog_text),
|
||||||
@ -1819,7 +1819,7 @@ class ConversationsListActivity :
|
|||||||
|
|
||||||
return settingsOfUserAreWrong &&
|
return settingsOfUserAreWrong &&
|
||||||
shouldShowNotificationWarningByUserChoice() &&
|
shouldShowNotificationWarningByUserChoice() &&
|
||||||
ClosedInterfaceImpl().isGooglePlayServicesAvailable
|
ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openConversation(textToPaste: String? = "") {
|
private fun openConversation(textToPaste: String? = "") {
|
||||||
|
@ -70,7 +70,8 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var platformPermissionUtil: PlatformPermissionUtil
|
lateinit var platformPermissionUtil: PlatformPermissionUtil
|
||||||
|
|
||||||
private var isGooglePlayServicesAvailable: Boolean = false
|
private var isPushMessagingServiceAvailable: Boolean = false
|
||||||
|
private var pushMessagingProvider: String = ""
|
||||||
|
|
||||||
sealed class DiagnoseElement {
|
sealed class DiagnoseElement {
|
||||||
data class DiagnoseHeadline(val headline: String) : DiagnoseElement()
|
data class DiagnoseHeadline(val headline: String) : DiagnoseElement()
|
||||||
@ -89,7 +90,8 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
)[DiagnoseViewModel::class.java]
|
)[DiagnoseViewModel::class.java]
|
||||||
|
|
||||||
val colorScheme = viewThemeUtils.getColorScheme(this)
|
val colorScheme = viewThemeUtils.getColorScheme(this)
|
||||||
isGooglePlayServicesAvailable = ClosedInterfaceImpl().isGooglePlayServicesAvailable
|
isPushMessagingServiceAvailable = ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)
|
||||||
|
pushMessagingProvider = ClosedInterfaceImpl().pushMessagingProvider()
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
val backgroundColor = colorResource(id = R.color.bg_default)
|
val backgroundColor = colorResource(id = R.color.bg_default)
|
||||||
@ -131,7 +133,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
viewState = viewState,
|
viewState = viewState,
|
||||||
onTestPushClick = { diagnoseViewModel.fetchTestPushResult() },
|
onTestPushClick = { diagnoseViewModel.fetchTestPushResult() },
|
||||||
onDismissDialog = { diagnoseViewModel.dismissDialog() },
|
onDismissDialog = { diagnoseViewModel.dismissDialog() },
|
||||||
isGooglePlayServicesAvailable = isGooglePlayServicesAvailable
|
pushMessagingProvider = pushMessagingProvider
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,17 +227,16 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
value = Build.VERSION.SDK_INT.toString()
|
value = Build.VERSION.SDK_INT.toString()
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isGooglePlayServicesAvailable) {
|
|
||||||
addDiagnosisEntry(
|
addDiagnosisEntry(
|
||||||
key = context.resources.getString(R.string.nc_diagnose_gplay_available_title),
|
key = context.resources.getString(R.string.nc_diagnose_push_notifications_available_title),
|
||||||
value = context.resources.getString(R.string.nc_diagnose_gplay_available_yes)
|
value = context.resources.getString(
|
||||||
)
|
when (pushMessagingProvider) {
|
||||||
} else {
|
"gplay" -> R.string.nc_diagnose_push_notifications_gplay
|
||||||
addDiagnosisEntry(
|
"unifiedpush" -> R.string.nc_diagnose_push_notifications_unified_push
|
||||||
key = context.resources.getString(R.string.nc_diagnose_gplay_available_title),
|
else -> R.string.nc_diagnose_push_notifications_available_no
|
||||||
value = context.resources.getString(R.string.nc_diagnose_gplay_available_no)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
@ -258,8 +259,8 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
value = BuildConfig.FLAVOR
|
value = BuildConfig.FLAVOR
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isGooglePlayServicesAvailable) {
|
if (isPushMessagingServiceAvailable) {
|
||||||
setupAppValuesForGooglePlayServices()
|
setupAppValuesForPushMessaging()
|
||||||
}
|
}
|
||||||
|
|
||||||
addDiagnosisEntry(
|
addDiagnosisEntry(
|
||||||
@ -269,7 +270,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("Detekt.LongMethod")
|
@Suppress("Detekt.LongMethod")
|
||||||
private fun setupAppValuesForGooglePlayServices() {
|
private fun setupAppValuesForPushMessaging() {
|
||||||
addDiagnosisEntry(
|
addDiagnosisEntry(
|
||||||
key = context.resources.getString(R.string.nc_diagnose_battery_optimization_title),
|
key = context.resources.getString(R.string.nc_diagnose_battery_optimization_title),
|
||||||
value = if (PowerManagerUtils().isIgnoringBatteryOptimizations()) {
|
value = if (PowerManagerUtils().isIgnoringBatteryOptimizations()) {
|
||||||
@ -307,6 +308,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (pushMessagingProvider == "gplay") {
|
||||||
addDiagnosisEntry(
|
addDiagnosisEntry(
|
||||||
key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_title),
|
key = context.resources.getString(R.string.nc_diagnose_firebase_push_token_title),
|
||||||
value = if (appPreferences.pushToken.isNullOrEmpty()) {
|
value = if (appPreferences.pushToken.isNullOrEmpty()) {
|
||||||
@ -339,6 +341,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupAccountValues() {
|
private fun setupAccountValues() {
|
||||||
val currentUser = currentUserProvider.currentUser.blockingGet()
|
val currentUser = currentUserProvider.currentUser.blockingGet()
|
||||||
@ -371,7 +374,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
translateBoolean(currentUser.capabilities?.notificationsCapability?.features?.isNotEmpty())
|
translateBoolean(currentUser.capabilities?.notificationsCapability?.features?.isNotEmpty())
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isGooglePlayServicesAvailable) {
|
if ((isPushMessagingServiceAvailable) && (pushMessagingProvider == "gplay")) {
|
||||||
setupPushRegistrationDiagnose()
|
setupPushRegistrationDiagnose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ fun DiagnoseContentComposable(
|
|||||||
viewState: NotificationUiState,
|
viewState: NotificationUiState,
|
||||||
onTestPushClick: () -> Unit,
|
onTestPushClick: () -> Unit,
|
||||||
onDismissDialog: () -> Unit,
|
onDismissDialog: () -> Unit,
|
||||||
isGooglePlayServicesAvailable: Boolean
|
pushMessagingProvider: String
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
Column(
|
Column(
|
||||||
@ -96,7 +96,7 @@ fun DiagnoseContentComposable(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isGooglePlayServicesAvailable) {
|
if (pushMessagingProvider == "gplay") {
|
||||||
ShowTestPushButton(onTestPushClick)
|
ShowTestPushButton(onTestPushClick)
|
||||||
}
|
}
|
||||||
ShowNotificationData(isLoading, showDialog, context, viewState, onDismissDialog)
|
ShowNotificationData(isLoading, showDialog, context, viewState, onDismissDialog)
|
||||||
@ -254,6 +254,6 @@ fun DiagnoseContentPreview() {
|
|||||||
NotificationUiState.Success("Test notification successful"),
|
NotificationUiState.Success("Test notification successful"),
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
true
|
"gplay"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.nextcloud.talk.interfaces
|
package com.nextcloud.talk.interfaces
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
|
||||||
interface ClosedInterface {
|
interface ClosedInterface {
|
||||||
|
|
||||||
val isGooglePlayServicesAvailable: Boolean
|
fun isPushMessagingServiceAvailable(context: Context): Boolean
|
||||||
|
fun pushMessagingProvider(): String
|
||||||
fun providerInstallerInstallIfNeededAsync()
|
fun providerInstallerInstallIfNeededAsync()
|
||||||
fun setUpPushTokenRegistration()
|
fun registerWithServer(context: Context, username: String?, forceChoose: Boolean): Boolean
|
||||||
|
fun unregisterWithServer(context: Context, username: String?)
|
||||||
}
|
}
|
||||||
|
@ -139,10 +139,38 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
private lateinit var notificationManager: NotificationManagerCompat
|
private lateinit var notificationManager: NotificationManagerCompat
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
|
Log.d(TAG, "started work")
|
||||||
|
|
||||||
sharedApplication!!.componentApplication.inject(this)
|
sharedApplication!!.componentApplication.inject(this)
|
||||||
context = applicationContext
|
context = applicationContext
|
||||||
|
|
||||||
|
when (inputData.getInt(BundleKeys.KEY_NOTIFICATION_BACKEND_TYPE, -1)) {
|
||||||
|
Companion.BackendType.FIREBASE_CLOUD_MESSAGING.value -> {
|
||||||
initDecryptedData(inputData)
|
initDecryptedData(inputData)
|
||||||
|
}
|
||||||
|
Companion.BackendType.UNIFIED_PUSH.value -> {
|
||||||
|
pushMessage = LoganSquare.parse(
|
||||||
|
inputData.getString(BundleKeys.KEY_NOTIFICATION_SUBJECT),
|
||||||
|
DecryptedPushMessage::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
userManager.users.blockingGet()?.let {
|
||||||
|
for (user in it) {
|
||||||
|
if (user.username == inputData.getString(BundleKeys.KEY_NOTIFICATION_SIGNATURE)) {
|
||||||
|
signatureVerification = SignatureVerification(true, user)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "parsed UP message")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// message not received from a valid backend
|
||||||
|
return Result.failure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initNcApiAndCredentials()
|
initNcApiAndCredentials()
|
||||||
|
|
||||||
notificationManager = NotificationManagerCompat.from(context!!)
|
notificationManager = NotificationManagerCompat.from(context!!)
|
||||||
@ -1028,5 +1056,14 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
private const val TIMER_START = 1
|
private const val TIMER_START = 1
|
||||||
private const val TIMER_COUNT = 12
|
private const val TIMER_COUNT = 12
|
||||||
private const val TIMER_DELAY: Long = 5
|
private const val TIMER_DELAY: Long = 5
|
||||||
|
private const val GET_ROOM_RETRY_COUNT: Long = 3
|
||||||
|
enum class BackendType(val value: Int) {
|
||||||
|
NONE(-1),
|
||||||
|
FIREBASE_CLOUD_MESSAGING(1),
|
||||||
|
UNIFIED_PUSH(2);
|
||||||
|
companion object {
|
||||||
|
fun fromInt(value: Int) = BackendType.values().first { it.value == value }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,15 +40,18 @@ public class PushRegistrationWorker extends Worker {
|
|||||||
@Inject
|
@Inject
|
||||||
OkHttpClient okHttpClient;
|
OkHttpClient okHttpClient;
|
||||||
|
|
||||||
|
Context workerContext;
|
||||||
|
|
||||||
public PushRegistrationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
|
public PushRegistrationWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
|
||||||
super(context, workerParams);
|
super(context, workerParams);
|
||||||
|
workerContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Result doWork() {
|
public Result doWork() {
|
||||||
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
|
||||||
if (new ClosedInterfaceImpl().isGooglePlayServicesAvailable()) {
|
if (new ClosedInterfaceImpl().isPushMessagingServiceAvailable(workerContext)) {
|
||||||
Data data = getInputData();
|
Data data = getInputData();
|
||||||
String origin = data.getString("origin");
|
String origin = data.getString("origin");
|
||||||
Log.d(TAG, "PushRegistrationWorker called via " + origin);
|
Log.d(TAG, "PushRegistrationWorker called via " + origin);
|
||||||
|
@ -161,6 +161,7 @@ class SettingsActivity :
|
|||||||
)
|
)
|
||||||
|
|
||||||
setupDiagnose()
|
setupDiagnose()
|
||||||
|
setupResetPushPreference()
|
||||||
setupPrivacyUrl()
|
setupPrivacyUrl()
|
||||||
setupSourceCodeUrl()
|
setupSourceCodeUrl()
|
||||||
binding.settingsVersionSummary.text = String.format("v" + BuildConfig.VERSION_NAME)
|
binding.settingsVersionSummary.text = String.format("v" + BuildConfig.VERSION_NAME)
|
||||||
@ -292,8 +293,8 @@ class SettingsActivity :
|
|||||||
@SuppressLint("StringFormatInvalid")
|
@SuppressLint("StringFormatInvalid")
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
private fun setupNotificationPermissionSettings() {
|
private fun setupNotificationPermissionSettings() {
|
||||||
if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) {
|
if (ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)) {
|
||||||
binding.settingsGplayOnlyWrapper.visibility = View.VISIBLE
|
binding.settingsPushNotificationsOnlyWrapper.visibility = View.VISIBLE
|
||||||
|
|
||||||
setTroubleshootingClickListenersIfNecessary()
|
setTroubleshootingClickListenersIfNecessary()
|
||||||
|
|
||||||
@ -375,8 +376,20 @@ class SettingsActivity :
|
|||||||
binding.settingsNotificationsPermissionWrapper.visibility = View.GONE
|
binding.settingsNotificationsPermissionWrapper.visibility = View.GONE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
binding.settingsGplayOnlyWrapper.visibility = View.GONE
|
binding.settingsPushNotificationsOnlyWrapper.visibility = View.GONE
|
||||||
binding.settingsGplayNotAvailable.visibility = View.VISIBLE
|
|
||||||
|
val pushMessagingProvider = ClosedInterfaceImpl().pushMessagingProvider()
|
||||||
|
if (pushMessagingProvider == "gplay") {
|
||||||
|
binding.settingsPushNotificationsNotAvailableText.append("\n".plus(
|
||||||
|
resources!!.getString(R.string.nc_diagnose_push_notifications_gplay).plus("\n").plus(resources!!
|
||||||
|
.getString(R.string.nc_diagnose_push_notifications_gplay_rectify))))
|
||||||
|
} else if (pushMessagingProvider == "unifiedpush") {
|
||||||
|
binding.settingsPushNotificationsNotAvailableText.append("\n".plus(
|
||||||
|
resources!!.getString(R.string.nc_diagnose_push_notifications_unified_push).plus("\n").plus
|
||||||
|
(resources!!.getString(R.string.nc_diagnose_push_notifications_unified_push_rectify))))
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.settingsPushNotificationsNotAvailable.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,6 +548,17 @@ class SettingsActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupResetPushPreference() {
|
||||||
|
binding.resetPushNotificationsWrapper.setOnClickListener {
|
||||||
|
for (user in userManager.users.blockingGet()) {
|
||||||
|
ClosedInterfaceImpl().apply {
|
||||||
|
unregisterWithServer(binding.root.context, user.username)
|
||||||
|
registerWithServer(binding.root.context, user.username, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupLicenceSetting() {
|
private fun setupLicenceSetting() {
|
||||||
if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_gpl3_url))) {
|
if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_gpl3_url))) {
|
||||||
binding.settingsLicence.setOnClickListener {
|
binding.settingsLicence.setOnClickListener {
|
||||||
@ -932,7 +956,7 @@ class SettingsActivity :
|
|||||||
binding.settingsShowNotificationWarningSwitch.isChecked =
|
binding.settingsShowNotificationWarningSwitch.isChecked =
|
||||||
appPreferences.showRegularNotificationWarning
|
appPreferences.showRegularNotificationWarning
|
||||||
|
|
||||||
if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) {
|
if (ClosedInterfaceImpl().isPushMessagingServiceAvailable(context)) {
|
||||||
binding.settingsShowNotificationWarning.setOnClickListener {
|
binding.settingsShowNotificationWarning.setOnClickListener {
|
||||||
val isChecked = binding.settingsShowNotificationWarningSwitch.isChecked
|
val isChecked = binding.settingsShowNotificationWarningSwitch.isChecked
|
||||||
binding.settingsShowNotificationWarningSwitch.isChecked = !isChecked
|
binding.settingsShowNotificationWarningSwitch.isChecked = !isChecked
|
||||||
|
@ -32,6 +32,7 @@ object BundleKeys {
|
|||||||
const val KEY_MODIFIED_BASE_URL = "KEY_MODIFIED_BASE_URL"
|
const val KEY_MODIFIED_BASE_URL = "KEY_MODIFIED_BASE_URL"
|
||||||
const val KEY_NOTIFICATION_SUBJECT = "KEY_NOTIFICATION_SUBJECT"
|
const val KEY_NOTIFICATION_SUBJECT = "KEY_NOTIFICATION_SUBJECT"
|
||||||
const val KEY_NOTIFICATION_SIGNATURE = "KEY_NOTIFICATION_SIGNATURE"
|
const val KEY_NOTIFICATION_SIGNATURE = "KEY_NOTIFICATION_SIGNATURE"
|
||||||
|
const val KEY_NOTIFICATION_BACKEND_TYPE = "KEY_NOTIFICATION_BACKEND_TYPE"
|
||||||
const val KEY_INTERNAL_USER_ID = "KEY_INTERNAL_USER_ID"
|
const val KEY_INTERNAL_USER_ID = "KEY_INTERNAL_USER_ID"
|
||||||
const val KEY_CONVERSATION_TYPE = "KEY_CONVERSATION_TYPE"
|
const val KEY_CONVERSATION_TYPE = "KEY_CONVERSATION_TYPE"
|
||||||
const val KEY_INVITED_PARTICIPANTS = "KEY_INVITED_PARTICIPANTS"
|
const val KEY_INVITED_PARTICIPANTS = "KEY_INVITED_PARTICIPANTS"
|
||||||
|
@ -60,6 +60,14 @@ class PowerManagerUtils {
|
|||||||
orientation = context!!.resources.configuration.orientation
|
orientation = context!!.resources.configuration.orientation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun acquireTimedPartialLock(msTimeout: Long): PowerManager.WakeLock {
|
||||||
|
// wakelock will be auto-released after the given time
|
||||||
|
val pm = context!!.getSystemService(POWER_SERVICE) as PowerManager
|
||||||
|
val wakeLock = pm!!.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "nctalk:timedPartialwakelock")
|
||||||
|
wakeLock!!.acquire(msTimeout)
|
||||||
|
return wakeLock
|
||||||
|
}
|
||||||
|
|
||||||
fun isIgnoringBatteryOptimizations(): Boolean {
|
fun isIgnoringBatteryOptimizations(): Boolean {
|
||||||
val packageName = context!!.packageName
|
val packageName = context!!.packageName
|
||||||
val pm = context!!.getSystemService(POWER_SERVICE) as PowerManager
|
val pm = context!!.getSystemService(POWER_SERVICE) as PowerManager
|
||||||
|
@ -205,7 +205,7 @@
|
|||||||
android:textStyle="bold"/>
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/settings_gplay_only_wrapper"
|
android:id="@+id/settings_push_notifications_only_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -277,7 +277,7 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/settings_gplay_not_available"
|
android:id="@+id/settings_push_notifications_not_available"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="@dimen/standard_padding"
|
android:padding="@dimen/standard_padding"
|
||||||
@ -286,9 +286,10 @@
|
|||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/settings_push_notifications_not_available_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/nc_diagnose_gplay_available_no"/>
|
android:text="@string/nc_diagnose_push_notifications_available_no" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@ -655,8 +656,8 @@
|
|||||||
android:id="@+id/diagnose_title"
|
android:id="@+id/diagnose_title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="@dimen/headline_text_size"
|
android:text="@string/nc_settings_diagnose_title"
|
||||||
android:text="@string/nc_settings_diagnose_title"/>
|
android:textSize="@dimen/headline_text_size" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/diagnose_subtitle"
|
android:id="@+id/diagnose_subtitle"
|
||||||
@ -665,6 +666,28 @@
|
|||||||
android:text="@string/nc_settings_diagnose_subtitle" />
|
android:text="@string/nc_settings_diagnose_subtitle" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/reset_push_notifications_wrapper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/standard_padding"
|
||||||
|
android:background="?android:attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/reset_push_notifications_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/headline_text_size"
|
||||||
|
android:text="@string/prefs_reset_push_title"/>
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/reset_push_notifications_subtitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/prefs_reset_push_summary"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/settings_client_cert"
|
android:id="@+id/settings_client_cert"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -201,9 +201,14 @@ How to translate with transifex:
|
|||||||
<string name="nc_diagnose_app_name_title">App name</string>
|
<string name="nc_diagnose_app_name_title">App name</string>
|
||||||
<string name="nc_diagnose_app_version_title">App version</string>
|
<string name="nc_diagnose_app_version_title">App version</string>
|
||||||
<string name="nc_diagnose_app_users_amount">Registered users</string>
|
<string name="nc_diagnose_app_users_amount">Registered users</string>
|
||||||
<string name="nc_diagnose_gplay_available_title">Google Play services</string>
|
<string name="nc_diagnose_push_notifications_available_title">Push notification services</string>
|
||||||
<string name="nc_diagnose_gplay_available_yes">Google Play services are available</string>
|
<string name="nc_diagnose_push_notifications_available_no">Push notifications are not available.</string>
|
||||||
<string name="nc_diagnose_gplay_available_no">Google Play services are not available. Notifications are not supported</string>
|
<string name="nc_diagnose_push_notifications_gplay">Push notifications are using the Google Play engine.</string>
|
||||||
|
<string name="nc_diagnose_push_notifications_gplay_rectify">An alternate version of Talk is available for devices
|
||||||
|
without the Google Play Apis.</string>
|
||||||
|
<string name="nc_diagnose_push_notifications_unified_push">Push notifications are using the UnifiedPush engine.</string>
|
||||||
|
<string name="nc_diagnose_push_notifications_unified_push_rectify">Notifications can be enabled via UnifiedPush.
|
||||||
|
Please see https://unifiedpush.org</string>
|
||||||
<string name="nc_diagnose_battery_optimization_title">Battery settings</string>
|
<string name="nc_diagnose_battery_optimization_title">Battery settings</string>
|
||||||
<string name="nc_diagnose_battery_optimization_not_ignored">Battery optimization is enabled which might cause issues. You should disable battery optimization!</string>
|
<string name="nc_diagnose_battery_optimization_not_ignored">Battery optimization is enabled which might cause issues. You should disable battery optimization!</string>
|
||||||
<string name="nc_diagnose_battery_optimization_ignored">Battery optimization is ignored, all fine</string>
|
<string name="nc_diagnose_battery_optimization_ignored">Battery optimization is ignored, all fine</string>
|
||||||
@ -860,4 +865,8 @@ How to translate with transifex:
|
|||||||
<string name="unarchived_conversation">Unarchived %1$s</string>
|
<string name="unarchived_conversation">Unarchived %1$s</string>
|
||||||
<string name="conversation_archived">Conversation is archived</string>
|
<string name="conversation_archived">Conversation is archived</string>
|
||||||
<string name="local_time">Local time: %1$s</string>
|
<string name="local_time">Local time: %1$s</string>
|
||||||
|
|
||||||
|
<string name="prefs_reset_push_title">Reset push notifications</string>
|
||||||
|
<string name="prefs_reset_push_summary">Reset push notifications in case of push messaging issues</string>
|
||||||
|
<string name="prefs_reset_push_done">Push notifications reset</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
package com.nextcloud.talk.utils;
|
package com.nextcloud.talk.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import com.nextcloud.talk.interfaces.ClosedInterface;
|
import com.nextcloud.talk.interfaces.ClosedInterface;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
public class ClosedInterfaceImpl implements ClosedInterface {
|
public class ClosedInterfaceImpl implements ClosedInterface {
|
||||||
@Override
|
@Override
|
||||||
@ -17,12 +21,23 @@ public class ClosedInterfaceImpl implements ClosedInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGooglePlayServicesAvailable() {
|
public boolean isPushMessagingServiceAvailable(Context context) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUpPushTokenRegistration() {
|
public String pushMessagingProvider() {
|
||||||
|
return "qa";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerWithServer(Context context, @Nullable String username) {
|
||||||
|
// no push notifications for qa build flavour :(
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterWithServer(@NonNull Context context, @Nullable String username) {
|
||||||
// no push notifications for qa build flavour :(
|
// no push notifications for qa build flavour :(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<verify-metadata>true</verify-metadata>
|
<verify-metadata>true</verify-metadata>
|
||||||
<verify-signatures>true</verify-signatures>
|
<verify-signatures>true</verify-signatures>
|
||||||
|
<ignored-keys>
|
||||||
|
<ignored-key id="4DA93C0B57A98B11" reason=""/>
|
||||||
|
<ignored-key id="73976C9C39C1479B84E2641A5A68A2249128E2C6" reason=""/>
|
||||||
|
</ignored-keys>
|
||||||
<trusted-artifacts>
|
<trusted-artifacts>
|
||||||
<trust file="tensorflow-lite-metadata-0.1.0-rc2.pom" reason="differing hash on every CI run - temp global trust"/>
|
<trust file="tensorflow-lite-metadata-0.1.0-rc2.pom" reason="differing hash on every CI run - temp global trust"/>
|
||||||
<trust group="androidx.fragment"/>
|
<trust group="androidx.fragment"/>
|
||||||
@ -12,6 +16,9 @@
|
|||||||
<trust group="org.javassist" name="javassist" version="3.26.0-GA" reason="java assist"/>
|
<trust group="org.javassist" name="javassist" version="3.26.0-GA" reason="java assist"/>
|
||||||
<trust file=".*-sources[.]jar" regex="true"/>
|
<trust file=".*-sources[.]jar" regex="true"/>
|
||||||
</trusted-artifacts>
|
</trusted-artifacts>
|
||||||
|
<ignored-keys>
|
||||||
|
<ignored-key id="C020E96222A31FB3" reason="Key couldn't be downloaded from any key server"/>
|
||||||
|
</ignored-keys>
|
||||||
<trusted-keys>
|
<trusted-keys>
|
||||||
<trusted-key id="02A36B6DB7056EB5E6FFEF893DA731F041734930" group="org.parceler"/>
|
<trusted-key id="02A36B6DB7056EB5E6FFEF893DA731F041734930" group="org.parceler"/>
|
||||||
<trusted-key id="03D5EBC6C81161316CF21CEE1592D9DA6586CF26" group="^com[.]afollestad($|([.].*))" regex="true"/>
|
<trusted-key id="03D5EBC6C81161316CF21CEE1592D9DA6586CF26" group="^com[.]afollestad($|([.].*))" regex="true"/>
|
||||||
@ -320,6 +327,58 @@
|
|||||||
</trusted-keys>
|
</trusted-keys>
|
||||||
</configuration>
|
</configuration>
|
||||||
<components>
|
<components>
|
||||||
|
<component group="org.unifiedpush.android" name="connector" version="3.0.7">
|
||||||
|
<artifact name="connector-3.0.7.aar">
|
||||||
|
<sha256 value="84b8edca39e4393985848acc1aa7530c6703b2851aae25d007cc7f45e20659c0" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="connector-3.0.7.module">
|
||||||
|
<sha256 value="2149687d8bc7d0a78295c0e03ba0157c6c58ce1f3804c16a1a2713f4fbbd7847" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="org.unifiedpush.android" name="connector-ui" version="1.1.0">
|
||||||
|
<artifact name="connector-ui-1.1.0.aar">
|
||||||
|
<sha256 value="154c8346344277a9ecd49ea7821a400f621a32f1099c94ca961c6eb8b611b093" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="connector-ui-1.1.0.module">
|
||||||
|
<sha256 value="bec6e094adc821624f8f52a7b8df0612c7d1423a7a838ec691b981160f8c8a7b" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="com.google.crypto.tink" name="tink" version="1.16.0">
|
||||||
|
<artifact name="tink-1.16.0.jar">
|
||||||
|
<sha256 value="7f5e380dde874cd44613952f374723da1f8636526c6a574945bceb0e65571d0a" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="tink-1.16.0.pom">
|
||||||
|
<sha256 value="28393661ae65329dcf782ffd7978b0a1ba0ad614577ee4b0bbb7bebdc4319673" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="com.google.protobuf" name="protobuf-parent" version="3.0.0">
|
||||||
|
<artifact name="protobuf-parent-3.0.0.pom">
|
||||||
|
<sha256 value="932e6bab9a24a7bc958bbdb7e29e04d083b473d11c4ba3fab1e9b7149579f272" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="com.google.protobuf" name="protobuf-java" version="3.19.3">
|
||||||
|
<artifact name="protobuf-java-3.19.3.pom">
|
||||||
|
<sha256 value="68f3a9cc44963e31083993c10a49ebeb1652d7ef63cf516fcaafcc32595f3a8e" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="com.google.protobuf" name="protobuf-bom" version="4.28.2">
|
||||||
|
<artifact name="protobuf-bom-4.28.2.pom">
|
||||||
|
<sha256 value="43666cd072728c646cc45a614aeeead1e0b23f818f652982df279a0e5adaf316" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="com.google.protobuf" name="protobuf-parent" version="4.28.2">
|
||||||
|
<artifact name="protobuf-parent-4.28.2.pom">
|
||||||
|
<sha256 value="f7f23fc16ed463cf52579fffafa03940e8e653b33c6b4f106082c5bf15050f75" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
|
<component group="com.google.protobuf" name="protobuf-java" version="4.28.2">
|
||||||
|
<artifact name="protobuf-java-4.28.2.jar">
|
||||||
|
<sha256 value="707bccf406f4fc61b841d4700daa8d3e84db8ab499ef3481a060fa6a0f06e627" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
<artifact name="protobuf-java-4.28.2.pom">
|
||||||
|
<sha256 value="1eaecce23fb47b1ae54996f16c0d5485563a972ec262b78a8180e07f0aa77253" origin="Generated by Gradle"/>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
<component group="androidx.activity" name="activity" version="1.0.0">
|
<component group="androidx.activity" name="activity" version="1.0.0">
|
||||||
<artifact name="activity-1.0.0.aar">
|
<artifact name="activity-1.0.0.aar">
|
||||||
<sha256 value="d1bc9842455c2e534415d88c44df4d52413b478db9093a1ba36324f705f44c3d" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
<sha256 value="d1bc9842455c2e534415d88c44df4d52413b478db9093a1ba36324f705f44c3d" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user