Skip to content

Commit

Permalink
rebind notification listener on companion pair
Browse files Browse the repository at this point in the history
  • Loading branch information
crc-32 committed Jun 20, 2024
1 parent 14b2f45 commit 8d5a701
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 44 deletions.
32 changes: 10 additions & 22 deletions android/app/src/main/kotlin/io/rebble/cobble/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.service.notification.NotificationListenerService
import android.text.TextUtils
import android.widget.Toast
import androidx.collection.ArrayMap
Expand All @@ -16,8 +17,10 @@ import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.rebble.cobble.bridges.FlutterBridge
import io.rebble.cobble.datasources.PermissionChangeBus
import io.rebble.cobble.notifications.NotificationListener
import io.rebble.cobble.service.CompanionDeviceService
import io.rebble.cobble.service.InCallService
import io.rebble.cobble.util.hasNotificationAccessPermission
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.plus
import java.net.URI
Expand Down Expand Up @@ -102,28 +105,6 @@ class MainActivity : FlutterActivity() {
}
}

private fun isNotificationServiceEnabled(): Boolean {
try {
val pkgName = packageName
val flat: String = Settings.Secure.getString(contentResolver,
"enabled_notification_listeners")
if (!TextUtils.isEmpty(flat)) {
val names = flat.split(":").toTypedArray()
for (i in names.indices) {
val cn = ComponentName.unflattenFromString(names[i])
if (cn != null) {
if (TextUtils.equals(pkgName, cn.packageName)) {
return true
}
}
}
}
} catch (e: NullPointerException) {
return false
}
return false
}

override fun onCreate(savedInstanceState: Bundle?) {
val injectionComponent = (applicationContext as CobbleApplication).component
val activityComponent = injectionComponent.createActivitySubcomponentFactory()
Expand Down Expand Up @@ -155,6 +136,13 @@ class MainActivity : FlutterActivity() {

val inCallServiceIntent = Intent(this, InCallService::class.java)
startService(inCallServiceIntent)


if (context.hasNotificationAccessPermission()) {
NotificationListenerService.requestRebind(
NotificationListener.getComponentName(context)
)
}
}

override fun onNewIntent(intent: Intent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.IntentSender
import android.os.Build
import android.service.notification.NotificationListenerService
import io.rebble.cobble.BuildConfig
import io.rebble.cobble.MainActivity
import io.rebble.cobble.bluetooth.ConnectionLooper
import io.rebble.cobble.bridges.FlutterBridge
import io.rebble.cobble.notifications.NotificationListener
import io.rebble.cobble.pigeons.Pigeons
import io.rebble.cobble.util.coroutines.asFlow
import io.rebble.cobble.util.hasNotificationAccessPermission
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -164,6 +167,13 @@ class ConnectionUiFlutterBridge @Inject constructor(
}
}

if (activity.context.hasNotificationAccessPermission()) {
Timber.d("Requesting rebind of notification listener")
NotificationListenerService.requestRebind(
NotificationListener.getComponentName(activity.context)
)
}

openConnectionToWatch(address)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@ class NotificationListener : NotificationListenerService() {

override fun onListenerConnected() {
isListening = true

unbindOnWatchDisconnect()

controlListenerHints()
observeNotificationToggle()
observeMutedPackages()
Expand Down Expand Up @@ -128,7 +125,7 @@ class NotificationListener : NotificationListenerService() {
}
}

GlobalScope.launch(Dispatchers.Main.immediate) {
coroutineScope.launch(Dispatchers.Main) {
var result: Pair<TimelineItem, BlobResponse.BlobStatus>? = notificationBridge.handleNotification(sbn.packageName, sbn.id.toLong(), tagId, title, text, sbn.notification.category
?: "", sbn.notification.color, messages ?: listOf(), actions)
?: return@launch
Expand Down Expand Up @@ -184,24 +181,6 @@ class NotificationListener : NotificationListenerService() {
}
}

@TargetApi(Build.VERSION_CODES.N)
private fun unbindOnWatchDisconnect() {
// It is a waste of resources to keep running notification listener in the background when
// watch disconnects.

// When watch disconnects, we call requestUnbind() to kill ourselves it and wait for
// ServiceLifecycleControl to starts up back up when watch reconnects.

coroutineScope.launch(Dispatchers.Main.immediate) {
connectionLooper.connectionState.drop(1).collect {
if (it is ConnectionState.Disconnected || it is ConnectionState.RecoveryMode) {
Timber.d("Connection state is $it, unbinding listener")
requestUnbind()
}
}
}
}

private fun controlListenerHints() {
coroutineScope.launch(Dispatchers.Main.immediate) {
combine(
Expand Down

0 comments on commit 8d5a701

Please sign in to comment.