1//
2//  sc-102-xx
3//  sec
4//
5//  Created by John Hurley 10/16/12.
6//  Copyright 2012 Apple Inc. All rights reserved.
7//
8
9/*
10    This test is a simple test of SOSCloudKeychainUserNotification to show
11    an OK/Cancel dialog to the user and get the response. Run with:
12
13        /AppleInternal/Applications/SecurityTests.app/SecurityTests sc_102_cfusernotification -v
14
15*/
16
17#include <AssertMacros.h>
18#include <CoreFoundation/CFUserNotification.h>
19#include <dispatch/dispatch.h>
20
21#include <utilities/SecCFWrappers.h>
22#include <utilities/debugging.h>
23
24#include "SOSCircle_regressions.h"
25#include "SOSCloudKeychainClient.h"
26#include "SOSCloudKeychainConstants.h"
27
28#if TARGET_OS_EMBEDDED && !TARGET_IPHONE_SIMULATOR
29#include <MobileGestalt.h>
30#endif
31
32static void tests(void)
33{
34//    CFStringRef messageToUser = CFSTR("OK to sync with world?");
35//    CFStringRef messageToUser = CFSTR("Allow “Emily‘s iPad to use your iCloud Keychain?");
36#if !TARGET_IPHONE_SIMULATOR
37#if TARGET_OS_EMBEDDED
38    CFStringRef our_peer_id = (CFStringRef)MGCopyAnswer(kMGQUserAssignedDeviceName, NULL);
39#else
40    CFStringRef our_peer_id = CFSTR("����");
41#endif
42#else
43    CFStringRef our_peer_id = CFSTR("Emily‘s iPad");
44#endif
45
46    CFStringRef messageToUser = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("Allow “%@” to use your iCloud Keychain?"), our_peer_id);
47    dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
48    dispatch_group_t work_group = dispatch_group_create();
49
50    // Prep the group for exitting the whole shebang.
51    dispatch_group_enter(work_group);
52    dispatch_group_notify(work_group, processQueue, ^
53        {
54            printf("Exiting via dispatch_group_notify; all work done\n");
55            CFRunLoopStop(CFRunLoopGetMain());
56        //  exit(0);
57        });
58
59    SOSCloudKeychainUserNotification(messageToUser, processQueue, ^ (CFDictionaryRef returnedValues, CFErrorRef error)
60        {
61            uint64_t flags = 0;
62            pass("Reply from SOSCloudKeychainUserNotification: %@", returnedValues);
63            CFStringRef nfkey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyNotificationFlags, kCFStringEncodingUTF8);
64            CFTypeRef cfflags = returnedValues ? CFDictionaryGetValue(returnedValues, nfkey) : NULL;
65            if (cfflags && (CFGetTypeID(cfflags) == CFNumberGetTypeID()))
66                CFNumberGetValue(cfflags, kCFNumberSInt64Type, &flags);
67            CFReleaseSafe(nfkey);
68
69            // flags is not actually a mask
70            if (flags == kCFUserNotificationDefaultResponse)
71                pass("OK button pressed");
72            else
73            if (flags == kCFUserNotificationCancelResponse)
74                pass("Cancel button pressed");
75            else
76            if (flags == kCFUserNotificationAlternateResponse)
77                pass("Alternate button pressed");
78            else
79                pass("Flags: %#llx", flags);
80
81            ok(error == NULL, "SOSCloudKeychainPutObjectsInCloud [error: %@:]", error);
82            dispatch_group_leave(work_group);
83        });
84
85    pass("Dialog is up for device \"%@\"", our_peer_id);
86    printf("Dialog is up\n");
87    dispatch_group_wait(work_group, DISPATCH_TIME_FOREVER);
88    CFRunLoopRun();                 // Wait for it...
89    pass("Exit from run loop");
90}
91
92static int kUNTestCount = 5;
93
94int sc_102_cfusernotification(int argc, char *const *argv)
95{
96    plan_tests(kUNTestCount);
97    tests();
98
99	return 0;
100}
101