9e8e626869158873896e515ac62755e09aa4f741
[platform/upstream/mdnsresponder.git] / mDNSResponder-1096.40.7 / mDNSMacOSX / Bonjour Safari Extension / SafariExtensionHandler.m
1 /*
2  *
3  * Copyright (c) 2017 Apple Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #import "SafariExtensionHandler.h"
19 #import "SafariExtensionViewController.h"
20
21 //#define SHOW_BROWSE_COUNT 1
22
23 #if SHOW_BROWSE_COUNT
24 #include <dns_sd.h>
25
26 static void browseReply( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context );
27 #endif
28
29 @interface SafariExtensionHandler ()
30
31 @property (strong) NSMutableDictionary *    instanceD;
32 #if SHOW_BROWSE_COUNT
33 @property (strong) dispatch_queue_t         instanceBrowseQ;
34 @property (assign) DNSServiceRef            instanceRef;    //  Never released!!!
35 #endif
36
37 @end
38
39 @implementation SafariExtensionHandler
40
41 - (instancetype)init
42 {
43     if( self = [super init] )
44     {
45 #if SHOW_BROWSE_COUNT
46         self.instanceD = [NSMutableDictionary dictionary];
47         [self startInstanceBrowse];
48 #endif
49     }
50     return( self );
51 }
52
53 - (void)validateToolbarItemInWindow:(SFSafariWindow *)window validationHandler:(void (^)(BOOL enabled, NSString *badgeText))validationHandler {
54     // This method will be called whenever some state changes in the passed in window. You should use this as a chance to enable or disable your toolbar item and set badge text.
55     (void)window;    // Unused
56     validationHandler(YES, _instanceD.count ? [NSNumber numberWithInteger: _instanceD.count].stringValue : @"");
57 }
58
59 - (SFSafariExtensionViewController *)popoverViewController {
60     return [SafariExtensionViewController sharedController];
61 }
62
63 #if SHOW_BROWSE_COUNT
64 - (void)startInstanceBrowse
65 {
66     if( !_instanceBrowseQ )
67     {
68         self.instanceBrowseQ = dispatch_queue_create( "DNSAllServiceBrowse", DISPATCH_QUEUE_PRIORITY_DEFAULT );
69         dispatch_set_context( _instanceBrowseQ, (void *)CFBridgingRetain( self ) );
70         dispatch_set_finalizer_f( _instanceBrowseQ, finalizer );
71     }
72     
73     dispatch_sync( _instanceBrowseQ, ^{
74         [_instanceD removeAllObjects];
75     });
76     
77     DNSServiceErrorType error;
78     if( (error = DNSServiceBrowse( &_instanceRef, 0/*no flags*/, 0, @"_http._tcp".UTF8String, "", browseReply, (__bridge void *)self )) != 0 )
79         NSLog(@"DNSServiceBrowse failed error: %ld", error);
80     
81     if( !error )
82     {
83         error = DNSServiceSetDispatchQueue( _instanceRef, _instanceBrowseQ );
84         if( error ) NSLog( @"DNSServiceSetDispatchQueue error: %d", error );
85     }
86 }
87
88 #pragma mark - Dispatch
89
90 static void finalizer( void * context )
91 {
92     SafariExtensionHandler *self = (__bridge SafariExtensionHandler *)context;
93     NSLog( @"finalizer: %@", self );
94     (void)CFBridgingRelease( (__bridge void *)self );
95 }
96
97 #pragma mark - DNS callbacks
98
99 static void browseReply( DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context )
100 {
101     (void)sdRef;            //    Unused
102     (void)interfaceIndex;   //    Unused
103     (void)errorCode;        //    Unused
104     SafariExtensionHandler *self = (__bridge SafariExtensionHandler *)context;
105     char fullNameBuffer[kDNSServiceMaxDomainName];
106     if( DNSServiceConstructFullName( fullNameBuffer, serviceName, regtype, replyDomain ) == kDNSServiceErr_NoError )
107     {
108         NSString *fullName = @(fullNameBuffer);
109         
110         if( flags & kDNSServiceFlagsAdd )
111         {
112             [self.instanceD setObject: fullName
113                                forKey: fullName];
114         }
115         else
116         {
117             [self.instanceD removeObjectForKey: fullName];
118         }
119     }
120 }
121 #endif
122
123 @end