Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: ios/web/crw_browsing_data_store.mm

Issue 1215433003: CL for Objective-C readability (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: y Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/web/public/crw_browsing_data_store.h" 5 #import "ios/web/public/crw_browsing_data_store.h"
6 6
7 #import <Foundation/Foundation.h> 7 #import <Foundation/Foundation.h>
8 8
9 #include "base/ios/ios_util.h" 9 #include "base/ios/ios_util.h"
10 #import "base/ios/weak_nsobject.h" 10 #import "base/ios/weak_nsobject.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #import "base/mac/scoped_nsobject.h" 12 #import "base/mac/scoped_nsobject.h"
13 #import "ios/web/browsing_data_managers/crw_cookie_browsing_data_manager.h" 13 #import "ios/web/browsing_data_managers/crw_cookie_browsing_data_manager.h"
14 #include "ios/web/public/active_state_manager.h" 14 #include "ios/web/public/active_state_manager.h"
15 #include "ios/web/public/browser_state.h" 15 #include "ios/web/public/browser_state.h"
16 16
17 namespace { 17 namespace {
18 // Represents the type of operations that a CRWBrowsingDataStore can perform. 18 // Represents the type of operations that a CRWBrowsingDataStore can perform.
19 enum OperationType { 19 enum OperationType {
20 // Represents NOP. 20 // Represents NOP.
21 NONE = 1, 21 NONE = 1,
22 // Stash operation involves stashing browsing data that web views create to 22 // Stash operation involves stashing browsing data that web views create to
23 // the associated BrowserState's state path. 23 // the associated BrowserState's state path.
24 STASH, 24 STASH,
25 // Restore operation involves restoring browsing data from the 25 // Restore operation involves restoring browsing data from the
26 // associated BrowserState's state path so that web views (UIWebViews and 26 // associated BrowserState's state path so that web views can read from them.
27 // WKWebViews) can read from them.
28 RESTORE, 27 RESTORE,
29 // Remove operation involves removing the data that web views create. 28 // Remove operation involves removing the data that web views create.
30 REMOVE, 29 REMOVE,
31 }; 30 };
32 31
33 // The name of the NSOperation that performs a restore operation. 32 // The name of the NSOperation that performs a |RESTORE| operation.
34 NSString* const kRestoreOperationName = @"CRWBrowsingDataStore.RESTORE"; 33 NSString* const kRestoreOperationName = @"CRWBrowsingDataStore.RESTORE";
35 // The name of the NSOperation that performs a stash operation. 34 // The name of the NSOperation that performs a |STASH| operation.
36 NSString* const kStashOperationName = @"CRWBrowsingDataStore.STASH"; 35 NSString* const kStashOperationName = @"CRWBrowsingDataStore.STASH";
37 } // namespace 36 } // namespace
38 37
38 // CRWBrowsingDataStore is implemented using 2 queues.
39 // 1) operationQueueForStashAndRestoreOperations:
40 // - This queue is used to perform |STASH| and |RESTORE| operations.
41 // - |STASH|, |RESTORE| operations are operations that have been explicitly
42 // requested by the user. And the performance of these operations block
43 // further user interaction. Hence this queue has a QoS of
44 // NSQualityOfServiceUserInitiated.
45 // - |STASH|, |RESTORE| operations from 2 different CRWBrowsingDataStores are
46 // not re-entrant. Hence this is a serial queue.
47 // 2) operationQueueForRemoveOperations:
48 // - This queue is used to perform |REMOVE| operations.
49 // - |REMOVE| operations is an operation that has been explicitly requested by
50 // the user. And the performance of this operation blocks further user
51 // interaction. Hence this queue has a QoS of NSQualityOfServiceUserInitiated.
52 // - |REMOVE| operations from 2 different CRWBrowingDataStores can be run in
53 // parallel. Hence this is a concurrent queue.
54 //
55 // |STASH|, |RESTORE|, |REMOVE| operations of a particular CRWBrowsingDataStore
56 // are not re-entrant. Hence these operations are serialized.
57
39 @interface CRWBrowsingDataStore () 58 @interface CRWBrowsingDataStore ()
40 // Returns a serial queue on which stash and restore operations can be scheduled 59 // Redefined to be read-write. Must be called from the main thread.
41 // to be run. All stash/restore operations need to be run on the same queue 60 @property(nonatomic, assign) web::BrowsingDataStoreMode mode;
42 // hence it is shared with all CRWBrowsingDataStores. 61 // The array of all browsing data managers. Must be called from the main
62 // thread.
63 @property(nonatomic, readonly) NSArray* allBrowsingDataManagers;
64 // The number of |STASH| or |RESTORE| operations that are still pending. Must be
65 // called from the main thread.
66 @property(nonatomic, assign) NSUInteger numberOfPendingStashOrRestoreOperations;
67
68 // Returns a serial queue on which |STASH| and |RESTORE| operations can be
69 // scheduled to be run. All |STASH|/|RESTORE| operations need to be run on the
70 // same queue hence it is shared with all CRWBrowsingDataStores.
43 + (NSOperationQueue*)operationQueueForStashAndRestoreOperations; 71 + (NSOperationQueue*)operationQueueForStashAndRestoreOperations;
44 // Returns a concurrent queue on which remove operations can be scheduled to be 72 // Returns a concurrent queue on which remove operations can be scheduled to be
45 // run. All remove operations need to be run on the same queue hence it is 73 // run. All |REMOVE| operations need to be run on the same queue hence it is
46 // shared with all CRWBrowsingDataStores. 74 // shared with all CRWBrowsingDataStores.
47 + (NSOperationQueue*)operationQueueForRemoveOperations; 75 + (NSOperationQueue*)operationQueueForRemoveOperations;
48 - (instancetype)init NS_UNAVAILABLE;
49 76
50 // The array of all browsing data managers. Must be accessed from the main 77 // Returns an array of CRWBrowsingDataManagers for the given
51 // thread. 78 // |browsingDataTypes|.
52 @property(nonatomic, readonly) NSArray* allBrowsingDataManagers;
53 // Returns an array of browsing data managers for the given |browsingDataTypes|.
54 - (NSArray*)browsingDataManagersForBrowsingDataTypes: 79 - (NSArray*)browsingDataManagersForBrowsingDataTypes:
55 (web::BrowsingDataTypes)browsingDataTypes; 80 (web::BrowsingDataTypes)browsingDataTypes;
56 // Returns the selector that needs to be performed on the 81 // Returns the selector that needs to be performed on the
57 // CRWBrowsingDataManagers for the |operationType|. |operationType| cannot be 82 // CRWBrowsingDataManagers for the |operationType|. |operationType| cannot be
58 // |NONE|. 83 // |NONE|.
59 - (SEL)browsingDataManagerSelectorForOperationType:(OperationType)operationType; 84 - (SEL)browsingDataManagerSelectorForOperationType:(OperationType)operationType;
60 // Returns the selector that needs to be performed on the 85 // Returns the selector that needs to be performed on the
61 // CRWBrowsingDataManagers for a REMOVE operation. 86 // CRWBrowsingDataManagers for a |REMOVE| operation.
62 - (SEL)browsingDataManagerSelectorForRemoveOperationType; 87 - (SEL)browsingDataManagerSelectorForRemoveOperationType;
63 88
64 // Redefined to be read-write. Must be called from the main thread. 89 // Sets the mode iff there are no more |STASH| or |RESTORE| operations that are
65 @property(nonatomic, assign) web::BrowsingDataStoreMode mode;
66 // Sets the mode iff there are no more stash or restore operations that are
67 // still pending. |mode| can only be either |ACTIVE| or |INACTIVE|. 90 // still pending. |mode| can only be either |ACTIVE| or |INACTIVE|.
68 // |handler| is called immediately (in the same runloop) with a BOOL indicating 91 // Returns YES if the mode was successfully changed to |mode|.
69 // whether the mode change was successful or not. |handler| can be nil. 92 - (BOOL)finalizeChangeToMode:(web::BrowsingDataStoreMode)mode;
70 - (void)finalizeChangeToMode:(web::BrowsingDataStoreMode)mode
71 andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler;
72
73 // Changes the mode of the CRWBrowsingDataStore to |mode|. This is an 93 // Changes the mode of the CRWBrowsingDataStore to |mode|. This is an
74 // asynchronous operation and the mode is not changed immediately. 94 // asynchronous operation and the mode is not changed immediately.
75 // |completionHandler| can be nil. 95 // |completionHandler| can be nil.
76 // |completionHandler| is called on the main thread. This block has no return 96 // |completionHandler| is called on the main thread. This block has no return
77 // value and takes a single BOOL argument that indicates whether or not the 97 // value and takes a single BOOL argument that indicates whether or not the
78 // mode change was successfully changed to |mode|. 98 // mode change was successfully changed to |mode|.
79 - (void)changeMode:(web::BrowsingDataStoreMode)mode 99 - (void)changeMode:(web::BrowsingDataStoreMode)mode
80 completionHandler:(void (^)(BOOL modeChangeWasSuccessful))completionHandler; 100 completionHandler:(void (^)(BOOL modeChangeWasSuccessful))completionHandler;
81 101
82 // The number of stash or restore operations that are still pending. 102 // Returns the OperationType (that needs to be performed) in order to change the
83 @property(nonatomic, assign) NSUInteger numberOfPendingStashOrRestoreOperations; 103 // mode to |mode|. Consults the delegate if one is present. |mode| cannot be
84 104 // |CHANGING|.
85 // Performs operations of type |operationType| on each of the 105 - (OperationType)operationTypeToChangeMode:(web::BrowsingDataStoreMode)mode;
106 // Performs an operation of type |operationType| on each of the
86 // |browsingDataManagers|. |operationType| cannot be |NONE|. 107 // |browsingDataManagers|. |operationType| cannot be |NONE|.
87 // Precondition: There must be no web views associated with the BrowserState. 108 // Precondition: There must be no web views associated with the BrowserState.
88 // |completionHandler| is called on the main thread and cannot be nil. 109 // |completionHandler| is called on the main thread and cannot be nil.
89 - (void)performOperationWithType:(OperationType)operationType 110 - (void)performOperationWithType:(OperationType)operationType
90 browsingDataManagers:(NSArray*)browsingDataManagers 111 browsingDataManagers:(NSArray*)browsingDataManagers
91 completionHandler:(ProceduralBlock)completionHandler; 112 completionHandler:(ProceduralBlock)completionHandler;
92 113 // Returns an NSOperation that calls |selector| on all the
93 // Creates an NSOperation that calls |selector| on all the
94 // |browsingDataManagers|. |selector| needs to be one of the methods in 114 // |browsingDataManagers|. |selector| needs to be one of the methods in
95 // CRWBrowsingDataManager. 115 // CRWBrowsingDataManager.
96 - (NSOperation*) 116 - (NSOperation*)operationWithBrowsingDataManagers:(NSArray*)browsingDataManagers
97 newOperationWithBrowsingDataManagers:(NSArray*)browsingDataManagers 117 selector:(SEL)selector;
98 selector:(SEL)selector;
99 // Enqueues |operation| to be run on |queue|. All operations are serialized to 118 // Enqueues |operation| to be run on |queue|. All operations are serialized to
100 // be run one after another. 119 // be run one after another.
101 - (void)addOperation:(NSOperation*)operation toQueue:(NSOperationQueue*)queue; 120 - (void)addOperation:(NSOperation*)operation toQueue:(NSOperationQueue*)queue;
102 @end 121 @end
103 122
104 @implementation CRWBrowsingDataStore { 123 @implementation CRWBrowsingDataStore {
105 web::BrowserState* _browserState; // Weak, owns this object. 124 web::BrowserState* _browserState; // Weak, owns this object.
106 // The delegate. 125 // The delegate.
107 base::WeakNSProtocol<id<CRWBrowsingDataStoreDelegate>> _delegate; 126 base::WeakNSProtocol<id<CRWBrowsingDataStoreDelegate>> _delegate;
108 // The mode of the CRWBrowsingDataStore. 127 // The mode of the CRWBrowsingDataStore.
109 web::BrowsingDataStoreMode _mode; 128 web::BrowsingDataStoreMode _mode;
110 // The dictionary that maps a browsing data type to its 129 // The dictionary that maps a browsing data type to its
111 // CRWBrowsingDataManager. 130 // CRWBrowsingDataManager.
112 base::scoped_nsobject<NSDictionary> _browsingDataTypeMap; 131 base::scoped_nsobject<NSDictionary> _browsingDataTypeMap;
113 // The last operation that was enqueued to be run. Can be stash, restore or a 132 // The last operation that was enqueued to be run. Can be a |STASH|, |RESTORE|
114 // delete operation. 133 // or a |REMOVE| operation.
115 base::scoped_nsobject<NSOperation> _lastDispatchedOperation; 134 base::scoped_nsobject<NSOperation> _lastDispatchedOperation;
116 // The last dispatched stash or restore operation that was enqueued to be run. 135 // The last dispatched |STASH| or |RESTORE| operation that was enqueued to be
136 // run.
117 base::scoped_nsobject<NSOperation> _lastDispatchedStashOrRestoreOperation; 137 base::scoped_nsobject<NSOperation> _lastDispatchedStashOrRestoreOperation;
118 // The number of stash or restore operations that are still pending. If this 138 // The number of |STASH| or |RESTORE| operations that are still pending. If
119 // value > 0 the mode of the CRWBrowsingDataStore is |CHANGING|. The mode 139 // the number of |STASH| or |RESTORE| operations is greater than 0U, the mode
120 // can be made ACTIVE or INACTIVE only be set when this value is 0. 140 // of the CRWBrowsingDataStore is |CHANGING|. The mode can be made ACTIVE or
141 // INACTIVE only be set when this value is 0U.
121 NSUInteger _numberOfPendingStashOrRestoreOperations; 142 NSUInteger _numberOfPendingStashOrRestoreOperations;
122 } 143 }
123 144
124 + (NSOperationQueue*)operationQueueForStashAndRestoreOperations { 145 #pragma mark -
125 static dispatch_once_t onceToken = 0; 146 #pragma mark NSObject Methods
126 static NSOperationQueue* operationQueueForStashAndRestoreOperations = nil;
127 dispatch_once(&onceToken, ^{
128 operationQueueForStashAndRestoreOperations =
129 [[NSOperationQueue alloc] init];
130 [operationQueueForStashAndRestoreOperations
131 setMaxConcurrentOperationCount:1U];
132 if (base::ios::IsRunningOnIOS8OrLater()) {
133 [operationQueueForStashAndRestoreOperations
134 setQualityOfService:NSQualityOfServiceUserInteractive];
135 }
136 });
137 return operationQueueForStashAndRestoreOperations;
138 }
139
140 + (NSOperationQueue*)operationQueueForRemoveOperations {
141 static dispatch_once_t onceToken = 0;
142 static NSOperationQueue* operationQueueForRemoveOperations = nil;
143 dispatch_once(&onceToken, ^{
144 operationQueueForRemoveOperations = [[NSOperationQueue alloc] init];
145 [operationQueueForRemoveOperations
146 setMaxConcurrentOperationCount:NSUIntegerMax];
147 if (base::ios::IsRunningOnIOS8OrLater()) {
148 [operationQueueForRemoveOperations
149 setQualityOfService:NSQualityOfServiceUserInitiated];
150 }
151 });
152 return operationQueueForRemoveOperations;
153 }
154 147
155 - (instancetype)initWithBrowserState:(web::BrowserState*)browserState { 148 - (instancetype)initWithBrowserState:(web::BrowserState*)browserState {
156 self = [super init]; 149 self = [super init];
157 if (self) { 150 if (self) {
158 DCHECK([NSThread isMainThread]); 151 DCHECK([NSThread isMainThread]);
152 DCHECK(browserState);
159 // TODO(shreyasv): Instantiate the necessary CRWBrowsingDataManagers that 153 // TODO(shreyasv): Instantiate the necessary CRWBrowsingDataManagers that
160 // are encapsulated within this class. crbug.com/480654. 154 // are encapsulated within this class. crbug.com/480654.
161 _browserState = browserState; 155 _browserState = browserState;
162 web::ActiveStateManager* activeStateManager = 156 web::ActiveStateManager* activeStateManager =
163 web::BrowserState::GetActiveStateManager(browserState); 157 web::BrowserState::GetActiveStateManager(browserState);
164 DCHECK(activeStateManager); 158 DCHECK(activeStateManager);
165 _mode = activeStateManager->IsActive() ? web::ACTIVE : web::INACTIVE; 159 _mode = activeStateManager->IsActive() ? web::ACTIVE : web::INACTIVE;
166 // TODO(shreyasv): If the creation of CRWBrowsingDataManagers turns out to 160 // TODO(shreyasv): If the creation of CRWBrowsingDataManagers turns out to
167 // be an expensive operations re-visit this with a lazy-evaluation approach. 161 // be an expensive operations re-visit this with a lazy-evaluation approach.
168 base::scoped_nsobject<CRWCookieBrowsingDataManager> 162 base::scoped_nsobject<CRWCookieBrowsingDataManager>
169 cookieBrowsingDataManager([[CRWCookieBrowsingDataManager alloc] 163 cookieBrowsingDataManager([[CRWCookieBrowsingDataManager alloc]
170 initWithBrowserState:browserState]); 164 initWithBrowserState:browserState]);
171 _browsingDataTypeMap.reset([@{ 165 _browsingDataTypeMap.reset([@{
172 @(web::BROWSING_DATA_TYPE_COOKIES) : cookieBrowsingDataManager, 166 @(web::BROWSING_DATA_TYPE_COOKIES) : cookieBrowsingDataManager,
173 } retain]); 167 } retain]);
174 } 168 }
175 return self; 169 return self;
176 } 170 }
177 171
178 - (instancetype)init { 172 - (instancetype)init {
Eugene But (OOO till 7-30) 2015/07/09 20:08:08 You don't need this since you marked it as NS_UNA
shreyasv1 2015/07/10 17:06:22 Removed here and in the unittest.
179 NOTREACHED(); 173 NOTREACHED();
180 return nil; 174 return nil;
181 } 175 }
182 176
183 - (NSString*)description { 177 - (NSString*)description {
184 NSString* format = @"<%@: %p; hasPendingOperations = { %@ }>"; 178 NSString* format = @"<%@: %p; hasPendingOperations = { %@ }; mode = { %@ }>";
185 NSString* hasPendingOperationsString = 179 NSString* hasPendingOperationsString =
186 [self hasPendingOperations] ? @"YES" : @"NO"; 180 [self hasPendingOperations] ? @"YES" : @"NO";
187 NSString* result = 181 NSString* modeString = nil;
188 [NSString stringWithFormat:format, NSStringFromClass(self.class), self, 182 switch (self.mode) {
189 hasPendingOperationsString]; 183 case web::ACTIVE:
184 modeString = @"ACTIVE";
185 break;
186 case web::CHANGING:
187 modeString = @"CHANGING";
188 break;
189 case web::INACTIVE:
190 modeString = @"INACTIVE";
191 break;
192 }
193 NSString* result = [NSString stringWithFormat:format,
194 NSStringFromClass(self.class), self, hasPendingOperationsString,
195 modeString];
190 return result; 196 return result;
191 } 197 }
192 198
199 + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key {
200 // It is necessary to override this for |mode| because the default KVO
201 // behavior in NSObject is to fire a notification irrespective of if an actual
202 // change was made to the ivar or not. The |mode| property needs fine grained
203 // control over the actual notifications being fired since observers need to
204 // be notified iff the |mode| actually changed.
205 if ([key isEqual:@"mode"]) {
206 return NO;
207 }
208 return [super automaticallyNotifiesObserversForKey:key];
209 }
210
211 #pragma mark -
212 #pragma mark Public Properties
213
214 - (id<CRWBrowsingDataStoreDelegate>)delegate {
215 return _delegate;
216 }
217
218 - (void)setDelegate:(id<CRWBrowsingDataStoreDelegate>)delegate {
219 _delegate.reset(delegate);
220 }
221
222 - (web::BrowsingDataStoreMode)mode {
223 DCHECK([NSThread isMainThread]);
224 return _mode;
225 }
226
227 - (BOOL)hasPendingOperations {
228 if (!_lastDispatchedOperation) {
229 return NO;
230 }
231 return ![_lastDispatchedOperation isFinished];
232 }
233
234 #pragma mark -
235 #pragma mark Public Methods
236
237 - (void)makeActiveWithCompletionHandler:
238 (void (^)(BOOL success))completionHandler {
239 DCHECK([NSThread isMainThread]);
240 // TODO(shreyasv): Verify the preconditions for this method when
241 // web::WebViewCounter class is implemented. crbug.com/480507.
242
243 [self changeMode:web::ACTIVE completionHandler:completionHandler];
244 }
245
246 - (void)makeInactiveWithCompletionHandler:
247 (void (^)(BOOL success))completionHandler {
248 DCHECK([NSThread isMainThread]);
249 // TODO(shreyasv): Verify the preconditions for this method when
250 // web::WebViewCounter class is implemented. crbug.com/480507.
251
252 [self changeMode:web::INACTIVE completionHandler:completionHandler];
253 }
254
255 - (void)removeDataOfTypes:(web::BrowsingDataTypes)browsingDataTypes
256 completionHandler:(ProceduralBlock)completionHandler {
257 DCHECK([NSThread isMainThread]);
258 // TODO(shreyasv): Verify the preconditions for this method when
259 // web::WebViewCounter class is implemented. crbug.com/480507.
260
261 NSArray* browsingDataManagers =
262 [self browsingDataManagersForBrowsingDataTypes:browsingDataTypes];
263 [self performOperationWithType:REMOVE
264 browsingDataManagers:browsingDataManagers
265 completionHandler:completionHandler];
266 }
267
268 #pragma mark -
269 #pragma mark Private Properties
270
271 - (void)setMode:(web::BrowsingDataStoreMode)mode {
272 DCHECK([NSThread isMainThread]);
273
274 if (_mode == mode) {
275 return;
276 }
277 if (mode == web::ACTIVE || mode == web::INACTIVE) {
278 DCHECK(!self.numberOfPendingStashOrRestoreOperations);
279 }
280 [self willChangeValueForKey:@"mode"];
281 _mode = mode;
282 [self didChangeValueForKey:@"mode"];
283 }
193 284
194 - (NSArray*)allBrowsingDataManagers { 285 - (NSArray*)allBrowsingDataManagers {
195 DCHECK([NSThread isMainThread]); 286 DCHECK([NSThread isMainThread]);
196 return [_browsingDataTypeMap allValues]; 287 return [_browsingDataTypeMap allValues];
197 } 288 }
198 289
290 - (NSUInteger)numberOfPendingStashOrRestoreOperations {
291 DCHECK([NSThread isMainThread]);
292 return _numberOfPendingStashOrRestoreOperations;
293 }
294
295 - (void)setNumberOfPendingStashOrRestoreOperations:
296 (NSUInteger)numberOfPendingStashOrRestoreOperations {
297 DCHECK([NSThread isMainThread]);
298 _numberOfPendingStashOrRestoreOperations =
299 numberOfPendingStashOrRestoreOperations;
300 }
301
302 #pragma mark -
303 #pragma mark Private Class Methods
304
305 + (NSOperationQueue*)operationQueueForStashAndRestoreOperations {
306 static dispatch_once_t onceToken = 0;
307 static NSOperationQueue* operationQueueForStashAndRestoreOperations = nil;
308 dispatch_once(&onceToken, ^{
309 operationQueueForStashAndRestoreOperations =
310 [[NSOperationQueue alloc] init];
311 [operationQueueForStashAndRestoreOperations
312 setMaxConcurrentOperationCount:1U];
313 if (base::ios::IsRunningOnIOS8OrLater()) {
314 [operationQueueForStashAndRestoreOperations
315 setQualityOfService:NSQualityOfServiceUserInitiated];
316 }
317 });
318 return operationQueueForStashAndRestoreOperations;
319 }
320
321 + (NSOperationQueue*)operationQueueForRemoveOperations {
322 static dispatch_once_t onceToken = 0;
323 static NSOperationQueue* operationQueueForRemoveOperations = nil;
324 dispatch_once(&onceToken, ^{
325 operationQueueForRemoveOperations = [[NSOperationQueue alloc] init];
326 [operationQueueForRemoveOperations
327 setMaxConcurrentOperationCount:NSUIntegerMax];
328 if (base::ios::IsRunningOnIOS8OrLater()) {
329 [operationQueueForRemoveOperations
330 setQualityOfService:NSQualityOfServiceUserInitiated];
331 }
332 });
333 return operationQueueForRemoveOperations;
334 }
335
336 #pragma mark -
337 #pragma mark Private Methods
338
199 - (NSArray*)browsingDataManagersForBrowsingDataTypes: 339 - (NSArray*)browsingDataManagersForBrowsingDataTypes:
200 (web::BrowsingDataTypes)browsingDataTypes { 340 (web::BrowsingDataTypes)browsingDataTypes {
201 __block NSMutableArray* result = [NSMutableArray array]; 341 __block NSMutableArray* result = [NSMutableArray array];
202 [_browsingDataTypeMap 342 [_browsingDataTypeMap
203 enumerateKeysAndObjectsUsingBlock:^(NSNumber* dataType, 343 enumerateKeysAndObjectsUsingBlock:^(NSNumber* dataType,
204 id<CRWBrowsingDataManager> manager, 344 id<CRWBrowsingDataManager> manager,
205 BOOL*) { 345 BOOL*) {
206 if ([dataType unsignedIntegerValue] & browsingDataTypes) { 346 if ([dataType unsignedIntegerValue] & browsingDataTypes) {
207 [result addObject:manager]; 347 [result addObject:manager];
208 } 348 }
209 }]; 349 }];
210 return result; 350 return result;
211 } 351 }
212 352
213 - (id<CRWBrowsingDataStoreDelegate>)delegate {
214 return _delegate;
215 }
216
217 - (void)setDelegate:(id<CRWBrowsingDataStoreDelegate>)delegate {
218 _delegate.reset(delegate);
219 }
220
221 - (SEL)browsingDataManagerSelectorForOperationType: 353 - (SEL)browsingDataManagerSelectorForOperationType:
222 (OperationType)operationType { 354 (OperationType)operationType {
223 switch (operationType) { 355 switch (operationType) {
224 case NONE: 356 case NONE:
225 NOTREACHED(); 357 NOTREACHED();
226 return nullptr; 358 return nullptr;
227 case STASH: 359 case STASH:
228 return @selector(stashData); 360 return @selector(stashData);
229 case RESTORE: 361 case RESTORE:
230 return @selector(restoreData); 362 return @selector(restoreData);
231 case REMOVE: 363 case REMOVE:
232 return [self browsingDataManagerSelectorForRemoveOperationType]; 364 return [self browsingDataManagerSelectorForRemoveOperationType];
233 }; 365 };
234 NOTREACHED();
235 return nullptr;
236 } 366 }
237 367
238 - (SEL)browsingDataManagerSelectorForRemoveOperationType { 368 - (SEL)browsingDataManagerSelectorForRemoveOperationType {
239 if (self.mode == web::ACTIVE) { 369 if (self.mode == web::ACTIVE) {
240 return @selector(removeDataAtCanonicalPath); 370 return @selector(removeDataAtCanonicalPath);
241 } 371 }
242 if (self.mode == web::INACTIVE) { 372 if (self.mode == web::INACTIVE) {
243 return @selector(removeDataAtStashPath); 373 return @selector(removeDataAtStashPath);
244 } 374 }
375 // Since the mode is |CHANGING|, find the last |STASH| or |RESTORE| operation
376 // that was enqueued in order to find out the eventual mode that the
377 // CRWBrowsingDataStore will be in when this |REMOVE| operation is run.
245 DCHECK(_lastDispatchedStashOrRestoreOperation); 378 DCHECK(_lastDispatchedStashOrRestoreOperation);
246 NSString* lastDispatchedStashOrRestoreOperationName = 379 NSString* lastDispatchedStashOrRestoreOperationName =
247 [_lastDispatchedStashOrRestoreOperation name]; 380 [_lastDispatchedStashOrRestoreOperation name];
248 if ([lastDispatchedStashOrRestoreOperationName 381 if ([lastDispatchedStashOrRestoreOperationName
249 isEqual:kRestoreOperationName]) { 382 isEqual:kRestoreOperationName]) {
250 return @selector(removeDataAtCanonicalPath); 383 return @selector(removeDataAtCanonicalPath);
251 } 384 }
252 if ([lastDispatchedStashOrRestoreOperationName isEqual:kStashOperationName]) { 385 if ([lastDispatchedStashOrRestoreOperationName isEqual:kStashOperationName]) {
253 return @selector(removeDataAtStashPath); 386 return @selector(removeDataAtStashPath);
254 } 387 }
255 NOTREACHED(); 388 NOTREACHED();
256 return nullptr; 389 return nullptr;
257 } 390 }
258 391
259 + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key { 392 - (BOOL)finalizeChangeToMode:(web::BrowsingDataStoreMode)mode {
260 // It is necessary to override this for |mode| because the default KVO
261 // behavior in NSObject is to fire a notification irrespective of if an actual
262 // change was made to the ivar or not. The |mode| property needs fine grained
263 // control over the actual notifications being fired since observers need to
264 // be notified iff the |mode| actually changed.
265 if ([key isEqual:@"mode"]) {
266 return NO;
267 }
268 return [super automaticallyNotifiesObserversForKey:(NSString*)key];
269 }
270
271 - (web::BrowsingDataStoreMode)mode {
272 DCHECK([NSThread isMainThread]);
273 return _mode;
274 }
275
276 - (void)setMode:(web::BrowsingDataStoreMode)mode {
277 DCHECK([NSThread isMainThread]);
278 if (_mode == mode) {
279 return;
280 }
281 if (mode == web::ACTIVE || mode == web::INACTIVE) {
282 DCHECK(!self.numberOfPendingStashOrRestoreOperations);
283 }
284 [self willChangeValueForKey:@"mode"];
285 _mode = mode;
286 [self didChangeValueForKey:@"mode"];
287 }
288
289 - (void)finalizeChangeToMode:(web::BrowsingDataStoreMode)mode
290 andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler {
291 DCHECK([NSThread isMainThread]); 393 DCHECK([NSThread isMainThread]);
292 DCHECK_NE(web::CHANGING, mode); 394 DCHECK_NE(web::CHANGING, mode);
293 395
294 BOOL modeChangeWasSuccessful = NO; 396 BOOL modeChangeWasSuccessful = NO;
295 if (!self.numberOfPendingStashOrRestoreOperations) { 397 if (!self.numberOfPendingStashOrRestoreOperations) {
296 [self setMode:mode]; 398 [self setMode:mode];
297 modeChangeWasSuccessful = YES; 399 modeChangeWasSuccessful = YES;
298 } 400 }
299 if (handler) { 401 return modeChangeWasSuccessful;
300 handler(modeChangeWasSuccessful);
301 }
302 }
303
304 - (NSUInteger)numberOfPendingStashOrRestoreOperations {
305 DCHECK([NSThread isMainThread]);
306 return _numberOfPendingStashOrRestoreOperations;
307 }
308
309 - (void)setNumberOfPendingStashOrRestoreOperations:
310 (NSUInteger)numberOfPendingStashOrRestoreOperations {
311 DCHECK([NSThread isMainThread]);
312 _numberOfPendingStashOrRestoreOperations =
313 numberOfPendingStashOrRestoreOperations;
314 }
315
316 - (void)makeActiveWithCompletionHandler:
317 (void (^)(BOOL success))completionHandler {
318 DCHECK([NSThread isMainThread]);
319
320 [self changeMode:web::ACTIVE completionHandler:completionHandler];
321 }
322
323 - (void)makeInactiveWithCompletionHandler:
324 (void (^)(BOOL success))completionHandler {
325 DCHECK([NSThread isMainThread]);
326
327 [self changeMode:web::INACTIVE completionHandler:completionHandler];
328 } 402 }
329 403
330 - (void)changeMode:(web::BrowsingDataStoreMode)mode 404 - (void)changeMode:(web::BrowsingDataStoreMode)mode
331 completionHandler: 405 completionHandler:
332 (void (^)(BOOL modeChangeWasSuccessful))completionHandler { 406 (void (^)(BOOL modeChangeWasSuccessful))completionHandler {
333 DCHECK([NSThread isMainThread]); 407 DCHECK([NSThread isMainThread]);
334 408
335 ProceduralBlock completionHandlerAfterPerformingOperation = ^{ 409 ProceduralBlock completionHandlerAfterPerformingOperation = ^{
336 [self finalizeChangeToMode:mode andCallCompletionHandler:completionHandler]; 410 BOOL modeChangeWasSuccessful = [self finalizeChangeToMode:mode];
411 if (completionHandler) {
412 completionHandler(modeChangeWasSuccessful);
413 }
337 }; 414 };
338 415
339 // Already in the desired mode. 416 OperationType operationType = [self operationTypeToChangeMode:mode];
340 if (self.mode == mode) { 417 if (operationType == NONE) {
341 // As a caller of this API, it is awkward to get the callback before the 418 // As a caller of this API, it is awkward to get the callback before the
342 // method call has completed, hence defer it. 419 // method call has completed, hence defer it.
343 dispatch_async(dispatch_get_main_queue(), ^{ 420 dispatch_async(dispatch_get_main_queue(),
344 completionHandlerAfterPerformingOperation(); 421 completionHandlerAfterPerformingOperation);
345 }); 422 } else {
346 return; 423 [self performOperationWithType:operationType
424 browsingDataManagers:[self allBrowsingDataManagers]
425 completionHandler:completionHandlerAfterPerformingOperation];
347 } 426 }
427 }
428
429 - (OperationType)operationTypeToChangeMode:(web::BrowsingDataStoreMode)mode {
430 DCHECK_NE(web::CHANGING, mode);
348 431
349 OperationType operationType = NONE; 432 OperationType operationType = NONE;
350 if (mode == web::ACTIVE) { 433 if (mode == self.mode) {
434 // Already in the desired mode.
435 operationType = NONE;
436 } else if (mode == web::ACTIVE) {
351 // By default a |RESTORE| operation is performed when the mode is changed 437 // By default a |RESTORE| operation is performed when the mode is changed
352 // to |ACTIVE|. 438 // to |ACTIVE|.
353 operationType = RESTORE; 439 operationType = RESTORE;
354 web::BrowsingDataStoreMakeActivePolicy makeActivePolicy = 440 web::BrowsingDataStoreMakeActivePolicy makeActivePolicy =
355 [_delegate decideMakeActiveOperationPolicyForBrowsingDataStore:self]; 441 [_delegate decideMakeActiveOperationPolicyForBrowsingDataStore:self];
356 operationType = (makeActivePolicy == web::ADOPT) ? REMOVE : RESTORE; 442 operationType = (makeActivePolicy == web::ADOPT) ? REMOVE : RESTORE;
357 } else { 443 } else {
358 // By default a |STASH| operation is performed when the mode is changed to 444 // By default a |STASH| operation is performed when the mode is changed to
359 // |INACTIVE|. 445 // |INACTIVE|.
360 operationType = STASH; 446 operationType = STASH;
361 web::BrowsingDataStoreMakeInactivePolicy makeInactivePolicy = 447 web::BrowsingDataStoreMakeInactivePolicy makeInactivePolicy =
362 [_delegate decideMakeInactiveOperationPolicyForBrowsingDataStore:self]; 448 [_delegate decideMakeInactiveOperationPolicyForBrowsingDataStore:self];
363 operationType = (makeInactivePolicy == web::DELETE) ? REMOVE : STASH; 449 operationType = (makeInactivePolicy == web::DELETE) ? REMOVE : STASH;
364 } 450 }
365 DCHECK_NE(NONE, operationType); 451 return operationType;
366 [self performOperationWithType:operationType
367 browsingDataManagers:[self allBrowsingDataManagers]
368 completionHandler:completionHandlerAfterPerformingOperation];
369 }
370
371 - (void)removeDataOfTypes:(web::BrowsingDataTypes)browsingDataTypes
372 completionHandler:(ProceduralBlock)completionHandler {
373 DCHECK([NSThread isMainThread]);
374
375 NSArray* browsingDataManagers =
376 [self browsingDataManagersForBrowsingDataTypes:browsingDataTypes];
377 [self performOperationWithType:REMOVE
378 browsingDataManagers:browsingDataManagers
379 completionHandler:^{
380 // Since this may be called on a background thread, bounce to
381 // the main thread.
382 dispatch_async(dispatch_get_main_queue(), completionHandler);
383 }];
384 }
385
386 - (BOOL)hasPendingOperations {
387 if (!_lastDispatchedOperation) {
388 return NO;
389 }
390 return ![_lastDispatchedOperation isFinished];
391 } 452 }
392 453
393 - (void)performOperationWithType:(OperationType)operationType 454 - (void)performOperationWithType:(OperationType)operationType
394 browsingDataManagers:(NSArray*)browsingDataManagers 455 browsingDataManagers:(NSArray*)browsingDataManagers
395 completionHandler:(ProceduralBlock)completionHandler { 456 completionHandler:(ProceduralBlock)completionHandler {
396 DCHECK([NSThread isMainThread]); 457 DCHECK([NSThread isMainThread]);
397 DCHECK(completionHandler); 458 DCHECK(completionHandler);
398 DCHECK_NE(NONE, operationType); 459 DCHECK_NE(NONE, operationType);
399 460
400 SEL selector = 461 SEL selector =
401 [self browsingDataManagerSelectorForOperationType:operationType]; 462 [self browsingDataManagerSelectorForOperationType:operationType];
402 DCHECK(selector); 463 DCHECK(selector);
403 464
404 if (operationType == RESTORE || operationType == STASH) { 465 if (operationType == RESTORE || operationType == STASH) {
405 [self setMode:web::CHANGING]; 466 [self setMode:web::CHANGING];
406 ++self.numberOfPendingStashOrRestoreOperations; 467 ++self.numberOfPendingStashOrRestoreOperations;
407 completionHandler = ^{ 468 completionHandler = ^{
408 --self.numberOfPendingStashOrRestoreOperations; 469 --self.numberOfPendingStashOrRestoreOperations;
409 // It is safe to this and does not lead to the block (|completionHandler|) 470 // It is safe to this and does not lead to the block (|completionHandler|)
410 // retaining itself. 471 // retaining itself.
411 completionHandler(); 472 completionHandler();
412 }; 473 };
413 } 474 }
414 475
415 ProceduralBlock callCompletionHandlerOnMainThread = ^{ 476 ProceduralBlock callCompletionHandlerOnMainThread = ^{
416 // This is called on a background thread, hence the need to bounce to the 477 // This is called on a background thread, hence the need to bounce to the
417 // main thread. 478 // main thread.
418 dispatch_async(dispatch_get_main_queue(), ^{ 479 dispatch_async(dispatch_get_main_queue(), completionHandler);
419 completionHandler();
420 });
421 }; 480 };
422 base::scoped_nsobject<NSOperation> operation( 481 NSOperation* operation =
423 [self newOperationWithBrowsingDataManagers:browsingDataManagers 482 [self operationWithBrowsingDataManagers:browsingDataManagers
424 selector:selector]); 483 selector:selector];
425 484
426 if (operationType == RESTORE || operationType == STASH) { 485 if (operationType == RESTORE || operationType == STASH) {
427 [operation setName:(RESTORE ? kRestoreOperationName : kStashOperationName)]; 486 [operation setName:(RESTORE ? kRestoreOperationName : kStashOperationName)];
428 _lastDispatchedStashOrRestoreOperation.reset([operation retain]); 487 _lastDispatchedStashOrRestoreOperation.reset([operation retain]);
429 } 488 }
430 489
431 NSOperationQueue* queue = nil; 490 NSOperationQueue* queue = nil;
432 switch (operationType) { 491 switch (operationType) {
492 case NONE:
493 NOTREACHED();
494 break;
433 case STASH: 495 case STASH:
434 case RESTORE: 496 case RESTORE:
435 queue = [CRWBrowsingDataStore operationQueueForStashAndRestoreOperations]; 497 queue = [CRWBrowsingDataStore operationQueueForStashAndRestoreOperations];
436 break; 498 break;
437 case REMOVE: 499 case REMOVE:
438 queue = [CRWBrowsingDataStore operationQueueForRemoveOperations]; 500 queue = [CRWBrowsingDataStore operationQueueForRemoveOperations];
439 break; 501 break;
440 default:
441 NOTREACHED();
442 break;
443 } 502 }
444 503
445 NSOperation* completionHandlerOperation = [NSBlockOperation 504 NSOperation* completionHandlerOperation = [NSBlockOperation
446 blockOperationWithBlock:callCompletionHandlerOnMainThread]; 505 blockOperationWithBlock:callCompletionHandlerOnMainThread];
447 506
448 [self addOperation:operation toQueue:queue]; 507 [self addOperation:operation toQueue:queue];
449 [self addOperation:completionHandlerOperation toQueue:queue]; 508 [self addOperation:completionHandlerOperation toQueue:queue];
450 } 509 }
451 510
452 - (NSOperation*) 511 - (NSOperation*)operationWithBrowsingDataManagers:(NSArray*)browsingDataManagers
453 newOperationWithBrowsingDataManagers:(NSArray*)browsingDataManagers 512 selector:(SEL)selector {
454 selector:(SEL)selector { 513 NSBlockOperation* operation = [[[NSBlockOperation alloc] init] autorelease];
455 NSBlockOperation* operation = [[NSBlockOperation alloc] init];
456 for (id<CRWBrowsingDataManager> manager : browsingDataManagers) { 514 for (id<CRWBrowsingDataManager> manager : browsingDataManagers) {
457 // |addExecutionBlock| farms out the different blocks added to it. hence the 515 // |addExecutionBlock| farms out the different blocks added to it. hence the
458 // operations are implicitly parallelized. 516 // operations are implicitly parallelized.
459 [operation addExecutionBlock:^{ 517 [operation addExecutionBlock:^{
460 [manager performSelector:selector]; 518 [manager performSelector:selector];
461 }]; 519 }];
462 } 520 }
463 return operation; 521 return operation;
464 } 522 }
465 523
466 - (void)addOperation:(NSOperation*)operation toQueue:(NSOperationQueue*)queue { 524 - (void)addOperation:(NSOperation*)operation toQueue:(NSOperationQueue*)queue {
467 DCHECK([NSThread isMainThread]); 525 DCHECK([NSThread isMainThread]);
468 DCHECK(operation); 526 DCHECK(operation);
469 DCHECK(queue); 527 DCHECK(queue);
470 528
471 if (_lastDispatchedOperation) { 529 if (_lastDispatchedOperation) {
472 [operation addDependency:_lastDispatchedOperation]; 530 [operation addDependency:_lastDispatchedOperation];
473 } 531 }
474 _lastDispatchedOperation.reset([operation retain]); 532 _lastDispatchedOperation.reset([operation retain]);
475 [queue addOperation:operation]; 533 [queue addOperation:operation];
476 } 534 }
477 535
478 @end 536 @end
OLDNEW
« no previous file with comments | « no previous file | ios/web/crw_browsing_data_store_unittest.mm » ('j') | ios/web/public/crw_browsing_data_store.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698