]>
Commit | Line | Data |
---|---|---|
866f8763 A |
1 | /* |
2 | * Copyright (c) 2017 Apple Inc. All Rights Reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | #import <Foundation/Foundation.h> | |
25 | ||
26 | #if OCTAGON | |
866f8763 | 27 | #import <CloudKit/CKContainer_Private.h> |
3f0f0d49 | 28 | #import <CloudKit/CloudKit.h> |
866f8763 | 29 | #include <Security/SecureObjectSync/SOSCloudCircle.h> |
3f0f0d49 A |
30 | #import "keychain/ckks/CKKSCondition.h" |
31 | #import "keychain/ckks/CloudKitDependencies.h" | |
32 | ||
33 | NS_ASSUME_NONNULL_BEGIN | |
866f8763 A |
34 | |
35 | /* | |
36 | * Implements a 'debouncer' to store the current CK account and circle state, and receive updates to it. | |
37 | * | |
38 | * Will only be considered "logged in" if we both have a CK account and are 'in circle'. | |
39 | * | |
40 | * It will notify listeners on account state changes, so multiple repeated account state notifications with the same state are filtered by this class. | |
41 | * Listeners can also get the 'current' state, no matter what it is. They will also then be atomically added to the notification queue, and so will | |
42 | * always receive the next update, preventing them from getting a stale state and missing an immediate update. | |
43 | */ | |
44 | ||
45 | typedef NS_ENUM(NSInteger, CKKSAccountStatus) { | |
46 | /* Set at initialization. This means we haven't figured out what the account state is. */ | |
3f0f0d49 | 47 | CKKSAccountStatusUnknown = 0, |
866f8763 | 48 | /* We have an iCloud account and are in-circle */ |
3f0f0d49 | 49 | CKKSAccountStatusAvailable = 1, |
866f8763 | 50 | /* No iCloud account is logged in on this device, or we're out of circle */ |
3f0f0d49 | 51 | CKKSAccountStatusNoAccount = 3, |
866f8763 A |
52 | }; |
53 | ||
79b9da22 A |
54 | @interface SOSAccountStatus : NSObject |
55 | @property SOSCCStatus status; | |
56 | @property (nullable) NSError* error; | |
57 | - (instancetype)init:(SOSCCStatus)status error:error; | |
58 | @end | |
59 | ||
ecaf5866 | 60 | @protocol CKKSAccountStateListener <NSObject> |
3f0f0d49 | 61 | - (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus; |
866f8763 A |
62 | @end |
63 | ||
64 | @interface CKKSCKAccountStateTracker : NSObject | |
3f0f0d49 | 65 | @property CKKSCondition* finishedInitialDispatches; |
866f8763 A |
66 | |
67 | // If you use these, please be aware they could change out from under you at any time | |
3f0f0d49 | 68 | @property (nullable) CKAccountInfo* currentCKAccountInfo; |
79b9da22 | 69 | @property (nullable) SOSAccountStatus* currentCircleStatus; |
866f8763 | 70 | |
ecaf5866 A |
71 | @property (readonly,atomic) CKKSAccountStatus currentComputedAccountStatus; |
72 | @property (nullable,readonly,atomic) NSError* currentAccountError; | |
73 | @property CKKSCondition* currentComputedAccountStatusValid; | |
74 | ||
866f8763 | 75 | // Fetched and memoized from CloudKit; we can't afford deadlocks with their callbacks |
3f0f0d49 A |
76 | @property (nullable, copy) NSString* ckdeviceID; |
77 | @property (nullable) NSError* ckdeviceIDError; | |
78 | @property CKKSCondition* ckdeviceIDInitialized; | |
866f8763 A |
79 | |
80 | // Fetched and memoized from the Account when we're in-circle; our threading model is strange | |
3f0f0d49 A |
81 | @property (nullable) NSString* accountCirclePeerID; |
82 | @property (nullable) NSError* accountCirclePeerIDError; | |
866f8763 A |
83 | @property CKKSCondition* accountCirclePeerIDInitialized; |
84 | ||
3f0f0d49 | 85 | - (instancetype)init:(CKContainer*)container nsnotificationCenterClass:(Class<CKKSNSNotificationCenter>)nsnotificationCenterClass; |
866f8763 | 86 | |
3f0f0d49 | 87 | - (dispatch_semaphore_t)notifyOnAccountStatusChange:(id<CKKSAccountStateListener>)listener; |
866f8763 A |
88 | |
89 | // Methods useful for testing: | |
90 | ||
91 | // Call this to simulate a notification (and pause the calling thread until all notifications are delivered) | |
3f0f0d49 A |
92 | - (void)notifyCKAccountStatusChangeAndWaitForSignal; |
93 | - (void)notifyCircleStatusChangeAndWaitForSignal; | |
94 | ||
95 | - (dispatch_group_t _Nullable)checkForAllDeliveries; | |
866f8763 | 96 | |
79b9da22 | 97 | + (SOSAccountStatus*)getCircleStatus; |
3f0f0d49 A |
98 | + (void)fetchCirclePeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))callback; |
99 | + (NSString*)stringFromAccountStatus:(CKKSAccountStatus)status; | |
866f8763 A |
100 | |
101 | @end | |
102 | ||
3f0f0d49 A |
103 | NS_ASSUME_NONNULL_END |
104 | #endif // OCTAGON |