diff --git a/README.md b/README.md index bdbf4389..c6cf41cf 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,25 @@ The `taskRemovedBehavior` parameter of navigation session initialization defines This parameter has only an effect on Android. +#### Android navigation notification + +Configure the built-in Android navigation notification when creating the first +navigation session. The options are ignored on iOS. + +```dart +await GoogleMapsNavigator.initializeNavigationSession( + notificationOptions: const NavigationNotificationOptions( + notificationId: 1234, + defaultMessage: 'Navigation is active', + resumeAppOnTap: true, + ), +); +``` + +`resumeAppOnTap` makes a notification tap launch or resume the application. +These options retain the Navigation SDK's turn-by-turn notification content; +custom notification layouts are not supported. + ### Add a map view ```dart diff --git a/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionManager.kt b/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionManager.kt index f4bda770..52736d74 100644 --- a/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionManager.kt +++ b/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionManager.kt @@ -18,6 +18,7 @@ package com.google.maps.flutter.navigation import android.app.Activity import android.app.Application +import android.content.Intent import android.content.res.Resources import android.location.Location import androidx.lifecycle.DefaultLifecycleObserver @@ -61,6 +62,7 @@ constructor( ) : DefaultLifecycleObserver { companion object { var navigationReadyListener: NavigationReadyListener? = null + private var foregroundServiceManagerInitialized = false } private var arrivalListener: Navigator.ArrivalListener? = null @@ -131,6 +133,7 @@ constructor( fun createNavigationSession( abnormalTerminationReportingEnabled: Boolean, behavior: TaskRemovedBehaviorDto, + notificationOptions: NavigationNotificationOptionsDto?, callback: (Result) -> Unit, ) { val currentState = GoogleMapsNavigatorHolder.getInitializationState() @@ -178,6 +181,13 @@ constructor( return } + try { + initializeForegroundServiceManager(notificationOptions) + } catch (error: Throwable) { + callback(Result.failure(error)) + return + } + // Enable or disable abnormal termination reporting. NavigationApi.setAbnormalTerminationReportingEnabled(abnormalTerminationReportingEnabled) @@ -288,6 +298,7 @@ constructor( // As unregisterListeners() is removing all listeners, we need to re-register them when // navigator is re-initialized. This is done in createNavigationSession() method. GoogleMapsNavigatorHolder.reset() + clearForegroundServiceManager() navigationReadyListener?.onNavigationReady(false) } } @@ -417,6 +428,46 @@ constructor( } } + private fun initializeForegroundServiceManager(options: NavigationNotificationOptionsDto?) { + if (options == null || foregroundServiceManagerInitialized) return + + val androidNotificationId = + options.notificationId?.let { + if (it !in Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong()) { + throw FlutterError( + "invalidNotificationId", + "notificationId must fit in a 32-bit integer.", + ) + } + it.toInt() + } + + val resumeIntent = + if (options.resumeAppOnTap) { + application.packageManager + .getLaunchIntentForPackage(application.packageName) + ?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) + } else { + null + } + + // This must happen before NavigationApi.getNavigator() + NavigationApi.initForegroundServiceManagerMessageAndIntent( + application, + androidNotificationId, + options.defaultMessage, + resumeIntent, + ) + foregroundServiceManagerInitialized = true + } + + private fun clearForegroundServiceManager() { + if (foregroundServiceManagerInitialized) { + NavigationApi.clearForegroundServiceManager() + foregroundServiceManagerInitialized = false + } + } + /** * Wraps [Navigator.startGuidance]. See * [Google Navigation SDK for Android](https://developers.google.com/maps/documentation/navigation/android-sdk/reference/com/google/android/libraries/navigation/Navigator#startGuidance()). diff --git a/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionMessageHandler.kt b/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionMessageHandler.kt index 5cbaed13..cb1d882a 100644 --- a/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionMessageHandler.kt +++ b/android/src/main/kotlin/com/google/maps/flutter/navigation/GoogleMapsNavigationSessionMessageHandler.kt @@ -27,9 +27,15 @@ class GoogleMapsNavigationSessionMessageHandler( override fun createNavigationSession( abnormalTerminationReportingEnabled: Boolean, behavior: TaskRemovedBehaviorDto, + notificationOptions: NavigationNotificationOptionsDto?, callback: (Result) -> Unit, ) { - sessionManager.createNavigationSession(abnormalTerminationReportingEnabled, behavior, callback) + sessionManager.createNavigationSession( + abnormalTerminationReportingEnabled, + behavior, + notificationOptions, + callback, + ) } override fun isInitialized(): Boolean { diff --git a/android/src/main/kotlin/com/google/maps/flutter/navigation/messages.g.kt b/android/src/main/kotlin/com/google/maps/flutter/navigation/messages.g.kt index 069698f0..d4e09b75 100644 --- a/android/src/main/kotlin/com/google/maps/flutter/navigation/messages.g.kt +++ b/android/src/main/kotlin/com/google/maps/flutter/navigation/messages.g.kt @@ -2695,6 +2695,44 @@ data class TermsAndConditionsUIParamsDto( override fun hashCode(): Int = toList().hashCode() } +/** + * Android foreground-service notification configuration. + * + * This preserves the Navigation SDK's built-in turn-by-turn notification. + * + * Generated class from Pigeon that represents data sent in messages. + */ +data class NavigationNotificationOptionsDto( + val notificationId: Long? = null, + val defaultMessage: String? = null, + val resumeAppOnTap: Boolean, +) { + companion object { + fun fromList(pigeonVar_list: List): NavigationNotificationOptionsDto { + val notificationId = pigeonVar_list[0] as Long? + val defaultMessage = pigeonVar_list[1] as String? + val resumeAppOnTap = pigeonVar_list[2] as Boolean + return NavigationNotificationOptionsDto(notificationId, defaultMessage, resumeAppOnTap) + } + } + + fun toList(): List { + return listOf(notificationId, defaultMessage, resumeAppOnTap) + } + + override fun equals(other: Any?): Boolean { + if (other !is NavigationNotificationOptionsDto) { + return false + } + if (this === other) { + return true + } + return MessagesPigeonUtils.deepEquals(toList(), other.toList()) + } + + override fun hashCode(): Int = toList().hashCode() +} + /** * Options for step image generation in turn-by-turn navigation events. * @@ -2979,6 +3017,11 @@ private open class messagesPigeonCodec : StandardMessageCodec() { } } 203.toByte() -> { + return (readValue(buffer) as? List)?.let { + NavigationNotificationOptionsDto.fromList(it) + } + } + 204.toByte() -> { return (readValue(buffer) as? List)?.let { StepImageGenerationOptionsDto.fromList(it) } @@ -3285,10 +3328,14 @@ private open class messagesPigeonCodec : StandardMessageCodec() { stream.write(202) writeValue(stream, value.toList()) } - is StepImageGenerationOptionsDto -> { + is NavigationNotificationOptionsDto -> { stream.write(203) writeValue(stream, value.toList()) } + is StepImageGenerationOptionsDto -> { + stream.write(204) + writeValue(stream, value.toList()) + } else -> super.writeValue(stream, value) } } @@ -6889,6 +6936,7 @@ interface NavigationSessionApi { fun createNavigationSession( abnormalTerminationReportingEnabled: Boolean, behavior: TaskRemovedBehaviorDto, + notificationOptions: NavigationNotificationOptionsDto?, callback: (Result) -> Unit, ) @@ -7011,8 +7059,12 @@ interface NavigationSessionApi { val args = message as List val abnormalTerminationReportingEnabledArg = args[0] as Boolean val behaviorArg = args[1] as TaskRemovedBehaviorDto - api.createNavigationSession(abnormalTerminationReportingEnabledArg, behaviorArg) { - result: Result -> + val notificationOptionsArg = args[2] as NavigationNotificationOptionsDto? + api.createNavigationSession( + abnormalTerminationReportingEnabledArg, + behaviorArg, + notificationOptionsArg, + ) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(MessagesPigeonUtils.wrapError(error)) diff --git a/example/lib/pages/navigation.dart b/example/lib/pages/navigation.dart index dd844eeb..2df8e784 100644 --- a/example/lib/pages/navigation.dart +++ b/example/lib/pages/navigation.dart @@ -313,7 +313,13 @@ class _NavigationPageState extends ExamplePageState { if (!_navigatorInitialized) { debugPrint('Initializing new navigation session...'); try { - await GoogleMapsNavigator.initializeNavigationSession(); + await GoogleMapsNavigator.initializeNavigationSession( + notificationOptions: const NavigationNotificationOptions( + notificationId: 1234, + defaultMessage: 'Navigation is active', + resumeAppOnTap: true, + ), + ); } on SessionInitializationException catch (e) { switch (e.code) { case SessionInitializationError.termsNotAccepted: diff --git a/ios/google_navigation_flutter/Sources/google_navigation_flutter/GoogleMapsNavigationSessionMessageHandler.swift b/ios/google_navigation_flutter/Sources/google_navigation_flutter/GoogleMapsNavigationSessionMessageHandler.swift index d40d55c7..079432b9 100644 --- a/ios/google_navigation_flutter/Sources/google_navigation_flutter/GoogleMapsNavigationSessionMessageHandler.swift +++ b/ios/google_navigation_flutter/Sources/google_navigation_flutter/GoogleMapsNavigationSessionMessageHandler.swift @@ -66,9 +66,10 @@ class GoogleMapsNavigationSessionMessageHandler: NavigationSessionApi { func createNavigationSession( abnormalTerminationReportingEnabled: Bool, - // taskRemovedBehaviourValue is Android only value and not used on - // iOS. + // taskRemovedBehaviourValue and notificationOptions are Android only + // values and not used on iOS. behavior: TaskRemovedBehaviorDto, + notificationOptions: NavigationNotificationOptionsDto?, completion: @escaping (Result) -> Void ) { do { diff --git a/ios/google_navigation_flutter/Sources/google_navigation_flutter/messages.g.swift b/ios/google_navigation_flutter/Sources/google_navigation_flutter/messages.g.swift index fc8f5d88..53d01f60 100644 --- a/ios/google_navigation_flutter/Sources/google_navigation_flutter/messages.g.swift +++ b/ios/google_navigation_flutter/Sources/google_navigation_flutter/messages.g.swift @@ -2488,6 +2488,45 @@ struct TermsAndConditionsUIParamsDto: Hashable { } } +/// Android foreground-service notification configuration. +/// +/// This preserves the Navigation SDK's built-in turn-by-turn notification. +/// +/// Generated class from Pigeon that represents data sent in messages. +struct NavigationNotificationOptionsDto: Hashable { + var notificationId: Int64? = nil + var defaultMessage: String? = nil + var resumeAppOnTap: Bool + + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ pigeonVar_list: [Any?]) -> NavigationNotificationOptionsDto? { + let notificationId: Int64? = nilOrValue(pigeonVar_list[0]) + let defaultMessage: String? = nilOrValue(pigeonVar_list[1]) + let resumeAppOnTap = pigeonVar_list[2] as! Bool + + return NavigationNotificationOptionsDto( + notificationId: notificationId, + defaultMessage: defaultMessage, + resumeAppOnTap: resumeAppOnTap + ) + } + func toList() -> [Any?] { + return [ + notificationId, + defaultMessage, + resumeAppOnTap, + ] + } + static func == (lhs: NavigationNotificationOptionsDto, rhs: NavigationNotificationOptionsDto) + -> Bool + { + return deepEqualsmessages(lhs.toList(), rhs.toList()) + } + func hash(into hasher: inout Hasher) { + deepHashmessages(value: toList(), hasher: &hasher) + } +} + /// Options for step image generation in turn-by-turn navigation events. /// /// Generated class from Pigeon that represents data sent in messages. @@ -2780,6 +2819,8 @@ private class MessagesPigeonCodecReader: FlutterStandardReader { case 202: return TermsAndConditionsUIParamsDto.fromList(self.readValue() as! [Any?]) case 203: + return NavigationNotificationOptionsDto.fromList(self.readValue() as! [Any?]) + case 204: return StepImageGenerationOptionsDto.fromList(self.readValue() as! [Any?]) default: return super.readValue(ofType: type) @@ -3011,9 +3052,12 @@ private class MessagesPigeonCodecWriter: FlutterStandardWriter { } else if let value = value as? TermsAndConditionsUIParamsDto { super.writeByte(202) super.writeValue(value.toList()) - } else if let value = value as? StepImageGenerationOptionsDto { + } else if let value = value as? NavigationNotificationOptionsDto { super.writeByte(203) super.writeValue(value.toList()) + } else if let value = value as? StepImageGenerationOptionsDto { + super.writeByte(204) + super.writeValue(value.toList()) } else { super.writeValue(value) } @@ -5880,6 +5924,7 @@ class ViewEventApi: ViewEventApiProtocol { protocol NavigationSessionApi { func createNavigationSession( abnormalTerminationReportingEnabled: Bool, behavior: TaskRemovedBehaviorDto, + notificationOptions: NavigationNotificationOptionsDto?, completion: @escaping (Result) -> Void) func isInitialized() throws -> Bool func cleanup(resetSession: Bool) throws @@ -5948,9 +5993,10 @@ class NavigationSessionApiSetup { let args = message as! [Any?] let abnormalTerminationReportingEnabledArg = args[0] as! Bool let behaviorArg = args[1] as! TaskRemovedBehaviorDto + let notificationOptionsArg: NavigationNotificationOptionsDto? = nilOrValue(args[2]) api.createNavigationSession( abnormalTerminationReportingEnabled: abnormalTerminationReportingEnabledArg, - behavior: behaviorArg + behavior: behaviorArg, notificationOptions: notificationOptionsArg ) { result in switch result { case .success: diff --git a/lib/src/method_channel/convert/navigation.dart b/lib/src/method_channel/convert/navigation.dart index 12a9a9bf..e6aafd99 100644 --- a/lib/src/method_channel/convert/navigation.dart +++ b/lib/src/method_channel/convert/navigation.dart @@ -17,6 +17,18 @@ import 'dart:ui'; import '../../../google_navigation_flutter.dart'; import '../method_channel.dart'; +/// [NavigationNotificationOptions] convert extension. +/// @nodoc +extension ConvertNavigationNotificationOptions + on NavigationNotificationOptions { + /// Converts [NavigationNotificationOptions] to its platform representation. + NavigationNotificationOptionsDto toDto() => NavigationNotificationOptionsDto( + notificationId: notificationId, + defaultMessage: defaultMessage, + resumeAppOnTap: resumeAppOnTap, + ); +} + /// [SpeedAlertSeverityDto] convert extension. /// @nodoc extension ConvertSpeedAlertSeverityDto on SpeedAlertSeverityDto { diff --git a/lib/src/method_channel/messages.g.dart b/lib/src/method_channel/messages.g.dart index 7c385156..b259adc1 100644 --- a/lib/src/method_channel/messages.g.dart +++ b/lib/src/method_channel/messages.g.dart @@ -3195,6 +3195,57 @@ class TermsAndConditionsUIParamsDto { int get hashCode => Object.hashAll(_toList()); } +/// Android foreground-service notification configuration. +/// +/// This preserves the Navigation SDK's built-in turn-by-turn notification. +class NavigationNotificationOptionsDto { + NavigationNotificationOptionsDto({ + this.notificationId, + this.defaultMessage, + required this.resumeAppOnTap, + }); + + int? notificationId; + + String? defaultMessage; + + bool resumeAppOnTap; + + List _toList() { + return [notificationId, defaultMessage, resumeAppOnTap]; + } + + Object encode() { + return _toList(); + } + + static NavigationNotificationOptionsDto decode(Object result) { + result as List; + return NavigationNotificationOptionsDto( + notificationId: result[0] as int?, + defaultMessage: result[1] as String?, + resumeAppOnTap: result[2]! as bool, + ); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) { + if (other is! NavigationNotificationOptionsDto || + other.runtimeType != runtimeType) { + return false; + } + if (identical(this, other)) { + return true; + } + return _deepEquals(encode(), other.encode()); + } + + @override + // ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => Object.hashAll(_toList()); +} + /// Options for step image generation in turn-by-turn navigation events. class StepImageGenerationOptionsDto { StepImageGenerationOptionsDto({ @@ -3474,9 +3525,12 @@ class _PigeonCodec extends StandardMessageCodec { } else if (value is TermsAndConditionsUIParamsDto) { buffer.putUint8(202); writeValue(buffer, value.encode()); - } else if (value is StepImageGenerationOptionsDto) { + } else if (value is NavigationNotificationOptionsDto) { buffer.putUint8(203); writeValue(buffer, value.encode()); + } else if (value is StepImageGenerationOptionsDto) { + buffer.putUint8(204); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -3671,6 +3725,8 @@ class _PigeonCodec extends StandardMessageCodec { case 202: return TermsAndConditionsUIParamsDto.decode(readValue(buffer)!); case 203: + return NavigationNotificationOptionsDto.decode(readValue(buffer)!); + case 204: return StepImageGenerationOptionsDto.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -8032,6 +8088,7 @@ class NavigationSessionApi { Future createNavigationSession( bool abnormalTerminationReportingEnabled, TaskRemovedBehaviorDto behavior, + NavigationNotificationOptionsDto? notificationOptions, ) async { final String pigeonVar_channelName = 'dev.flutter.pigeon.google_navigation_flutter.NavigationSessionApi.createNavigationSession$pigeonVar_messageChannelSuffix'; @@ -8042,7 +8099,11 @@ class NavigationSessionApi { binaryMessenger: pigeonVar_binaryMessenger, ); final Future pigeonVar_sendFuture = pigeonVar_channel.send( - [abnormalTerminationReportingEnabled, behavior], + [ + abnormalTerminationReportingEnabled, + behavior, + notificationOptions, + ], ); final List? pigeonVar_replyList = await pigeonVar_sendFuture as List?; diff --git a/lib/src/method_channel/session_api.dart b/lib/src/method_channel/session_api.dart index d5aeafad..a2766304 100644 --- a/lib/src/method_channel/session_api.dart +++ b/lib/src/method_channel/session_api.dart @@ -55,6 +55,7 @@ class NavigationSessionAPIImpl { Future createNavigationSession( bool abnormalTerminationReportingEnabled, TaskRemovedBehavior taskRemovedBehavior, + NavigationNotificationOptions? notificationOptions, ) async { // Setup session API streams. ensureSessionAPISetUp(); @@ -63,6 +64,7 @@ class NavigationSessionAPIImpl { await _sessionApi.createNavigationSession( abnormalTerminationReportingEnabled, taskRemovedBehavior.toDto(), + notificationOptions?.toDto(), ); } on PlatformException catch (e) { switch (e.code) { diff --git a/lib/src/navigator/google_navigation_flutter_navigator.dart b/lib/src/navigator/google_navigation_flutter_navigator.dart index 3cc37950..b0d9276c 100644 --- a/lib/src/navigator/google_navigation_flutter_navigator.dart +++ b/lib/src/navigator/google_navigation_flutter_navigator.dart @@ -49,15 +49,19 @@ class GoogleMapsNavigator { /// Optional parameter [abnormalTerminationReportingEnabled] can be used enables/disables /// reporting abnormal SDK terminations such as the app crashes while the SDK is still running. /// + /// [notificationOptions] configures Android's built-in navigation notification. + /// It is not available on iOS and is ignored there. static Future initializeNavigationSession({ bool abnormalTerminationReportingEnabled = true, TaskRemovedBehavior taskRemovedBehavior = TaskRemovedBehavior.continueService, + NavigationNotificationOptions? notificationOptions, }) async { await GoogleMapsNavigationPlatform.instance.navigationSessionAPI .createNavigationSession( abnormalTerminationReportingEnabled, taskRemovedBehavior, + notificationOptions, ); // Enable road-snapped location updates if there are subscriptions to them. diff --git a/lib/src/types/navigation_notification_options.dart b/lib/src/types/navigation_notification_options.dart new file mode 100644 index 00000000..5c13035e --- /dev/null +++ b/lib/src/types/navigation_notification_options.dart @@ -0,0 +1,39 @@ +// Copyright 2026 Google LLC +// +// 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 +// +// https://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. + +/// Configures the Android navigation foreground-service notification. +/// +/// These options preserve the Navigation SDK's built-in turn-by-turn +/// notification. This Android-only configuration is not available on iOS and +/// is ignored there. +/// {@category Navigation} +class NavigationNotificationOptions { + /// Creates Android navigation notification options. + const NavigationNotificationOptions({ + this.notificationId, + this.defaultMessage, + this.resumeAppOnTap = false, + }); + + /// The Android notification ID. The Navigation SDK default is used when null. + final int? notificationId; + + /// Text shown when the SDK is not actively navigating. + /// + /// The Navigation SDK default is used when null. + final String? defaultMessage; + + /// Whether tapping the notification opens or resumes the application. + final bool resumeAppOnTap; +} diff --git a/lib/src/types/types.dart b/lib/src/types/types.dart index 3f2af579..9859c0de 100644 --- a/lib/src/types/types.dart +++ b/lib/src/types/types.dart @@ -22,6 +22,7 @@ export 'navigation.dart'; export 'navigation_destinations.dart'; export 'navigation_header_styling_options.dart'; export 'navigation_initialization_params.dart'; +export 'navigation_notification_options.dart'; export 'navigation_view_types.dart'; export 'navinfo.dart'; export 'polygons.dart'; diff --git a/pigeons/messages.dart b/pigeons/messages.dart index 1a53788a..21f6bf67 100644 --- a/pigeons/messages.dart +++ b/pigeons/messages.dart @@ -1505,6 +1505,21 @@ enum TaskRemovedBehaviorDto { quitService, } +/// Android foreground-service notification configuration. +/// +/// This preserves the Navigation SDK's built-in turn-by-turn notification. +class NavigationNotificationOptionsDto { + NavigationNotificationOptionsDto({ + this.notificationId, + this.defaultMessage, + required this.resumeAppOnTap, + }); + + final int? notificationId; + final String? defaultMessage; + final bool resumeAppOnTap; +} + /// Options for step image generation in turn-by-turn navigation events. class StepImageGenerationOptionsDto { StepImageGenerationOptionsDto({ @@ -1527,6 +1542,7 @@ abstract class NavigationSessionApi { void createNavigationSession( bool abnormalTerminationReportingEnabled, TaskRemovedBehaviorDto behavior, + NavigationNotificationOptionsDto? notificationOptions, ); bool isInitialized(); void cleanup(bool resetSession); diff --git a/test/google_navigation_flutter_test.dart b/test/google_navigation_flutter_test.dart index 66ac099b..da865890 100644 --- a/test/google_navigation_flutter_test.dart +++ b/test/google_navigation_flutter_test.dart @@ -1303,11 +1303,25 @@ void main() { // Initialize session and session controller. await GoogleMapsNavigator.initializeNavigationSession( abnormalTerminationReportingEnabled: false, + notificationOptions: const NavigationNotificationOptions( + notificationId: 1234, + defaultMessage: 'Navigation is active', + resumeAppOnTap: true, + ), ); VerificationResult result = verify( - sessionMockApi.createNavigationSession(captureAny, captureAny), + sessionMockApi.createNavigationSession( + captureAny, + captureAny, + captureAny, + ), ); expect(result.captured[0] as bool, false); + final NavigationNotificationOptionsDto notificationOptions = + result.captured[2] as NavigationNotificationOptionsDto; + expect(notificationOptions.notificationId, 1234); + expect(notificationOptions.defaultMessage, 'Navigation is active'); + expect(notificationOptions.resumeAppOnTap, true); // Start/stop guidance. diff --git a/test/google_navigation_flutter_test.mocks.dart b/test/google_navigation_flutter_test.mocks.dart index 31703705..f19a4eee 100644 --- a/test/google_navigation_flutter_test.mocks.dart +++ b/test/google_navigation_flutter_test.mocks.dart @@ -57,26 +57,34 @@ class _FakeNavigationTimeAndDistanceDto_1 extends _i1.SmartFake ) : super(parent, parentInvocation); } -class _FakeCameraPositionDto_2 extends _i1.SmartFake +class _FakeNavigationHeaderStylingOptionsDto_2 extends _i1.SmartFake + implements _i2.NavigationHeaderStylingOptionsDto { + _FakeNavigationHeaderStylingOptionsDto_2( + Object parent, + Invocation parentInvocation, + ) : super(parent, parentInvocation); +} + +class _FakeCameraPositionDto_3 extends _i1.SmartFake implements _i2.CameraPositionDto { - _FakeCameraPositionDto_2(Object parent, Invocation parentInvocation) + _FakeCameraPositionDto_3(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeLatLngBoundsDto_3 extends _i1.SmartFake +class _FakeLatLngBoundsDto_4 extends _i1.SmartFake implements _i2.LatLngBoundsDto { - _FakeLatLngBoundsDto_3(Object parent, Invocation parentInvocation) + _FakeLatLngBoundsDto_4(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeMapPaddingDto_4 extends _i1.SmartFake implements _i2.MapPaddingDto { - _FakeMapPaddingDto_4(Object parent, Invocation parentInvocation) +class _FakeMapPaddingDto_5 extends _i1.SmartFake implements _i2.MapPaddingDto { + _FakeMapPaddingDto_5(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } -class _FakeImageDescriptorDto_5 extends _i1.SmartFake +class _FakeImageDescriptorDto_6 extends _i1.SmartFake implements _i2.ImageDescriptorDto { - _FakeImageDescriptorDto_5(Object parent, Invocation parentInvocation) + _FakeImageDescriptorDto_6(Object parent, Invocation parentInvocation) : super(parent, parentInvocation); } @@ -93,11 +101,13 @@ class MockTestNavigationSessionApi extends _i1.Mock _i4.Future createNavigationSession( bool? abnormalTerminationReportingEnabled, _i2.TaskRemovedBehaviorDto? behavior, + _i2.NavigationNotificationOptionsDto? notificationOptions, ) => (super.noSuchMethod( Invocation.method(#createNavigationSession, [ abnormalTerminationReportingEnabled, behavior, + notificationOptions, ]), returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), @@ -480,6 +490,31 @@ class MockTestMapViewApi extends _i1.Mock implements _i3.TestMapViewApi { returnValueForMissingStub: null, ); + @override + _i2.NavigationHeaderStylingOptionsDto getNavigationHeaderStylingOptions( + int? viewId, + ) => + (super.noSuchMethod( + Invocation.method(#getNavigationHeaderStylingOptions, [viewId]), + returnValue: _FakeNavigationHeaderStylingOptionsDto_2( + this, + Invocation.method(#getNavigationHeaderStylingOptions, [viewId]), + ), + ) + as _i2.NavigationHeaderStylingOptionsDto); + + @override + void setNavigationHeaderStylingOptions( + int? viewId, + _i2.NavigationHeaderStylingOptionsDto? stylingOptions, + ) => super.noSuchMethod( + Invocation.method(#setNavigationHeaderStylingOptions, [ + viewId, + stylingOptions, + ]), + returnValueForMissingStub: null, + ); + @override bool isNavigationFooterEnabled(int? viewId) => (super.noSuchMethod( @@ -843,7 +878,7 @@ class MockTestMapViewApi extends _i1.Mock implements _i3.TestMapViewApi { _i2.CameraPositionDto getCameraPosition(int? viewId) => (super.noSuchMethod( Invocation.method(#getCameraPosition, [viewId]), - returnValue: _FakeCameraPositionDto_2( + returnValue: _FakeCameraPositionDto_3( this, Invocation.method(#getCameraPosition, [viewId]), ), @@ -854,7 +889,7 @@ class MockTestMapViewApi extends _i1.Mock implements _i3.TestMapViewApi { _i2.LatLngBoundsDto getVisibleRegion(int? viewId) => (super.noSuchMethod( Invocation.method(#getVisibleRegion, [viewId]), - returnValue: _FakeLatLngBoundsDto_3( + returnValue: _FakeLatLngBoundsDto_4( this, Invocation.method(#getVisibleRegion, [viewId]), ), @@ -1283,7 +1318,7 @@ class MockTestMapViewApi extends _i1.Mock implements _i3.TestMapViewApi { _i2.MapPaddingDto getPadding(int? viewId) => (super.noSuchMethod( Invocation.method(#getPadding, [viewId]), - returnValue: _FakeMapPaddingDto_4( + returnValue: _FakeMapPaddingDto_5( this, Invocation.method(#getPadding, [viewId]), ), @@ -1377,7 +1412,7 @@ class MockTestAutoMapViewApi extends _i1.Mock _i2.CameraPositionDto getCameraPosition() => (super.noSuchMethod( Invocation.method(#getCameraPosition, []), - returnValue: _FakeCameraPositionDto_2( + returnValue: _FakeCameraPositionDto_3( this, Invocation.method(#getCameraPosition, []), ), @@ -1388,7 +1423,7 @@ class MockTestAutoMapViewApi extends _i1.Mock _i2.LatLngBoundsDto getVisibleRegion() => (super.noSuchMethod( Invocation.method(#getVisibleRegion, []), - returnValue: _FakeLatLngBoundsDto_3( + returnValue: _FakeLatLngBoundsDto_4( this, Invocation.method(#getVisibleRegion, []), ), @@ -2025,7 +2060,7 @@ class MockTestAutoMapViewApi extends _i1.Mock _i2.MapPaddingDto getPadding() => (super.noSuchMethod( Invocation.method(#getPadding, []), - returnValue: _FakeMapPaddingDto_4( + returnValue: _FakeMapPaddingDto_5( this, Invocation.method(#getPadding, []), ), @@ -2095,7 +2130,7 @@ class MockTestImageRegistryApi extends _i1.Mock width, height, ]), - returnValue: _FakeImageDescriptorDto_5( + returnValue: _FakeImageDescriptorDto_6( this, Invocation.method(#registerBitmapImage, [ imageId, diff --git a/test/messages_test.g.dart b/test/messages_test.g.dart index 7a905b66..b371b58d 100644 --- a/test/messages_test.g.dart +++ b/test/messages_test.g.dart @@ -254,9 +254,12 @@ class _PigeonCodec extends StandardMessageCodec { } else if (value is TermsAndConditionsUIParamsDto) { buffer.putUint8(202); writeValue(buffer, value.encode()); - } else if (value is StepImageGenerationOptionsDto) { + } else if (value is NavigationNotificationOptionsDto) { buffer.putUint8(203); writeValue(buffer, value.encode()); + } else if (value is StepImageGenerationOptionsDto) { + buffer.putUint8(204); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -451,6 +454,8 @@ class _PigeonCodec extends StandardMessageCodec { case 202: return TermsAndConditionsUIParamsDto.decode(readValue(buffer)!); case 203: + return NavigationNotificationOptionsDto.decode(readValue(buffer)!); + case 204: return StepImageGenerationOptionsDto.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -5814,6 +5819,7 @@ abstract class TestNavigationSessionApi { Future createNavigationSession( bool abnormalTerminationReportingEnabled, TaskRemovedBehaviorDto behavior, + NavigationNotificationOptionsDto? notificationOptions, ); bool isInitialized(); @@ -5945,10 +5951,13 @@ abstract class TestNavigationSessionApi { arg_behavior != null, 'Argument for dev.flutter.pigeon.google_navigation_flutter.NavigationSessionApi.createNavigationSession was null, expected non-null TaskRemovedBehaviorDto.', ); + final NavigationNotificationOptionsDto? arg_notificationOptions = + (args[2] as NavigationNotificationOptionsDto?); try { await api.createNavigationSession( arg_abnormalTerminationReportingEnabled!, arg_behavior!, + arg_notificationOptions, ); return wrapResponse(empty: true); } on PlatformException catch (e) {