public override void OnReceive(Context context, Intent intent) { var hostAddress = intent.GetStringExtra(HostAddressTag); var workId = intent.GetStringExtra(WorkIdTag); var notificationId = intent.GetIntExtra(NotificationIdTag, 0); if (workId != null && notificationId != 0 && hostAddress != null) { Log.Debug("Aborting work for {Action} {NotificationId} {WorkId}", intent.Action, notificationId, workId); try { WorkManager.GetInstance(Application.Context).CancelWorkById(UUID.FromString(workId)); NotificationHelper.DestroyNotification(notificationId); switch (intent.Action) { case ActionKindShutdown: SystemStateManager.Clear(hostAddress, SystemStateKind.Shutdown); break; case ActionKindHibernate: SystemStateManager.Clear(hostAddress, SystemStateKind.Hibernate); break; case ActionKindRestart: SystemStateManager.Clear(hostAddress, SystemStateKind.Restart); break; } } catch (Exception e) { Log.Error(e); } } }
protected override async Task <Data> DoWorkAsync(CancellationToken cancellationToken) { var notificationId = (GetStateKind() + "+" + _agentAddress).GetHashCode(); Log.Debug("Spawned notification with Id {Id}", notificationId); try { var scheduled = await SystemStateManager.GetScheduledTimeAsync(_agentAddress, GetStateKind()); if (scheduled == null || DateTime.Now > scheduled.Value) { Log.Info("A system state event passed while the device was not working."); return(Data.Empty); } var progressDataBuilder = new Data.Builder(); UpdateProgress(progressDataBuilder, 0, false); if (!HostEndpointAddress.TryParse(_agentAddress, out var address)) { Log.Warn("Address {Address} could not be parsed - aborting process", _agentAddress); return(Data.Empty); } using (var agent = GrpcApplicationAgentFactory.Create(GrpcChannelHub.GetChannelFor(address))) { var hostName = await agent.DesktopClient.GetHostNameAsync(TimeSpan.FromSeconds(5)); var notification = NotificationHelper.DisplayNotification(notificationId, builder => { builder.SetCategory(NotificationCompat.CategoryProgress); builder.SetContentTitle(GetNotificationTitle(hostName)); builder.SetOnlyAlertOnce(true); builder.SetSmallIcon(GetNotificationIcon()); var intent = new Intent(); intent.SetAction(GetAbortAction()); intent.PutExtra(AbortBroadcastReceiver.NotificationIdTag, notificationId); intent.PutExtra(AbortBroadcastReceiver.WorkIdTag, Id.ToString()); intent.PutExtra(AbortBroadcastReceiver.HostAddressTag, _agentAddress); var pendingIntent = PendingIntent.GetBroadcast(Application.Context, notificationId, intent, PendingIntentFlags.OneShot); builder.AddAction(Android.Resource.Drawable.ButtonPlus, "Abort", pendingIntent); }, GetNotificationChannel()); SetForegroundAsync(new ForegroundInfo(notificationId, notification.Build())); var startDifference = scheduled.Value - DateTime.Now; while (scheduled > DateTime.Now) { var currentDifference = scheduled.Value - DateTime.Now; var progress = (100f / startDifference.TotalSeconds) * currentDifference.TotalSeconds; notification.SetProgress(100, (int)progress, false); UpdateProgress(progressDataBuilder, progress, true); notification.SetContentText(currentDifference.ToString("hh\\:mm\\:ss")); NotificationHelper.UpdateNotification(ApplicationContext, notificationId, notification); await Task.Delay(1000, cancellationToken); } UpdateProgress(progressDataBuilder, 0, false); NotificationHelper.DestroyNotification(notificationId); SystemStateManager.Clear(_agentAddress, GetStateKind()); var result = await ExecuteFinalizerAsync(agent); Xamarin.Essentials.MainThread.BeginInvokeOnMainThread(() => { if (result) { ToastHelper.Display(GetSuccessToastMessage(hostName), ToastLength.Long); } else { ToastHelper.Display("Error", ToastLength.Short); } }); } } catch (RpcException e) { Log.Debug(e, "Cancelling work because of an RPC exception"); WorkManager.GetInstance(ApplicationContext).CancelWorkById(Id); } return(Data.Empty); }