Skip to content

Commit 8d5a701

Browse files
committed
rebind notification listener on companion pair
1 parent 14b2f45 commit 8d5a701

File tree

3 files changed

+21
-44
lines changed

3 files changed

+21
-44
lines changed

android/app/src/main/kotlin/io/rebble/cobble/MainActivity.kt

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import android.content.Intent
88
import android.os.Build
99
import android.os.Bundle
1010
import android.provider.Settings
11+
import android.service.notification.NotificationListenerService
1112
import android.text.TextUtils
1213
import android.widget.Toast
1314
import androidx.collection.ArrayMap
@@ -16,8 +17,10 @@ import io.flutter.embedding.android.FlutterActivity
1617
import io.flutter.embedding.engine.FlutterEngine
1718
import io.rebble.cobble.bridges.FlutterBridge
1819
import io.rebble.cobble.datasources.PermissionChangeBus
20+
import io.rebble.cobble.notifications.NotificationListener
1921
import io.rebble.cobble.service.CompanionDeviceService
2022
import io.rebble.cobble.service.InCallService
23+
import io.rebble.cobble.util.hasNotificationAccessPermission
2124
import kotlinx.coroutines.CoroutineScope
2225
import kotlinx.coroutines.plus
2326
import java.net.URI
@@ -102,28 +105,6 @@ class MainActivity : FlutterActivity() {
102105
}
103106
}
104107

105-
private fun isNotificationServiceEnabled(): Boolean {
106-
try {
107-
val pkgName = packageName
108-
val flat: String = Settings.Secure.getString(contentResolver,
109-
"enabled_notification_listeners")
110-
if (!TextUtils.isEmpty(flat)) {
111-
val names = flat.split(":").toTypedArray()
112-
for (i in names.indices) {
113-
val cn = ComponentName.unflattenFromString(names[i])
114-
if (cn != null) {
115-
if (TextUtils.equals(pkgName, cn.packageName)) {
116-
return true
117-
}
118-
}
119-
}
120-
}
121-
} catch (e: NullPointerException) {
122-
return false
123-
}
124-
return false
125-
}
126-
127108
override fun onCreate(savedInstanceState: Bundle?) {
128109
val injectionComponent = (applicationContext as CobbleApplication).component
129110
val activityComponent = injectionComponent.createActivitySubcomponentFactory()
@@ -155,6 +136,13 @@ class MainActivity : FlutterActivity() {
155136

156137
val inCallServiceIntent = Intent(this, InCallService::class.java)
157138
startService(inCallServiceIntent)
139+
140+
141+
if (context.hasNotificationAccessPermission()) {
142+
NotificationListenerService.requestRebind(
143+
NotificationListener.getComponentName(context)
144+
)
145+
}
158146
}
159147

160148
override fun onNewIntent(intent: Intent) {

android/app/src/main/kotlin/io/rebble/cobble/bridges/ui/ConnectionUiFlutterBridge.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@ import android.content.Intent
1515
import android.content.IntentFilter
1616
import android.content.IntentSender
1717
import android.os.Build
18+
import android.service.notification.NotificationListenerService
1819
import io.rebble.cobble.BuildConfig
1920
import io.rebble.cobble.MainActivity
2021
import io.rebble.cobble.bluetooth.ConnectionLooper
2122
import io.rebble.cobble.bridges.FlutterBridge
23+
import io.rebble.cobble.notifications.NotificationListener
2224
import io.rebble.cobble.pigeons.Pigeons
2325
import io.rebble.cobble.util.coroutines.asFlow
26+
import io.rebble.cobble.util.hasNotificationAccessPermission
2427
import kotlinx.coroutines.CoroutineScope
2528
import kotlinx.coroutines.ExperimentalCoroutinesApi
2629
import kotlinx.coroutines.launch
@@ -164,6 +167,13 @@ class ConnectionUiFlutterBridge @Inject constructor(
164167
}
165168
}
166169

170+
if (activity.context.hasNotificationAccessPermission()) {
171+
Timber.d("Requesting rebind of notification listener")
172+
NotificationListenerService.requestRebind(
173+
NotificationListener.getComponentName(activity.context)
174+
)
175+
}
176+
167177
openConnectionToWatch(address)
168178
}
169179

android/app/src/main/kotlin/io/rebble/cobble/notifications/NotificationListener.kt

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ class NotificationListener : NotificationListenerService() {
6363

6464
override fun onListenerConnected() {
6565
isListening = true
66-
67-
unbindOnWatchDisconnect()
68-
6966
controlListenerHints()
7067
observeNotificationToggle()
7168
observeMutedPackages()
@@ -128,7 +125,7 @@ class NotificationListener : NotificationListenerService() {
128125
}
129126
}
130127

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

187-
@TargetApi(Build.VERSION_CODES.N)
188-
private fun unbindOnWatchDisconnect() {
189-
// It is a waste of resources to keep running notification listener in the background when
190-
// watch disconnects.
191-
192-
// When watch disconnects, we call requestUnbind() to kill ourselves it and wait for
193-
// ServiceLifecycleControl to starts up back up when watch reconnects.
194-
195-
coroutineScope.launch(Dispatchers.Main.immediate) {
196-
connectionLooper.connectionState.drop(1).collect {
197-
if (it is ConnectionState.Disconnected || it is ConnectionState.RecoveryMode) {
198-
Timber.d("Connection state is $it, unbinding listener")
199-
requestUnbind()
200-
}
201-
}
202-
}
203-
}
204-
205184
private fun controlListenerHints() {
206185
coroutineScope.launch(Dispatchers.Main.immediate) {
207186
combine(

0 commit comments

Comments
 (0)