45 ExecState* exec, |
45 ExecState* exec, |
46 HBufC8* svcName, |
46 HBufC8* svcName, |
47 MDeviceBinding* deviceBinding) |
47 MDeviceBinding* deviceBinding) |
48 : JSObject( exec->lexicalInterpreter()->builtinObjectPrototype() ) |
48 : JSObject( exec->lexicalInterpreter()->builtinObjectPrototype() ) |
49 { |
49 { |
50 m_privateData = new ServiceObjectPrivate(svcName, deviceBinding); |
50 m_valid = EFalse; |
51 if (m_privateData && m_privateData->m_deviceBinding) |
51 m_privateData = NULL; |
52 { |
52 if ( deviceBinding ) |
53 m_valid = true; |
53 { |
54 // protect this object |
54 m_privateData = new ServiceObjectPrivate(this, svcName, deviceBinding); |
55 KJS::Collector::protect(this); |
55 if ( m_privateData ) |
56 } |
56 m_valid = ETrue; |
57 else |
57 } |
58 { |
|
59 m_valid = false; |
|
60 } |
|
61 } |
58 } |
62 |
59 |
63 |
60 |
64 // ---------------------------------------------------------------------------- |
61 // ---------------------------------------------------------------------------- |
65 // ServiceObject::~ServiceObject |
62 // ServiceObject::~ServiceObject |
67 // |
64 // |
68 // |
65 // |
69 // ---------------------------------------------------------------------------- |
66 // ---------------------------------------------------------------------------- |
70 ServiceObject::~ServiceObject() |
67 ServiceObject::~ServiceObject() |
71 { |
68 { |
72 // only can be called by garbage collection after the |
69 Close(); |
73 // ServiceObject::Close() was called |
|
74 } |
70 } |
75 |
71 |
76 // ---------------------------------------------------------------------------- |
72 // ---------------------------------------------------------------------------- |
77 // ServiceObject::Close |
73 // ServiceObject::Close |
78 // |
74 // |
79 // ---------------------------------------------------------------------------- |
75 // ---------------------------------------------------------------------------- |
80 void ServiceObject::Close( ExecState* exec, bool unmark ) |
76 void ServiceObject::Close() |
81 { |
77 { |
82 // avoid double close |
78 // avoid double close |
83 if(!m_valid) |
79 if ( !m_valid ) |
84 { |
|
85 if(unmark) |
|
86 { |
|
87 // unprotect this to allow the garbage collection to release this jsobject |
|
88 KJS::Collector::unprotect(this); |
|
89 } |
|
90 return; |
80 return; |
91 } |
81 |
92 |
82 m_valid = EFalse; |
93 // set isClosing flag to true |
|
94 m_privateData->isClosing = true; |
|
95 |
|
96 if ( exec ) |
|
97 { |
|
98 PropertyNameArray propertyNames; |
|
99 this->getPropertyNames( exec, propertyNames ); |
|
100 unsigned size = static_cast<unsigned>(propertyNames.size()); |
|
101 |
|
102 for (unsigned i = 0; i < size; i++) |
|
103 { |
|
104 JSValue * jsvalue = this->get( exec, propertyNames[i] ); |
|
105 if(jsvalue->isObject()) |
|
106 { |
|
107 JSObject * prop = jsvalue->toObject( exec ); |
|
108 if (prop->inherits( &DeviceLiwInterface::info )) |
|
109 { |
|
110 (static_cast<DeviceLiwInterface*>(prop))->Close(exec); |
|
111 } |
|
112 } |
|
113 } |
|
114 } |
|
115 |
|
116 delete m_privateData; |
83 delete m_privateData; |
117 m_privateData = NULL; |
84 m_privateData = NULL; |
118 m_valid = false; |
|
119 |
|
120 if(unmark) |
|
121 { |
|
122 // unprotect this to allow the garbage collection to release this jsobject |
|
123 KJS::Collector::unprotect(this); |
|
124 } |
|
125 } |
85 } |
126 |
86 |
127 // ---------------------------------------------------------------------------- |
87 // ---------------------------------------------------------------------------- |
128 // ServiceObject::toString |
88 // ServiceObject::toString |
129 // |
89 // |
162 |
122 |
163 // 1.2 check own property |
123 // 1.2 check own property |
164 m_privateData->m_propName = propertyName; |
124 m_privateData->m_propName = propertyName; |
165 JSValue* val = getDirect( propertyName ); |
125 JSValue* val = getDirect( propertyName ); |
166 |
126 |
167 // if the property is an interface and interface is closed |
127 // if the property is an interface which has been closed |
168 bool need_recreate = false; |
128 bool need_recreate = false; |
169 if ( val && val->isObject() && |
129 if ( val && val->isObject() && |
170 val->toObject(exec)->inherits( &KJS::DeviceLiwInterface::info ) ) |
130 val->toObject(exec)->inherits( &KJS::DeviceLiwInterface::info ) ) |
171 { |
131 { |
172 DeviceLiwInterface* interface = static_cast<DeviceLiwInterface*>(val); |
132 DeviceLiwInterface* interface = static_cast<DeviceLiwInterface*>(val); |
173 if ( !interface->isValid() && !m_privateData->isClosing) |
133 if ( !interface->isValid() ) |
174 { |
134 { |
175 need_recreate = true; |
135 need_recreate = true; |
176 } |
136 } |
177 } |
137 } |
178 |
138 |
181 if ( !val ) |
141 if ( !val ) |
182 { |
142 { |
183 // 1.3 check prototypes |
143 // 1.3 check prototypes |
184 JSObject *proto = static_cast<JSObject *>(this->prototype()); |
144 JSObject *proto = static_cast<JSObject *>(this->prototype()); |
185 |
145 |
186 while (!proto->isNull() && proto->isObject()) { |
146 while (!proto->isNull() && proto->isObject()) |
|
147 { |
187 if (proto->getOwnPropertySlot(exec, propertyName, slot)) |
148 if (proto->getOwnPropertySlot(exec, propertyName, slot)) |
188 return true; |
149 return true; |
189 |
150 |
190 proto = static_cast<JSObject *>(proto->prototype()); |
151 proto = static_cast<JSObject *>(proto->prototype()); |
191 } |
152 } |
192 } |
153 } |
193 |
154 |
|
155 // Create an interface for me, please! |
194 // Store the interface in the object so we get the same one each time. |
156 // Store the interface in the object so we get the same one each time. |
195 JSValue* resultVal = m_privateData->m_deviceBinding->CreateInterface( |
157 JSValue* resultVal = m_privateData->m_deviceBinding->CreateInterface( |
196 exec, m_privateData->m_svcName, m_privateData->m_propName ); |
158 exec, m_privateData->m_svcName, m_privateData->m_propName ); |
197 |
159 |
198 if ( resultVal->type() == UndefinedType || exec->hadException() ) |
160 if ( resultVal->type() == UndefinedType || exec->hadException() ) |
199 return false; |
161 return false; |
200 else |
162 else |
201 { |
163 { |
202 JSValue* s = resultVal->toObject(exec)->get( exec, m_privateData->m_propName ); |
164 JSValue* s = resultVal->toObject(exec)->get( exec, m_privateData->m_propName ); |
|
165 DeviceLiwInterface* ifObj = static_cast<DeviceLiwInterface*>(s); |
|
166 DevicePrivateBase* ifData = ifObj->getInterfaceData(); |
|
167 DevicePrivateBase* soData = this->getServiceData(); |
|
168 ifData->SetParent( soData ); |
|
169 soData->AddChild( ifData ); |
203 this->putDirect( propertyName, s, DontDelete|ReadOnly ); |
170 this->putDirect( propertyName, s, DontDelete|ReadOnly ); |
204 } |
171 } |
205 |
172 |
206 // clean the DeviceLiwResult which is useless |
173 // clean the DeviceLiwResult which is useless |
207 if(resultVal->isObject()) |
174 if(resultVal->isObject()) |
208 { |
175 { |
209 JSObject * jsobj = resultVal->toObject( exec ); |
176 JSObject * jsobj = resultVal->toObject( exec ); |
210 if(jsobj->inherits( &KJS::DeviceLiwResult::info )) |
177 if(jsobj->inherits( &KJS::DeviceLiwResult::info )) |
211 { |
178 { |
212 DeviceLiwResult* result = static_cast<DeviceLiwResult*>(jsobj); |
179 DeviceLiwResult* result = static_cast<DeviceLiwResult*>(jsobj); |
213 result->quickClose(); |
180 result->Close(); |
214 } |
181 } |
215 } |
182 } |
216 } |
183 } |
217 return JSObject::getOwnPropertySlot(exec, propertyName, slot); |
184 return JSObject::getOwnPropertySlot(exec, propertyName, slot); |
218 } |
185 } |
315 // the close function cann't be called in the callback function |
282 // the close function cann't be called in the callback function |
316 if(so->IsRunningCallBack(exec)) |
283 if(so->IsRunningCallBack(exec)) |
317 { |
284 { |
318 return throwError(exec, GeneralError, "Can not close service object in callback function."); |
285 return throwError(exec, GeneralError, "Can not close service object in callback function."); |
319 } |
286 } |
320 so->Close( exec, false ); |
287 so->Close(); |
321 } |
288 } |
322 return ret; |
289 return ret; |
323 } |
290 } |
324 |
291 |
325 // --------------------------------------------------------------------------- |
292 // --------------------------------------------------------------------------- |
326 // DeviceLiwMapPrivate constructor |
293 // DeviceLiwMapPrivate constructor |
327 // |
294 // |
328 // --------------------------------------------------------------------------- |
295 // --------------------------------------------------------------------------- |
329 ServiceObjectPrivate::ServiceObjectPrivate(HBufC8* svcName, MDeviceBinding* deviceBinding ) |
296 ServiceObjectPrivate::ServiceObjectPrivate(ServiceObject* jsobj, HBufC8* svcName, MDeviceBinding* deviceBinding ) |
330 { |
297 { |
331 m_svcName = svcName; |
298 m_svcName = svcName; |
332 m_deviceBinding = deviceBinding; |
299 m_deviceBinding = deviceBinding; |
333 isClosing = false; |
300 m_jsobj = jsobj; |
334 } |
301 } |
335 |
302 |
336 // --------------------------------------------------------------------------- |
303 // --------------------------------------------------------------------------- |
337 // DeviceLiwMapPrivate::Close |
304 // DeviceLiwMapPrivate::destructor |
338 // |
305 // |
339 // --------------------------------------------------------------------------- |
306 // --------------------------------------------------------------------------- |
340 void ServiceObjectPrivate::Close() |
307 ServiceObjectPrivate::~ServiceObjectPrivate() |
341 { |
308 { |
|
309 // invalid the ServiceObject |
|
310 if (m_jsobj) |
|
311 m_jsobj->m_valid = EFalse; |
|
312 |
342 m_deviceBinding->UnloadServiceProvider(KWildChar(), m_svcName->Des()); |
313 m_deviceBinding->UnloadServiceProvider(KWildChar(), m_svcName->Des()); |
343 m_deviceBinding = NULL; |
314 m_deviceBinding = NULL; |
344 |
315 |
345 delete m_svcName; |
316 delete m_svcName; |
346 m_svcName = NULL; |
317 m_svcName = NULL; |
347 } |
318 } |
348 |
319 |
349 //END OF FILE |
320 //END OF FILE |