/// <summary> /// Called by the app when the app is suspending /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void OnSuspending_Fired(object sender, SuspendingEventArgs e) { // Setup a ref deferral for everyone to hold. We also need to setup a clean up action to save the setting // when the deferral is done. RefCountedDeferral refDeferral = new RefCountedDeferral(e.SuspendingOperation.GetDeferral(), () => { // We need to flush the settings here just before we complete the deferal. We need to block this function // until the settings are flushed. using (AutoResetEvent are = new AutoResetEvent(false)) { Task.Run(async() => { // Flush out the local settings await SettingsMan.FlushLocalSettings(); are.Set(); }); are.WaitOne(); } }); // Add a ref to cover anyone down this call stack. refDeferral.AddRef(); // Make the OnSuspendingArgs args = new OnSuspendingArgs() { RefDeferral = refDeferral }; // Fire the event m_onSuspending.Raise(this, args); // Release our ref to the deferral refDeferral.ReleaseRef(); }
/// <summary> /// This will actually kick off all of the work. /// </summary> public async Task RunUpdate(RefCountedDeferral refDefferal) { // If we are a background task report the time if (m_baconMan.IsBackgroundTask) { LastUpdateTime = DateTime.Now; } // If we are not a background task check message of the day if (!m_baconMan.IsBackgroundTask) { // Sleep for a little while to give the UI some time get work done. await Task.Delay(1000); // Check for MOTD updates. await m_baconMan.MotdMan.CheckForUpdates(); // Sleep for a little while to give the UI some time get work done. await Task.Delay(5000); } // Ensure everything is ready await EnsureBackgroundSetup(); // Run the image update if needed await ImageUpdaterMan.RunUpdate(refDefferal); // Run the message update if needed. MessageUpdaterMan.RunUpdate(refDefferal); }
/// <summary> /// Release the deferral for a type if it is held /// </summary> /// <param name="type"></param> private void ReleaseDeferral(UpdateTypes type) { lock (this) { if (type == UpdateTypes.LockScreen) { if (m_lockScreenRefDeferral != null) { m_lockScreenRefDeferral.ReleaseRef(); } m_lockScreenRefDeferral = null; } else if (type == UpdateTypes.Band) { if (m_bandRefDeferral != null) { m_bandRefDeferral.ReleaseRef(); } m_bandRefDeferral = null; } else { if (m_desktopRefDeferral != null) { m_desktopRefDeferral.ReleaseRef(); } m_desktopRefDeferral = null; } } }
/// <summary> /// Checks if we should update and if so does so. /// </summary> /// <param name="refDeferral"></param> /// <param name="force"></param> public void RunUpdate(RefCountedDeferral refDeferral, bool force = false) { if (!IsEnabled || !_baconMan.UserMan.IsUserSignedIn) { return; } var timeSinceLastRun = DateTime.Now - LastUpdateTime; if (!(timeSinceLastRun.TotalMinutes > 10) && !force) { return; } // We should update. Grab the deferral _refDeferral = refDeferral; _refDeferral.AddRef(); // Make the collector _collector = new MessageCollector(_baconMan); // We don't need to sub to the collection update because we will get // called automatically when it updates _collector.OnCollectorStateChange += Collector_OnCollectorStateChange; // Tell it to update! _collector.Update(true); }
/// <summary> /// Release the deferral for a type if it is held /// </summary> /// <param name="type"></param> private void ReleaseDeferral(UpdateTypes type) { lock (this) { switch (type) { case UpdateTypes.LockScreen: _lockScreenRefDeferral?.ReleaseRef(); _lockScreenRefDeferral = null; break; case UpdateTypes.Band: _mBandRefDeferral?.ReleaseRef(); _mBandRefDeferral = null; break; case UpdateTypes.All: break; case UpdateTypes.Desktop: break; default: _mDesktopRefDeferral?.ReleaseRef(); _mDesktopRefDeferral = null; break; } } }
/// <summary> /// Releases the deferral if it is held. /// </summary> private void ReleaseDeferal() { if (m_refDeferral != null) { m_refDeferral.ReleaseRef(); } m_refDeferral = null; }
public async void Run(IBackgroundTaskInstance taskInstance) { // Create the baconit manager _mBaconMan = new BaconManager(true); // Setup the ref counted deferral var refDeferral = new RefCountedDeferral(taskInstance.GetDeferral(), OnDeferralCleanup); // Add a ref so everyone in this call is protected refDeferral.AddRef(); // Fire off the update await _mBaconMan.BackgroundMan.RunUpdate(refDeferral); // After this returns the deferral will call complete unless someone else took a ref on it. refDeferral.ReleaseRef(); }
/// <summary> /// This will actually kick off all of the work. /// </summary> public async Task RunUpdate(RefCountedDeferral refDefferal) { // If we are a background task report the time if (m_baconMan.IsBackgroundTask) { LastUpdateTime = DateTime.Now; } // Ensure everything is ready await EnsureBackgroundSetup(); // Run the image update if needed await ImageUpdaterMan.RunUpdate(refDefferal); // Run the message update if needed. MessageUpdaterMan.RunUpdate(refDefferal); }
/// <summary> /// Kicks off an update of the images. /// </summary> /// <param name="force"></param> public async Task RunUpdate(RefCountedDeferral refDeferral, bool force = false) { if ((IsDeskopEnabled || IsLockScreenEnabled || IsBandWallpaperEnabled) && UserProfilePersonalizationSettings.IsSupported()) { TimeSpan timeSinceLastRun = DateTime.Now - LastImageUpdate; if (timeSinceLastRun.TotalMinutes > UpdateFrquency || force) { // Make sure we aren't running lock (this) { if (m_isRunning) { return; } m_isRunning = true; } // Do the updates await KickOffUpdate(force, refDeferral); } } }
/// <summary> /// Actually does the update /// </summary> private async Task KickOffUpdate(bool force, RefCountedDeferral refDeferral) { m_baconMan.TelemetryMan.ReportLog(this, "Updater updating."); try { // Figure out if we need to do a full update int fullUpdateFequencyMins = UpdateFrquency * c_maxImageCacheCount; TimeSpan timeSinceLastFullUpdate = DateTime.Now - LastFullUpdate; if (timeSinceLastFullUpdate.TotalMinutes > fullUpdateFequencyMins || force) { m_baconMan.TelemetryMan.ReportLog(this, "Running full update"); // Update lock screen images if (IsLockScreenEnabled) { m_baconMan.TelemetryMan.ReportLog(this, "Updating lock screen", SeverityLevel.Verbose); // Make a deferral scope object so we can do our work without being killed. // Note! We need release this object or it will hang the app around forever! m_lockScreenRefDeferral = refDeferral; m_lockScreenRefDeferral.AddRef(); // Kick off the update, this will happen async. GetSubredditStories(LockScreenSubredditName, UpdateTypes.LockScreen); } if (IsDeskopEnabled) { m_baconMan.TelemetryMan.ReportLog(this, "Updating lock screen", SeverityLevel.Verbose); // Shortcut: If lock screen in enabled and it is the same subreddit just share the same cache. If not, // get the desktop images if (IsLockScreenEnabled && LockScreenSubredditName.Equals(DesktopSubredditName)) { m_baconMan.TelemetryMan.ReportLog(this, "Desktop same sub as lockscreen, skipping image update.", SeverityLevel.Verbose); } else { m_baconMan.TelemetryMan.ReportLog(this, "Updating desktop image", SeverityLevel.Verbose); // Make a deferral scope object so we can do our work without being killed. // Note! We need release this object or it will hang the app around forever! m_desktopRefDeferral = refDeferral; m_desktopRefDeferral.AddRef(); // Kick off the update, this will happen async. GetSubredditStories(DesktopSubredditName, UpdateTypes.Desktop); } } // Update lock screen images if (IsBandWallpaperEnabled) { m_baconMan.TelemetryMan.ReportLog(this, "Updating band wallpaper", SeverityLevel.Verbose); // Make a deferral scope object so we can do our work without being killed. // Note! We need release this object or it will hang the app around forever! m_bandRefDeferral = refDeferral; m_bandRefDeferral.AddRef(); // Kick off the update, this will happen async. GetSubredditStories(BandSubredditName, UpdateTypes.Band); } } // Else full update else { m_baconMan.TelemetryMan.ReportLog(this, "No need for a full update, just rotating."); // If we aren't doing a full update just rotate the images. await DoImageRotation(UpdateTypes.All); // Stop the running state lock (this) { m_isRunning = false; } } } catch (Exception e) { m_baconMan.MessageMan.DebugDia("Failed to set background image", e); m_baconMan.TelemetryMan.ReportUnExpectedEvent(this, "Failed to set background image", e); } }
/// <summary> /// Releases the deferral if it is held. /// </summary> private void ReleaseDeferral() { _refDeferral?.ReleaseRef(); _refDeferral = null; }