1/* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "WKProcessGroup.h" 28#import "WKProcessGroupPrivate.h" 29 30#import "ObjCObjectGraph.h" 31#import "WKConnectionInternal.h" 32#import "WKContext.h" 33#import "WKRetainPtr.h" 34#import "WKStringCF.h" 35#import <wtf/RetainPtr.h> 36 37@interface WKProcessGroupData : NSObject { 38@public 39 // Underlying context object. 40 WKRetainPtr<WKContextRef> _contextRef; 41 42 // Delegate for callbacks. 43 id<WKProcessGroupDelegate> _delegate; 44} 45@end 46 47@implementation WKProcessGroupData 48@end 49 50@implementation WKProcessGroup 51 52static void didCreateConnection(WKContextRef, WKConnectionRef connectionRef, const void* clientInfo) 53{ 54 WKProcessGroup *processGroup = (WKProcessGroup *)clientInfo; 55 if ([processGroup.delegate respondsToSelector:@selector(processGroup:didCreateConnectionToWebProcessPlugIn:)]) { 56 RetainPtr<WKConnection> connection = adoptNS([[WKConnection alloc] _initWithConnectionRef:connectionRef]); 57 [processGroup.delegate processGroup:processGroup didCreateConnectionToWebProcessPlugIn:connection.get()]; 58 } 59} 60 61static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef contextRef) 62{ 63 WKContextConnectionClient connectionClient; 64 memset(&connectionClient, 0, sizeof(connectionClient)); 65 66 connectionClient.version = kWKContextConnectionClientCurrentVersion; 67 connectionClient.clientInfo = processGroup; 68 connectionClient.didCreateConnection = didCreateConnection; 69 70 WKContextSetConnectionClient(contextRef, &connectionClient); 71} 72 73static WKTypeRef getInjectedBundleInitializationUserData(WKContextRef, const void* clientInfo) 74{ 75 WKProcessGroup *processGroup = (WKProcessGroup *)clientInfo; 76 if ([processGroup.delegate respondsToSelector:@selector(processGroupWillCreateConnectionToWebProcessPlugIn:)]) { 77 RetainPtr<id> initializationUserData = [processGroup.delegate processGroupWillCreateConnectionToWebProcessPlugIn:processGroup]; 78 RefPtr<WebKit::ObjCObjectGraph> wkMessageBody = WebKit::ObjCObjectGraph::create(initializationUserData.get()); 79 return (WKTypeRef)wkMessageBody.release().leakRef(); 80 } 81 82 return 0; 83} 84 85static void setUpInectedBundleClient(WKProcessGroup *processGroup, WKContextRef contextRef) 86{ 87 WKContextInjectedBundleClient injectedBundleClient; 88 memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); 89 90 injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion; 91 injectedBundleClient.clientInfo = processGroup; 92 injectedBundleClient.getInjectedBundleInitializationUserData = getInjectedBundleInitializationUserData; 93 94 WKContextSetInjectedBundleClient(contextRef, &injectedBundleClient); 95} 96 97- (id)init 98{ 99 return [self initWithInjectedBundleURL:nil]; 100} 101 102- (id)initWithInjectedBundleURL:(NSURL *)bundleURL 103{ 104 self = [super init]; 105 if (!self) 106 return nil; 107 108 _data = [[WKProcessGroupData alloc] init]; 109 110 if (bundleURL) 111 _data->_contextRef = adoptWK(WKContextCreateWithInjectedBundlePath(adoptWK(WKStringCreateWithCFString((CFStringRef)[bundleURL path])).get())); 112 else 113 _data->_contextRef = adoptWK(WKContextCreate()); 114 115 setUpConnectionClient(self, _data->_contextRef.get()); 116 setUpInectedBundleClient(self, _data->_contextRef.get()); 117 118 return self; 119} 120 121- (void)dealloc 122{ 123 WKContextSetConnectionClient(_data->_contextRef.get(), 0); 124 WKContextSetInjectedBundleClient(_data->_contextRef.get(), 0); 125 126 [_data release]; 127 [super dealloc]; 128} 129 130- (id<WKProcessGroupDelegate>)delegate 131{ 132 return _data->_delegate; 133} 134 135- (void)setDelegate:(id<WKProcessGroupDelegate>)delegate 136{ 137 _data->_delegate = delegate; 138} 139 140@end 141 142@implementation WKProcessGroup (Private) 143 144- (WKContextRef)_contextRef 145{ 146 return _data->_contextRef.get(); 147} 148 149@end 150