1/* 2 * Copyright (c) 2012-2013 Apple Computer, 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// 25// CKDUserInteraction.m 26// CloudKeychainProxy 27// 28 29#import <CoreFoundation/CFUserNotification.h> 30#import <utilities/debugging.h> 31 32#import "CKDUserInteraction.h" 33#import "SOSARCDefines.h" 34 35static CKDUserInteraction *sharedInstance = nil; 36static CKDUserInteractionBlock completion; 37 38#define XPROXYUISCOPE "proxy-ui" 39 40static void userNotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) 41{ 42 43/* 44 kCFUserNotificationDefaultResponse = 0, 45 kCFUserNotificationAlternateResponse = 1, 46 kCFUserNotificationOtherResponse = 2, 47 kCFUserNotificationCancelResponse = 3 48*/ 49 50 CKDUserInteraction *sharedInstance = [CKDUserInteraction sharedInstance]; 51 CFDictionaryRef userResponses = CFUserNotificationGetResponseDictionary(userNotification); 52 // CFOptionFlags are poorly named, since it's a single response value, not a mask 53 54 secdebug(XPROXYUISCOPE, "sharedInstance: %@, rlsr: %@", sharedInstance, sharedInstance.runLoopSourceRef); 55 secdebug(XPROXYUISCOPE, "userNotification responses: %@, flags: %#lx",userResponses, responseFlags); 56 57 if (sharedInstance.runLoopSourceRef) 58 CFRunLoopRemoveSource(CFRunLoopGetMain(), sharedInstance.runLoopSourceRef, kCFRunLoopDefaultMode); 59 60 if (completion) // sharedInstance.completion 61 { 62 secdebug(XPROXYUISCOPE, "Calling user completion routine"); 63 completion(userResponses, responseFlags); // sharedInstance.completion 64 } 65 66 secdebug(XPROXYUISCOPE, "Releasing user completion routine"); 67// Block_release(completion); // sharedInstance.completion 68 69/* 70 if (responseFlags & kCFUserNotificationCancelResponse) { 71 returnCode = kABNotifierUserCancelled; 72 } else { 73 fUsername = (CFStringRef)CFUserNotificationGetResponseValue(notification, kCFUserNotificationTextFieldValuesKey, 0); 74 if(fUsername) CFRetain(fUsername); 75 76 fPassword = (CFStringRef)CFUserNotificationGetResponseValue(notification, kCFUserNotificationTextFieldValuesKey, 1); 77 if(fPassword) CFRetain(fPassword); 78 79 if((response & CFUserNotificationCheckBoxChecked(0))) 80*/ 81 82// if (responseFlags == kCFUserNotificationCancelResponse || responseFlags == kCFUserNotificationDefaultResponse) 83 CFRunLoopStop(CFRunLoopGetCurrent()); 84 secdebug(XPROXYUISCOPE, "exit"); 85} 86 87@implementation CKDUserInteraction 88 89+ (CKDUserInteraction *) sharedInstance 90{ 91 if (!sharedInstance) 92 sharedInstance = [[self alloc] init]; 93 94 return sharedInstance; 95} 96 97- (void)requestShowNotification:(NSDictionary *)infoForUserInfo completion:(CKDUserInteractionBlock)completionf 98{ 99 __block CFOptionFlags flags = kCFUserNotificationCautionAlertLevel | kCFUserNotificationNoDefaultButtonFlag; 100 CFTimeInterval timeout = 30.0; 101 102// completion = Block_copy(completionf); 103 completion = completionf; 104 105 CFStringRef headerStr = (__bridge CFStringRef)([infoForUserInfo objectForKey:(__bridge id)kCFUserNotificationAlertHeaderKey]); 106 107 CFStringRef cancelStr = CFSTR("No way"); //CFStringCreateWithCString(kCFAllocatorDefault, cancel.c_str(), kCFStringEncodingUTF8); 108 CFStringRef defaultStr = CFSTR("Sure"); //CFStringCreateWithCString(kCFAllocatorDefault, settings.c_str(), kCFStringEncodingUTF8); 109 110 CFMutableDictionaryRef notifyDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 111 112 // Header and buttons 113 CFDictionarySetValue(notifyDictionary, kCFUserNotificationAlertHeaderKey, headerStr); 114 CFDictionarySetValue(notifyDictionary, kCFUserNotificationDefaultButtonTitleKey, defaultStr); 115 CFDictionarySetValue(notifyDictionary, kCFUserNotificationAlternateButtonTitleKey, cancelStr); 116 117 SInt32 error = 0; 118 _userNotificationRef = CFUserNotificationCreate(kCFAllocatorDefault, timeout, flags, &error, notifyDictionary); 119 120 if (_userNotificationRef) 121 { 122 _runLoopSourceRef = CFUserNotificationCreateRunLoopSource(kCFAllocatorDefault, _userNotificationRef, userNotificationCallback, 0); 123 CFRunLoopAddSource(CFRunLoopGetMain(), _runLoopSourceRef, kCFRunLoopDefaultMode); 124 } 125 126} 127 128@end 129 130