Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions ci/android/src/androidTest/kotlin/rs/pushups/ci/PushupsTest.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package rs.pushups.ci

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.ParcelFileDescriptor
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
Expand All @@ -26,6 +30,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import java.util.UUID
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import rs.pushups.PushupsMessagingService

Expand All @@ -50,9 +55,37 @@ class PushupsTest {
@BeforeClass
@JvmStatic
fun fetchToken() {
leaveStoppedState()
token = Tasks.await(FirebaseMessaging.getInstance().token, 120, TimeUnit.SECONDS)
}

/**
* Takes the package out of the stopped state `am instrument` leaves it in, where FCM holds
* its pushes until an Activity starts, through a broadcast to a manifest receiver, which
* creates no Activity, so the first push still finds a process that never had one.
*/
private fun leaveStoppedState() {
val delivered = CountDownLatch(1)
context.sendOrderedBroadcast(
Intent().setComponent(ComponentName(context, UnstoppedReceiver::class.java)),
null,
object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) = delivered.countDown()
},
null,
Activity.RESULT_OK,
null,
null,
)
check(delivered.await(30, TimeUnit.SECONDS)) { "the receiver got no broadcast within 30 s" }
val state = instrumentation.uiAutomation
.executeShellCommand("dumpsys package ${context.packageName}")
.let { descriptor ->
ParcelFileDescriptor.AutoCloseInputStream(descriptor).bufferedReader().use { it.readText() }
}
check(" stopped=false" in state) { "the package is still stopped:\n$state" }
}

@AfterClass
@JvmStatic
fun finish() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package rs.pushups.ci

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent

/**
* The target of an explicit broadcast that takes the package out of the stopped state
* `am instrument` leaves it in, since delivering to a manifest receiver clears that state
* without creating an Activity.
*/
class UnstoppedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<!-- Takes the package out of the stopped state `am instrument` leaves it in. -->
<receiver
android:name="rs.pushups.ci.UnstoppedReceiver"
android:exported="false" />
</application>
</manifest>