1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/ios/scoped_critical_action.h" 6 7 #import <UIKit/UIKit.h> 8 9 #include "base/logging.h" 10 #include "base/synchronization/lock.h" 11 12 namespace base { 13 namespace ios { 14 15 // This implementation calls |beginBackgroundTaskWithExpirationHandler:| when 16 // instantiated and |endBackgroundTask:| when destroyed, creating a scope whose 17 // execution will continue (temporarily) even after the app is backgrounded. 18 ScopedCriticalAction::ScopedCriticalAction() { 19 background_task_id_ = [[UIApplication sharedApplication] 20 beginBackgroundTaskWithExpirationHandler:^{ 21 DLOG(WARNING) << "Background task with id " << background_task_id_ 22 << " expired."; 23 // Note if |endBackgroundTask:| is not called for each task before time 24 // expires, the system kills the application. 25 EndBackgroundTask(); 26 }]; 27 if (background_task_id_ == UIBackgroundTaskInvalid) { 28 DLOG(WARNING) << 29 "beginBackgroundTaskWithExpirationHandler: returned an invalid ID"; 30 } else { 31 VLOG(3) << "Beginning background task with id " << background_task_id_; 32 } 33 } 34 35 ScopedCriticalAction::~ScopedCriticalAction() { 36 EndBackgroundTask(); 37 } 38 39 void ScopedCriticalAction::EndBackgroundTask() { 40 UIBackgroundTaskIdentifier task_id; 41 { 42 AutoLock lock_scope(background_task_id_lock_); 43 if (background_task_id_ == UIBackgroundTaskInvalid) 44 return; 45 task_id = background_task_id_; 46 background_task_id_ = UIBackgroundTaskInvalid; 47 } 48 49 VLOG(3) << "Ending background task with id " << task_id; 50 [[UIApplication sharedApplication] endBackgroundTask:task_id]; 51 } 52 53 } // namespace ios 54 } // namespace base 55