Skip to content

Commit b8385af

Browse files
authored
refactor(android): drop the two call callbacks Android never delivers (#368)
The calling plugin offered two events that only an iPhone can produce: continuing a call started from the system's own recents or voice assistant, and the reset the system sends when it drops every call it was tracking. On Android nothing has ever raised either of them, yet both looked like part of the shared contract, inviting Android logic that could never run. Both are now removed from the Android side and marked as iOS-only in the shared interface and the documentation, so the contract says what actually happens. The version of the tool that produces the generated message files is pinned alongside, so those files stay stable.
1 parent 3a8bd5e commit b8385af

11 files changed

Lines changed: 23 additions & 134 deletions

File tree

AGENTS.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ WebtritCallkeepPlatform (platform_interface)
9898

9999
**Platform to Flutter** (via `CallkeepDelegate`): `performStartCall`, `performAnswerCall`, `performEndCall`,
100100
`performSetHeld`, `performSetMuted`, `performSendDTMF`, `performAudioDeviceSet`, `performAudioDevicesUpdate`,
101-
`didActivateAudioSession`, `didDeactivateAudioSession`, `didReset`, `continueStartCallIntent`, `didPushIncomingCall`.
101+
`didActivateAudioSession`, `didDeactivateAudioSession`, `didPushIncomingCall`.
102+
103+
`didReset` and `continueStartCallIntent` are declared on `CallkeepDelegate` but are delivered by iOS only:
104+
the Android side has no source for either event, so they are absent from the Android pigeon surface.
102105

103106
`perform*` methods return `Future<bool>` — return `true` on success, `false` on failure.
104107
Returning `false` causes the native side to abort the operation.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,14 @@ Implement `CallkeepDelegate` and pass it to `setDelegate` to receive platform ev
150150
| `performAnswerCall(callId)` | User answered from system UI |
151151
| `performEndCall(callId)` | User ended from system UI or system terminated the call |
152152
| `performStartCall(callId, handle, ...)` | User initiated outgoing call from system UI (e.g. Siri) |
153-
| `continueStartCallIntent(callId, handle, ...)` | System confirmed outgoing call intent |
153+
| `continueStartCallIntent(callId, handle, ...)` | System confirmed outgoing call intent (iOS only) |
154154
| `performSetHeld(callId, onHold)` | User toggled hold from system UI |
155155
| `performSetMuted(callId, muted)` | User toggled mute from system UI |
156156
| `performSendDTMF(callId, digit)` | User sent DTMF from system dial pad |
157157
| `performSetSpeaker(callId, on)` | User toggled speaker from system UI |
158158
| `didActivateAudioSession()` | System activated the audio session |
159159
| `didDeactivateAudioSession()` | System deactivated the audio session |
160-
| `didReset()` | System reset all call state |
160+
| `didReset()` | System reset all call state (iOS only) |
161161

162162
`perform*` methods return `Future<bool>`. Return `false` to signal failure — the platform will
163163
terminate the call.

webtrit_callkeep_android/android/src/main/kotlin/com/webtrit/callkeep/Generated.kt

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,23 +2296,6 @@ class PDelegateFlutterApi(private val binaryMessenger: BinaryMessenger, private
22962296
GeneratedPigeonCodec()
22972297
}
22982298
}
2299-
fun continueStartCallIntent(handleArg: PHandle, displayNameArg: String?, videoArg: Boolean, callback: (Result<Unit>) -> Unit)
2300-
{
2301-
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
2302-
val channelName = "dev.flutter.pigeon.webtrit_callkeep_android.PDelegateFlutterApi.continueStartCallIntent$separatedMessageChannelSuffix"
2303-
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
2304-
channel.send(listOf(handleArg, displayNameArg, videoArg)) {
2305-
if (it is List<*>) {
2306-
if (it.size > 1) {
2307-
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
2308-
} else {
2309-
callback(Result.success(Unit))
2310-
}
2311-
} else {
2312-
callback(Result.failure(GeneratedPigeonUtils.createConnectionError(channelName)))
2313-
}
2314-
}
2315-
}
23162299
fun didPushIncomingCall(handleArg: PHandle, displayNameArg: String?, videoArg: Boolean, callIdArg: String, errorArg: PIncomingCallError?, callback: (Result<Unit>) -> Unit)
23172300
{
23182301
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
@@ -2524,23 +2507,6 @@ class PDelegateFlutterApi(private val binaryMessenger: BinaryMessenger, private
25242507
}
25252508
}
25262509
}
2527-
fun didReset(callback: (Result<Unit>) -> Unit)
2528-
{
2529-
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
2530-
val channelName = "dev.flutter.pigeon.webtrit_callkeep_android.PDelegateFlutterApi.didReset$separatedMessageChannelSuffix"
2531-
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
2532-
channel.send(null) {
2533-
if (it is List<*>) {
2534-
if (it.size > 1) {
2535-
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
2536-
} else {
2537-
callback(Result.success(Unit))
2538-
}
2539-
} else {
2540-
callback(Result.failure(GeneratedPigeonUtils.createConnectionError(channelName)))
2541-
}
2542-
}
2543-
}
25442510
}
25452511
/** Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */
25462512
class PDelegateBackgroundServiceFlutterApi(private val binaryMessenger: BinaryMessenger, private val messageChannelSuffix: String = "") {

webtrit_callkeep_android/lib/src/common/callkeep.pigeon.dart

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,8 +2100,6 @@ class PHostConnectionsApi {
21002100
abstract class PDelegateFlutterApi {
21012101
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
21022102

2103-
void continueStartCallIntent(PHandle handle, String? displayName, bool video);
2104-
21052103
void didPushIncomingCall(PHandle handle, String? displayName, bool video, String callId, PIncomingCallError? error);
21062104

21072105
Future<bool> performStartCall(String callId, PHandle handle, String? displayNameOrContactIdentifier, bool video);
@@ -2124,33 +2122,8 @@ abstract class PDelegateFlutterApi {
21242122

21252123
void didDeactivateAudioSession();
21262124

2127-
void didReset();
2128-
21292125
static void setUp(PDelegateFlutterApi? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
21302126
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
2131-
{
2132-
final pigeonVar_channel = BasicMessageChannel<Object?>(
2133-
'dev.flutter.pigeon.webtrit_callkeep_android.PDelegateFlutterApi.continueStartCallIntent$messageChannelSuffix', pigeonChannelCodec,
2134-
binaryMessenger: binaryMessenger);
2135-
if (api == null) {
2136-
pigeonVar_channel.setMessageHandler(null);
2137-
} else {
2138-
pigeonVar_channel.setMessageHandler((Object? message) async {
2139-
final List<Object?> args = message! as List<Object?>;
2140-
final PHandle arg_handle = args[0]! as PHandle;
2141-
final String? arg_displayName = args[1] as String?;
2142-
final bool arg_video = args[2]! as bool;
2143-
try {
2144-
api.continueStartCallIntent(arg_handle, arg_displayName, arg_video);
2145-
return wrapResponse(empty: true);
2146-
} on PlatformException catch (e) {
2147-
return wrapResponse(error: e);
2148-
} catch (e) {
2149-
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
2150-
}
2151-
});
2152-
}
2153-
}
21542127
{
21552128
final pigeonVar_channel = BasicMessageChannel<Object?>(
21562129
'dev.flutter.pigeon.webtrit_callkeep_android.PDelegateFlutterApi.didPushIncomingCall$messageChannelSuffix', pigeonChannelCodec,
@@ -2390,25 +2363,6 @@ abstract class PDelegateFlutterApi {
23902363
});
23912364
}
23922365
}
2393-
{
2394-
final pigeonVar_channel = BasicMessageChannel<Object?>(
2395-
'dev.flutter.pigeon.webtrit_callkeep_android.PDelegateFlutterApi.didReset$messageChannelSuffix', pigeonChannelCodec,
2396-
binaryMessenger: binaryMessenger);
2397-
if (api == null) {
2398-
pigeonVar_channel.setMessageHandler(null);
2399-
} else {
2400-
pigeonVar_channel.setMessageHandler((Object? message) async {
2401-
try {
2402-
api.didReset();
2403-
return wrapResponse(empty: true);
2404-
} on PlatformException catch (e) {
2405-
return wrapResponse(error: e);
2406-
} catch (e) {
2407-
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
2408-
}
2409-
});
2410-
}
2411-
}
24122366
}
24132367
}
24142368

webtrit_callkeep_android/lib/src/webtrit_callkeep_android.dart

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,6 @@ class _CallkeepDelegateRelay implements PDelegateFlutterApi {
390390

391391
final CallkeepDelegate _delegate;
392392

393-
@override
394-
void continueStartCallIntent(PHandle handle, String? displayName, bool video) {
395-
_delegate.continueStartCallIntent(handle.toCallkeep(), displayName, video);
396-
}
397-
398393
@override
399394
void didPushIncomingCall(PHandle handle, String? displayName, bool video, String callId, PIncomingCallError? error) {
400395
_delegate.didPushIncomingCall(handle.toCallkeep(), displayName, video, callId, error?.value.toCallkeep());
@@ -465,11 +460,6 @@ class _CallkeepDelegateRelay implements PDelegateFlutterApi {
465460
void didDeactivateAudioSession() {
466461
_delegate.didDeactivateAudioSession();
467462
}
468-
469-
@override
470-
void didReset() {
471-
_delegate.didReset();
472-
}
473463
}
474464

475465
class _PushRegistryDelegateRelay implements PPushRegistryDelegateFlutterApi {

webtrit_callkeep_android/pigeons/callkeep.messages.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,6 @@ abstract class PHostConnectionsApi {
427427

428428
@FlutterApi()
429429
abstract class PDelegateFlutterApi {
430-
@ObjCSelector('continueStartCallIntentHandle:displayName:video:')
431-
void continueStartCallIntent(PHandle handle, String? displayName, bool video);
432-
433430
@ObjCSelector('didPushIncomingCallHandle:displayName:video:id:error:')
434431
void didPushIncomingCall(PHandle handle, String? displayName, bool video, String callId, PIncomingCallError? error);
435432

@@ -470,9 +467,6 @@ abstract class PDelegateFlutterApi {
470467

471468
@ObjCSelector('didDeactivateAudioSession')
472469
void didDeactivateAudioSession();
473-
474-
@ObjCSelector('didReset')
475-
void didReset();
476470
}
477471

478472
@FlutterApi()

webtrit_callkeep_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ dependencies:
2424
dev_dependencies:
2525
flutter_test:
2626
sdk: flutter
27-
pigeon: ^27.0.0
27+
pigeon: 27.1.0
2828
plugin_platform_interface: ^2.1.8
2929
flutter_lints: ^6.0.0

webtrit_callkeep_android/test/delegate_relay_test.dart

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -182,30 +182,6 @@ void main() {
182182
expect(() => WebtritCallkeepPlatform.instance.setDelegate(null), returnsNormally);
183183
});
184184

185-
test('continueStartCallIntent forwards converted handle and args', () async {
186-
await _send('$_prefix.PDelegateFlutterApi.continueStartCallIntent', [
187-
PHandle(type: PHandleTypeEnum.number, value: '+1234'),
188-
'Alice',
189-
true,
190-
]);
191-
expect(fake.calls['continueStartCallIntent'], hasLength(1));
192-
final args = fake.calls['continueStartCallIntent']![0];
193-
expect((args[0] as CallkeepHandle).type, CallkeepHandleType.number);
194-
expect((args[0] as CallkeepHandle).value, '+1234');
195-
expect(args[1], 'Alice');
196-
expect(args[2], true);
197-
});
198-
199-
test('continueStartCallIntent forwards null displayName', () async {
200-
await _send('$_prefix.PDelegateFlutterApi.continueStartCallIntent', [
201-
PHandle(type: PHandleTypeEnum.email, value: 'a@b.com'),
202-
null,
203-
false,
204-
]);
205-
final args = fake.calls['continueStartCallIntent']![0];
206-
expect(args[1], isNull);
207-
});
208-
209185
test('didPushIncomingCall with null error forwards null error', () async {
210186
await _send('$_prefix.PDelegateFlutterApi.didPushIncomingCall', [
211187
PHandle(type: PHandleTypeEnum.number, value: '555'),
@@ -325,11 +301,6 @@ void main() {
325301
await _send('$_prefix.PDelegateFlutterApi.didDeactivateAudioSession', []);
326302
expect(fake.calls['didDeactivateAudioSession'], hasLength(1));
327303
});
328-
329-
test('didReset calls delegate', () async {
330-
await _send('$_prefix.PDelegateFlutterApi.didReset', []);
331-
expect(fake.calls['didReset'], hasLength(1));
332-
});
333304
});
334305

335306
// ---------------------------------------------------------------------------

webtrit_callkeep_ios/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ dependencies:
2424
dev_dependencies:
2525
flutter_test:
2626
sdk: flutter
27-
pigeon: ^27.0.0
27+
pigeon: 27.1.0
2828
plugin_platform_interface: ^2.1.8
2929
flutter_lints: ^6.0.0

webtrit_callkeep_platform_interface/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,14 @@ CallkeepHandle.sip('user@example.com')
7070
| `performAnswerCall` | User answered from system UI |
7171
| `performEndCall` | User ended from system UI or system terminated the call |
7272
| `performStartCall` | User initiated outgoing call from system UI |
73-
| `continueStartCallIntent` | System confirmed outgoing call intent |
73+
| `continueStartCallIntent` | System confirmed outgoing call intent (iOS only) |
7474
| `performSetHeld` | Hold toggled from system UI |
7575
| `performSetMuted` | Mute toggled from system UI |
7676
| `performSendDTMF` | DTMF sent from system dial pad |
7777
| `performSetSpeaker` | Speaker toggled from system UI |
7878
| `didActivateAudioSession` | System activated the audio session |
7979
| `didDeactivateAudioSession` | System deactivated the audio session |
80-
| `didReset` | System reset all call state |
80+
| `didReset` | System reset all call state (iOS only) |
8181

8282
`perform*` methods return `Future<bool>`. Return `false` to signal failure — the platform
8383
terminates the call.

0 commit comments

Comments
 (0)