Skip to content

Commit 0370c51

Browse files
aaraniTaras
authored andcommitted
Background tasks support
Fixes xamarin#409 Upstream PR: xamarin#1674 (Removed .netstandard1.0 target framework because it doesn't support OS checks.) Co-authored-by: Taras <mail@webwarrior.ws>
1 parent 72bc989 commit 0370c51

10 files changed

+261
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Android.Content;
5+
6+
namespace Xamarin.Essentials.Background
7+
{
8+
public static partial class Background
9+
{
10+
static ContextWrapper context;
11+
12+
public static void Init(ContextWrapper ctx)
13+
{
14+
context = ctx;
15+
}
16+
17+
internal static void PlatformStart()
18+
{
19+
if (context == null)
20+
throw new InvalidOperationException("Background service is not initialized yet");
21+
var intent = new Intent(context, typeof(BackgroundService));
22+
context.StartService(intent);
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Android.App;
5+
using Android.Content;
6+
using Android.OS;
7+
8+
namespace Xamarin.Essentials.Background
9+
{
10+
[Service]
11+
public class BackgroundService : Service
12+
{
13+
static bool isRunning;
14+
15+
public override IBinder OnBind(Intent intent)
16+
{
17+
return null;
18+
}
19+
20+
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
21+
{
22+
if (!isRunning)
23+
{
24+
Background.StartJobs();
25+
26+
isRunning = true;
27+
}
28+
29+
return StartCommandResult.Sticky;
30+
}
31+
32+
public override void OnDestroy()
33+
{
34+
}
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using System.Threading.Tasks;
5+
6+
namespace Xamarin.Essentials.Background
7+
{
8+
public static partial class Background
9+
{
10+
internal static void PlatformStart()
11+
{
12+
BackgroundService.Start();
13+
}
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using UIKit;
5+
6+
namespace Xamarin.Essentials.Background
7+
{
8+
public static class BackgroundService
9+
{
10+
static nint taskId;
11+
static bool isRunning;
12+
13+
/// <summary>
14+
/// Start the execution of background service
15+
/// </summary>
16+
public static void Start()
17+
{
18+
if (isRunning)
19+
return;
20+
21+
taskId = UIApplication.SharedApplication.BeginBackgroundTask("BackgroundTask", Stop);
22+
Background.StartJobs();
23+
24+
isRunning = true;
25+
}
26+
27+
public static void Stop()
28+
{
29+
UIApplication.SharedApplication.EndBackgroundTask(taskId);
30+
}
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Xamarin.Essentials.Background
6+
{
7+
public partial class Background
8+
{
9+
internal static void PlatformStart()
10+
{
11+
// TODO?: https://developer.apple.com/documentation/backgroundtasks
12+
StartJobs();
13+
}
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Runtime.InteropServices;
2+
3+
namespace Xamarin.Essentials.Background
4+
{
5+
public static partial class Background
6+
{
7+
internal static void PlatformStart()
8+
{
9+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
10+
Background.StartJobs();
11+
else
12+
throw ExceptionUtils.NotSupportedOrImplementedException;
13+
}
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Xamarin.Essentials.Background
8+
{
9+
public static partial class Background
10+
{
11+
static Dictionary<string, IBackgroundTask> schedules = new Dictionary<string, IBackgroundTask>();
12+
13+
public static void Add<T>(Func<T> schedule)
14+
where T : IBackgroundTask
15+
{
16+
#if NETSTANDARD1_0
17+
var typeName = schedule.GetType().GenericTypeArguments[0]?.Name;
18+
#else
19+
var typeName = schedule.GetType().GetGenericArguments()[0]?.Name;
20+
#endif
21+
22+
if (typeName != null && !schedules.ContainsKey(typeName))
23+
schedules.Add(typeName, schedule());
24+
}
25+
26+
internal static Task StartJobs()
27+
{
28+
return Task.WhenAll(schedules.Values.Select(x => x.StartJob()));
29+
}
30+
31+
public static void StartBackgroundWork()
32+
{
33+
PlatformStart();
34+
}
35+
}
36+
37+
public interface IBackgroundTask
38+
{
39+
Task StartJob();
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Xamarin.Essentials.Background
6+
{
7+
public partial class Background
8+
{
9+
internal static void PlatformStart()
10+
{
11+
// TODO: https://docs.tizen.org/application/native/guides/applications/service-app/
12+
throw ExceptionUtils.NotSupportedOrImplementedException;
13+
}
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Windows.ApplicationModel.Activation;
7+
using Windows.ApplicationModel.Background;
8+
9+
namespace Xamarin.Essentials.Background
10+
{
11+
public static partial class Background
12+
{
13+
const string backServiceName = "BackgroundService";
14+
15+
internal static void PlatformStart()
16+
{
17+
Task.Run(StartBackgroundServiceAsync);
18+
}
19+
20+
public static async Task OnBackgroundActivated(BackgroundActivatedEventArgs args)
21+
{
22+
var deferral = args.TaskInstance.GetDeferral();
23+
await StartJobs();
24+
deferral.Complete();
25+
}
26+
27+
static async Task StartBackgroundServiceAsync()
28+
{
29+
var access = await BackgroundExecutionManager.RequestAccessAsync();
30+
31+
switch (access)
32+
{
33+
case BackgroundAccessStatus.Unspecified:
34+
case BackgroundAccessStatus.DeniedByUser:
35+
case BackgroundAccessStatus.DeniedBySystemPolicy:
36+
await StartJobs();
37+
return;
38+
}
39+
40+
var builder = new BackgroundTaskBuilder
41+
{
42+
Name = backServiceName,
43+
IsNetworkRequested = true
44+
};
45+
46+
var trigger = new ApplicationTrigger();
47+
builder.SetTrigger(trigger);
48+
49+
var isAlreadyRegistered = BackgroundTaskRegistration.AllTasks.Any(t => t.Value?.Name == backServiceName);
50+
if (isAlreadyRegistered)
51+
{
52+
foreach (var tsk in BackgroundTaskRegistration.AllTasks)
53+
{
54+
if (tsk.Value.Name == backServiceName)
55+
{
56+
tsk.Value.Unregister(true);
57+
break;
58+
}
59+
}
60+
}
61+
62+
builder.Register();
63+
await trigger.RequestAsync();
64+
}
65+
}
66+
}

Xamarin.Essentials/Xamarin.Essentials.csproj

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="MSBuild.Sdk.Extras/3.0.22">
22
<PropertyGroup>
3-
<TargetFrameworks>netstandard1.0;netstandard2.0;Xamarin.iOS10;Xamarin.TVOS10;Xamarin.WatchOS10;MonoAndroid80;MonoAndroid81;MonoAndroid90;MonoAndroid10.0;tizen40;Xamarin.Mac20;</TargetFrameworks>
3+
<TargetFrameworks>netstandard2.0;Xamarin.iOS10;Xamarin.TVOS10;Xamarin.WatchOS10;MonoAndroid80;MonoAndroid81;MonoAndroid90;MonoAndroid10.0;tizen40;Xamarin.Mac20;</TargetFrameworks>
44
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);uap10.0.16299;</TargetFrameworks>
55
<AssemblyName>Xamarin.Essentials</AssemblyName>
66
<RootNamespace>Xamarin.Essentials</RootNamespace>
@@ -55,9 +55,6 @@
5555
<Compile Include="**\*.shared.cs" />
5656
<Compile Include="**\*.shared.*.cs" />
5757
</ItemGroup>
58-
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard1.')) ">
59-
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
60-
</ItemGroup>
6158
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
6259
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
6360
<Compile Include="**\*.netstandard.cs" />

0 commit comments

Comments
 (0)