@@ -17,6 +17,7 @@ import 'models/notification_options.dart';
1717import 'models/notification_permission.dart' ;
1818import 'models/service_request_result.dart' ;
1919import 'task_handler.dart' ;
20+ import 'utils/utility.dart' ;
2021
2122export 'errors/service_already_started_exception.dart' ;
2223export 'errors/service_not_initialized_exception.dart' ;
@@ -101,11 +102,11 @@ class FlutterForegroundTask {
101102 List <NotificationButton >? notificationButtons,
102103 Function ? callback,
103104 }) async {
104- if (! isInitialized) {
105- return ServiceRequestResult .error (ServiceNotInitializedException ());
106- }
107-
108105 try {
106+ if (! isInitialized) {
107+ throw ServiceNotInitializedException ();
108+ }
109+
109110 if (await isRunningService) {
110111 throw ServiceAlreadyStartedException ();
111112 }
@@ -123,25 +124,7 @@ class FlutterForegroundTask {
123124 );
124125
125126 if (! skipServiceResponseCheck) {
126- final Stopwatch stopwatch = Stopwatch ()..start ();
127- bool isStarted = false ;
128- await Future .doWhile (() async {
129- isStarted = await isRunningService;
130-
131- // official doc: Once the service has been created, the service must call its startForeground() method within five seconds.
132- // ref: https://developer.android.com/guide/components/services#StartingAService
133- if (isStarted || stopwatch.elapsedMilliseconds > 5 * 1000 ) {
134- return false ;
135- } else {
136- await Future .delayed (const Duration (milliseconds: 100 ));
137- return true ;
138- }
139- });
140-
141- // no response :(
142- if (! isStarted) {
143- throw ServiceTimeoutException ();
144- }
127+ await checkServiceStateChange (target: true );
145128 }
146129
147130 return ServiceRequestResult .success ();
@@ -204,25 +187,7 @@ class FlutterForegroundTask {
204187 await _platform.stopService ();
205188
206189 if (! skipServiceResponseCheck) {
207- final Stopwatch stopwatch = Stopwatch ()..start ();
208- bool isStopped = false ;
209- await Future .doWhile (() async {
210- isStopped = ! (await isRunningService);
211-
212- // official doc: Once the service has been created, the service must call its startForeground() method within five seconds.
213- // ref: https://developer.android.com/guide/components/services#StartingAService
214- if (isStopped || stopwatch.elapsedMilliseconds > 5 * 1000 ) {
215- return false ;
216- } else {
217- await Future .delayed (const Duration (milliseconds: 100 ));
218- return true ;
219- }
220- });
221-
222- // no response :(
223- if (! isStopped) {
224- throw ServiceTimeoutException ();
225- }
190+ await checkServiceStateChange (target: false );
226191 }
227192
228193 return ServiceRequestResult .success ();
@@ -231,6 +196,22 @@ class FlutterForegroundTask {
231196 }
232197 }
233198
199+ @visibleForTesting
200+ static Future <void > checkServiceStateChange ({required bool target}) async {
201+ // official doc: Once the service has been created, the service must call its startForeground() method within 5 seconds.
202+ // ref: https://developer.android.com/guide/components/services#StartingAService
203+ final bool isCompleted = await Utility .instance.completedWithinDeadline (
204+ deadline: const Duration (seconds: 5 ),
205+ future: () async {
206+ return target == await isRunningService;
207+ },
208+ );
209+
210+ if (! isCompleted) {
211+ throw ServiceTimeoutException ();
212+ }
213+ }
214+
234215 /// Returns whether the foreground service is running.
235216 static Future <bool > get isRunningService => _platform.isRunningService;
236217
0 commit comments