diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml
index 5c27da044e..d13e40248f 100644
--- a/.idea/dictionaries/bmarty.xml
+++ b/.idea/dictionaries/bmarty.xml
@@ -29,6 +29,7 @@
signout
signup
ssss
+ sygnal
threepid
unwedging
diff --git a/CHANGES.md b/CHANGES.md
index 05d189ed12..e365768f86 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -16,6 +16,7 @@ Improvements 🙌:
- Drawer: move settings access and add sign out action (#2171)
- Filter room member (and banned users) by name (#2184)
- Implement "Jump to read receipt" and "Mention" actions on the room member profile screen
+ - Add Sygnal API implementation to test is Push are correctly received
Bugfix 🐛:
- Improve support for image/audio/video/file selection with intent changes (#1376)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt
index 0e33be400c..8284b50332 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt
@@ -66,6 +66,19 @@ interface PushersService {
append: Boolean,
withEventIdOnly: Boolean): UUID
+ /**
+ * Directly ask Sygnal to send a push to this device
+ * @param url the Sygnal url (full path)
+ * @param appId the application id
+ * @param pushkey the FCM token
+ * @param callback callback to know if Sygnal has accepted the request. In this case, the app should receive a Push with the provided data (TODO)
+ *
+ */
+ fun testPush(url: String,
+ appId: String,
+ pushkey: String,
+ callback: MatrixCallback)
+
/**
* Remove the http pusher
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
index 1154d1967c..0dfdec1804 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
@@ -17,7 +17,7 @@
package org.matrix.android.sdk.internal.network
internal object NetworkConstants {
-
+ // Homeserver
private const val URI_API_PREFIX_PATH = "_matrix/client"
const val URI_API_PREFIX_PATH_ = "$URI_API_PREFIX_PATH/"
const val URI_API_PREFIX_PATH_R0 = "$URI_API_PREFIX_PATH/r0/"
@@ -31,5 +31,9 @@ internal object NetworkConstants {
const val URI_IDENTITY_PREFIX_PATH = "_matrix/identity/v2"
const val URI_IDENTITY_PATH_V2 = "$URI_IDENTITY_PREFIX_PATH/"
+ // Sygnal
+ const val URI_SYGNAL_PREFIX_PATH = "_matrix/push/v1/"
+
+ // Integration
const val URI_INTEGRATION_MANAGER_PATH = "_matrix/integrations/v1/"
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt
index 8f80ac46e4..c7d5e1f8b8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt
@@ -28,6 +28,7 @@ import org.matrix.android.sdk.internal.database.query.where
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.di.SessionId
import org.matrix.android.sdk.internal.di.WorkManagerProvider
+import org.matrix.android.sdk.internal.session.pushers.sygnal.SygnalNotifyTask
import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.task.configureWith
import org.matrix.android.sdk.internal.worker.WorkerParamsFactory
@@ -41,10 +42,22 @@ internal class DefaultPushersService @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
@SessionId private val sessionId: String,
private val getPusherTask: GetPushersTask,
+ private val sygnalNotifyTask: SygnalNotifyTask,
private val removePusherTask: RemovePusherTask,
private val taskExecutor: TaskExecutor
) : PushersService {
+ override fun testPush(url: String,
+ appId: String,
+ pushkey: String,
+ callback: MatrixCallback) {
+ sygnalNotifyTask
+ .configureWith(SygnalNotifyTask.Params(url, appId, pushkey)) {
+ this.callback = callback
+ }
+ .executeBy(taskExecutor)
+ }
+
override fun refreshPushers() {
getPusherTask
.configureWith()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt
index a6042b27a2..5810f26c85 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt
@@ -25,6 +25,8 @@ import org.matrix.android.sdk.api.session.pushers.PushersService
import org.matrix.android.sdk.internal.session.notification.DefaultProcessEventForPushTask
import org.matrix.android.sdk.internal.session.notification.DefaultPushRuleService
import org.matrix.android.sdk.internal.session.notification.ProcessEventForPushTask
+import org.matrix.android.sdk.internal.session.pushers.sygnal.DefaultSygnalNotifyTask
+import org.matrix.android.sdk.internal.session.pushers.sygnal.SygnalNotifyTask
import org.matrix.android.sdk.internal.session.room.notification.DefaultSetRoomNotificationStateTask
import org.matrix.android.sdk.internal.session.room.notification.SetRoomNotificationStateTask
import retrofit2.Retrofit
@@ -86,4 +88,7 @@ internal abstract class PushersModule {
@Binds
abstract fun bindProcessEventForPushTask(task: DefaultProcessEventForPushTask): ProcessEventForPushTask
+
+ @Binds
+ abstract fun bindSygnalNotifyTask(task: DefaultSygnalNotifyTask): SygnalNotifyTask
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalAPI.kt
new file mode 100644
index 0000000000..7550e14a97
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalAPI.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.matrix.android.sdk.internal.session.pushers.sygnal
+
+import org.matrix.android.sdk.internal.network.NetworkConstants
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+internal interface SygnalAPI {
+ /**
+ * Ask Sygnal to send a push to the current device.
+ *
+ * Ref: https://matrix.org/docs/spec/push_gateway/r0.1.1#post-matrix-push-v1-notify
+ */
+ @POST(NetworkConstants.URI_SYGNAL_PREFIX_PATH + "notify")
+ fun notify(@Body body: SygnalNotifyBody): Call
+}
+
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalDevice.kt
new file mode 100644
index 0000000000..a5cfe389cc
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalDevice.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.pushers.sygnal
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class SygnalDevice(
+ /**
+ * Required. The app_id given when the pusher was created.
+ */
+ @Json(name = "app_id")
+ val appId: String,
+ /**
+ * Required. The pushkey given when the pusher was created.
+ */
+ @Json(name = "pushkey")
+ val pushKey: String
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotification.kt
new file mode 100644
index 0000000000..b28449a481
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotification.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.pushers.sygnal
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class SygnalNotification(
+ /**
+ * Required. This is an array of devices that the notification should be sent to.
+ */
+ @Json(name = "devices")
+ val devices: List
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyBody.kt
new file mode 100644
index 0000000000..7b13d8ff79
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyBody.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.pushers.sygnal
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class SygnalNotifyBody(
+ /**
+ * Required. Information about the push notification
+ */
+ @Json(name = "notification")
+ val notification: SygnalNotification
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyResponse.kt
new file mode 100644
index 0000000000..73d5aa1e2c
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyResponse.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.internal.session.pushers.sygnal
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+@JsonClass(generateAdapter = true)
+internal data class SygnalNotifyResponse(
+ @Json(name = "rejected")
+ val rejectedPushKey: List
+)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyTask.kt
new file mode 100644
index 0000000000..eb3cd433a9
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/sygnal/SygnalNotifyTask.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.matrix.android.sdk.internal.session.pushers.sygnal
+
+import okhttp3.OkHttpClient
+import org.matrix.android.sdk.internal.di.Unauthenticated
+import org.matrix.android.sdk.internal.network.NetworkConstants
+import org.matrix.android.sdk.internal.network.RetrofitFactory
+import org.matrix.android.sdk.internal.network.executeRequest
+import org.matrix.android.sdk.internal.task.Task
+import javax.inject.Inject
+
+internal interface SygnalNotifyTask : Task {
+ data class Params(
+ val url: String,
+ val appId: String,
+ val pushKey: String
+ )
+}
+
+internal class DefaultSygnalNotifyTask @Inject constructor(
+ private val retrofitFactory: RetrofitFactory,
+ @Unauthenticated private val unauthenticatedOkHttpClient: OkHttpClient
+) : SygnalNotifyTask {
+
+ override suspend fun execute(params: SygnalNotifyTask.Params) {
+ val sygnalApi = retrofitFactory.create(
+ unauthenticatedOkHttpClient,
+ params.url.substringBefore(NetworkConstants.URI_SYGNAL_PREFIX_PATH)
+ )
+ .create(SygnalAPI::class.java)
+
+ val response = executeRequest(null) {
+ apiCall = sygnalApi.notify(
+ SygnalNotifyBody(
+ SygnalNotification(
+ devices = listOf(
+ SygnalDevice(
+ params.appId,
+ params.pushKey
+ )
+ )
+ )
+ )
+ )
+ }
+
+ if (response.rejectedPushKey.contains(params.pushKey)) {
+ throw IllegalStateException("Failure")
+ }
+ }
+}
diff --git a/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromSygnal.kt b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromSygnal.kt
new file mode 100644
index 0000000000..b291b750b4
--- /dev/null
+++ b/vector/src/gplay/java/im/vector/app/gplay/features/settings/troubleshoot/TestPushFromSygnal.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package im.vector.app.gplay.features.settings.troubleshoot
+
+import androidx.appcompat.app.AppCompatActivity
+import im.vector.app.R
+import im.vector.app.core.pushers.PushersManager
+import im.vector.app.core.resources.StringProvider
+import im.vector.app.features.settings.troubleshoot.TroubleshootTest
+import im.vector.app.push.fcm.FcmHelper
+import org.matrix.android.sdk.api.MatrixCallback
+import javax.inject.Inject
+
+/**
+ * Test Push by asking Sygnal to send a Push back
+ */
+class TestPushFromSygnal @Inject constructor(private val context: AppCompatActivity,
+ private val stringProvider: StringProvider,
+ private val pushersManager: PushersManager)
+ : TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) {
+
+ override fun perform() {
+ val fcmToken = FcmHelper.getFcmToken(context) ?: run {
+ status = TestStatus.FAILED
+ return
+ }
+ pushersManager.testPush(fcmToken, object : MatrixCallback {
+ override fun onFailure(failure: Throwable) {
+ description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_failed)
+ status = TestStatus.FAILED
+ }
+
+ override fun onSuccess(data: Unit) {
+ description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_success)
+ status = TestStatus.SUCCESS
+ }
+ })
+ }
+}
diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/NotificationTroubleshootTestManagerFactory.kt b/vector/src/gplay/java/im/vector/app/push/fcm/NotificationTroubleshootTestManagerFactory.kt
index b2dad09483..06d3283afa 100644
--- a/vector/src/gplay/java/im/vector/app/push/fcm/NotificationTroubleshootTestManagerFactory.kt
+++ b/vector/src/gplay/java/im/vector/app/push/fcm/NotificationTroubleshootTestManagerFactory.kt
@@ -23,16 +23,20 @@ import im.vector.app.features.settings.troubleshoot.TestPushRulesSettings
import im.vector.app.features.settings.troubleshoot.TestSystemSettings
import im.vector.app.gplay.features.settings.troubleshoot.TestFirebaseToken
import im.vector.app.gplay.features.settings.troubleshoot.TestPlayServices
+import im.vector.app.gplay.features.settings.troubleshoot.TestPushFromSygnal
import im.vector.app.gplay.features.settings.troubleshoot.TestTokenRegistration
import javax.inject.Inject
-class NotificationTroubleshootTestManagerFactory @Inject constructor(private val testSystemSettings: TestSystemSettings,
- private val testAccountSettings: TestAccountSettings,
- private val testDeviceSettings: TestDeviceSettings,
- private val testBingRulesSettings: TestPushRulesSettings,
- private val testPlayServices: TestPlayServices,
- private val testFirebaseToken: TestFirebaseToken,
- private val testTokenRegistration: TestTokenRegistration) {
+class NotificationTroubleshootTestManagerFactory @Inject constructor(
+ private val testSystemSettings: TestSystemSettings,
+ private val testAccountSettings: TestAccountSettings,
+ private val testDeviceSettings: TestDeviceSettings,
+ private val testBingRulesSettings: TestPushRulesSettings,
+ private val testPlayServices: TestPlayServices,
+ private val testFirebaseToken: TestFirebaseToken,
+ private val testTokenRegistration: TestTokenRegistration,
+ private val testPushFromSygnal: TestPushFromSygnal
+) {
fun create(fragment: Fragment): NotificationTroubleshootTestManager {
val mgr = NotificationTroubleshootTestManager(fragment)
@@ -43,6 +47,7 @@ class NotificationTroubleshootTestManagerFactory @Inject constructor(private val
mgr.addTest(testPlayServices)
mgr.addTest(testFirebaseToken)
mgr.addTest(testTokenRegistration)
+ mgr.addTest(testPushFromSygnal)
return mgr
}
}
diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt
index f0d27182e7..e86ff104b7 100644
--- a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt
+++ b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt
@@ -34,6 +34,16 @@ class PushersManager @Inject constructor(
private val stringProvider: StringProvider,
private val appNameProvider: AppNameProvider
) {
+ fun testPush(pushKey: String, callback: MatrixCallback) {
+ val currentSession = activeSessionHolder.getActiveSession()
+
+ currentSession.testPush(
+ stringProvider.getString(R.string.pusher_http_url),
+ stringProvider.getString(R.string.pusher_app_id),
+ pushKey,
+ callback
+ )
+ }
fun registerPusherWithFcmKey(pushKey: String): UUID {
val currentSession = activeSessionHolder.getActiveSession()
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index d48162de29..be83a6dc50 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -749,6 +749,10 @@
FCM token successfully registered to HomeServer.
Failed to register FCM token to HomeServer:\n%1$s
+ Test Push
+ The application is receiving PUSH, you should see a notification.
+ Failed to receive push. Solution could be to reinstall the application.
+
Notifications Service
Notifications Service is running.
Notifications Service is not running.\nTry to restart the application.