|
1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Resolver for remote items |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 // INCLUDE FILES |
|
24 // upnp stack api's |
|
25 #include <upnpobject.h> |
|
26 #include <upnpitem.h> |
|
27 #include <upnpcontainer.h> |
|
28 #include <upnpelement.h> |
|
29 #include <upnpattribute.h> |
|
30 #include <upnpdlnaprotocolinfo.h> |
|
31 |
|
32 // upnpframework / avcontroller api |
|
33 #include "upnpavbrowsingsession.h" // browsing session |
|
34 |
|
35 // upnpframework / avcontroller helper api |
|
36 #include "upnpresourceselector.h" // MUPnPResourceSelector |
|
37 #include "upnpitemresolverobserver.h" // observer for this class |
|
38 #include "upnpitemutility.h" // for ResourceFromItem |
|
39 #include "upnpconstantdefs.h" // for browsing param: KSortNone |
|
40 |
|
41 // upnpframework / xml parser api |
|
42 #include "upnpxmlparser.h" // for xml parsing |
|
43 |
|
44 // avcontrollerhelper internal |
|
45 #include "upnpremoteitemresolver.h" |
|
46 |
|
47 _LIT( KComponentLogfile, "upnpavcontrollerhelper.txt"); |
|
48 #include "upnplog.h" |
|
49 |
|
50 // CONSTANTS |
|
51 |
|
52 |
|
53 // METHODS |
|
54 |
|
55 // -------------------------------------------------------------------------- |
|
56 // CUPnPRemoteItemResolver::NewL |
|
57 //--------------------------------------------------------------------------- |
|
58 CUPnPRemoteItemResolver* CUPnPRemoteItemResolver::NewL( |
|
59 const TDesC8& aItemId, |
|
60 MUPnPAVBrowsingSession& aHostSession, |
|
61 MUPnPResourceSelector& aSelector, |
|
62 const TDesC8& aBrowseFilter ) |
|
63 { |
|
64 CUPnPRemoteItemResolver* self = new (ELeave) CUPnPRemoteItemResolver( |
|
65 aItemId, aHostSession, aSelector, aBrowseFilter ); |
|
66 CleanupStack::PushL( self ); |
|
67 self->ConstructL( aItemId, aHostSession, aSelector, aBrowseFilter ); |
|
68 CleanupStack::Pop( self ); |
|
69 return self; |
|
70 } |
|
71 |
|
72 |
|
73 // -------------------------------------------------------------------------- |
|
74 // CUPnPRemoteItemResolver::CUPnPRemoteItemResolver |
|
75 //--------------------------------------------------------------------------- |
|
76 CUPnPRemoteItemResolver::CUPnPRemoteItemResolver( |
|
77 const TDesC8& /*aItemId*/, |
|
78 MUPnPAVBrowsingSession& aHostSession, |
|
79 MUPnPResourceSelector& aSelector, |
|
80 const TDesC8& aBrowseFilter ) |
|
81 : CUPnPAbstractBrowsingSessionObserver() |
|
82 , iBrowsingSession( aHostSession ) |
|
83 , iSelector( aSelector ) |
|
84 , iBrowseFilter( aBrowseFilter ) |
|
85 { |
|
86 iState = EStateIdle; |
|
87 SetSession( aHostSession ); |
|
88 } |
|
89 |
|
90 |
|
91 // -------------------------------------------------------------------------- |
|
92 // CUPnPRemoteItemResolver::ConstructL |
|
93 //--------------------------------------------------------------------------- |
|
94 void CUPnPRemoteItemResolver::ConstructL( |
|
95 const TDesC8& aItemId, |
|
96 MUPnPAVBrowsingSession& /*aHostSession*/, |
|
97 MUPnPResourceSelector& /*aSelector*/, |
|
98 const TDesC8& /*aBrowseFilter*/ ) |
|
99 { |
|
100 iItemId = aItemId.AllocL(); |
|
101 } |
|
102 |
|
103 // -------------------------------------------------------------------------- |
|
104 // CUPnPRemoteItemResolver::~CUPnPRemoteItemResolver |
|
105 //--------------------------------------------------------------------------- |
|
106 CUPnPRemoteItemResolver::~CUPnPRemoteItemResolver() |
|
107 { |
|
108 Cleanup(); |
|
109 delete iItemId; |
|
110 iItemId = 0; |
|
111 } |
|
112 |
|
113 // -------------------------------------------------------------------------- |
|
114 // CUPnPRemoteItemResolver::ResolveL |
|
115 //--------------------------------------------------------------------------- |
|
116 void CUPnPRemoteItemResolver::ResolveL( |
|
117 MUPnPItemResolverObserver& aObserver ) |
|
118 { |
|
119 __LOG( "RemoteItemResolver:Resolve()" ); |
|
120 __ASSERTD( iState == EStateIdle, __FILE__, __LINE__ ); |
|
121 |
|
122 // enable receiving callbacks here |
|
123 EnableSessionObserver(); |
|
124 |
|
125 // change state |
|
126 iObserver = &aObserver; |
|
127 iState = EStateActive; |
|
128 |
|
129 iRecursionDepth = 0; |
|
130 |
|
131 iBrowsingSession.BrowseL( |
|
132 iItemId->Des(), iBrowseFilter, |
|
133 MUPnPAVBrowsingSession::EMetadata, |
|
134 0, 1, KSortNone ); |
|
135 |
|
136 } |
|
137 |
|
138 |
|
139 // -------------------------------------------------------------------------- |
|
140 // CUPnPRemoteItemResolver::Item |
|
141 //--------------------------------------------------------------------------- |
|
142 const CUpnpItem& CUPnPRemoteItemResolver::Item() const |
|
143 { |
|
144 __LOG( "RemoteItemResolver:item" ); |
|
145 __ASSERTD( iState == EStateReady, __FILE__, __LINE__ ); |
|
146 __ASSERTD( iFirstLevelItem, __FILE__, __LINE__ ); |
|
147 |
|
148 return *iFirstLevelItem; |
|
149 } |
|
150 |
|
151 |
|
152 // -------------------------------------------------------------------------- |
|
153 // CUPnPRemoteItemResolver::Resource |
|
154 //--------------------------------------------------------------------------- |
|
155 const CUpnpElement& CUPnPRemoteItemResolver::Resource() const |
|
156 { |
|
157 __LOG( "RemoteItemResolver:Resource" ); |
|
158 __ASSERTD( iState == EStateReady, __FILE__, __LINE__ ); |
|
159 __ASSERTD( iResource, __FILE__, __LINE__ ); |
|
160 |
|
161 return *iResource; |
|
162 } |
|
163 |
|
164 // -------------------------------------------------------------------------- |
|
165 // CUPnPRemoteItemResolver::BrowseResponse |
|
166 //--------------------------------------------------------------------------- |
|
167 void CUPnPRemoteItemResolver::BrowseResponse( |
|
168 const TDesC8& aBrowseResponse, |
|
169 TInt aError, |
|
170 TInt /*aMatches*/, |
|
171 TInt /*aTotalCount*/, |
|
172 const TDesC8& /*aUpdateId*/ ) |
|
173 { |
|
174 __ASSERTD( iState == EStateActive, __FILE__, __LINE__ ); |
|
175 __LOG1( "RemoteItemResolver:BrowseResponse(%d)", aError ); |
|
176 |
|
177 // If the browse succeeded, parse the response and process the result |
|
178 if ( aError == KErrNone ) |
|
179 { |
|
180 TRAP( aError, BrowseResponseL( aBrowseResponse ) ); |
|
181 } |
|
182 |
|
183 // It the browse failed, or the parsing/processging of the response |
|
184 // failed, do complete. |
|
185 if( aError != KErrNone ) |
|
186 { |
|
187 Complete( aError ); |
|
188 } |
|
189 } |
|
190 |
|
191 // -------------------------------------------------------------------------- |
|
192 // CUPnPRemoteItemResolver::BrowseResponseL |
|
193 //--------------------------------------------------------------------------- |
|
194 // |
|
195 void CUPnPRemoteItemResolver::BrowseResponseL( const TDesC8& aBrowseResponse ) |
|
196 { |
|
197 __LOG( "RemoteItemResolver:BrowseResponseL" ); |
|
198 |
|
199 // Status code |
|
200 TInt status = KErrNone; |
|
201 |
|
202 // Result array |
|
203 RPointerArray<CUpnpObject> array; |
|
204 |
|
205 // Create parser |
|
206 CUPnPXMLParser* parser = NULL; |
|
207 TRAP( status, parser = CUPnPXMLParser::NewL() ); |
|
208 |
|
209 // If the parser was created succesfully... |
|
210 if( status == KErrNone ) |
|
211 { |
|
212 CleanupStack::PushL( parser ); |
|
213 |
|
214 // Parse the result data, and process the result object |
|
215 TRAP( status, |
|
216 parser->ParseResultDataL( array, aBrowseResponse ); |
|
217 if(array.Count()!= 0 ) |
|
218 ProcessResultObjectL( array[0] ); |
|
219 else |
|
220 { |
|
221 //handle error no object |
|
222 Complete( KErrNotFound ); |
|
223 } |
|
224 ); |
|
225 |
|
226 // Clean up |
|
227 CleanupStack::PopAndDestroy( parser ); |
|
228 parser = NULL; |
|
229 } |
|
230 |
|
231 // Empty, reset and close the array |
|
232 for( TInt i=0; i<array.Count(); i++ ) |
|
233 { |
|
234 delete array[i]; |
|
235 } |
|
236 array.Reset(); |
|
237 array.Close(); |
|
238 |
|
239 // If there was an error, forward the leave |
|
240 if( status != KErrNone ) |
|
241 { |
|
242 User::Leave( status ); |
|
243 } |
|
244 } |
|
245 |
|
246 // -------------------------------------------------------------------------- |
|
247 // CUPnPRemoteItemResolver::ProcessResultObjectL |
|
248 //--------------------------------------------------------------------------- |
|
249 void CUPnPRemoteItemResolver::ProcessResultObjectL( |
|
250 const CUpnpObject* aResult ) |
|
251 { |
|
252 if ( aResult->ObjectType() != EUPnPItem ) |
|
253 { |
|
254 User::Leave( KErrArgument ); |
|
255 } |
|
256 |
|
257 // copy the item |
|
258 CUpnpItem* item = CUpnpItem::NewL(); |
|
259 CleanupStack::PushL( item ); |
|
260 item->CopyL( *aResult ); |
|
261 |
|
262 // select the resource |
|
263 __LOG( "RemoteItemResolver:calling SelectResource" ); |
|
264 const CUpnpElement& res = |
|
265 iSelector.SelectResourceL( *item ); |
|
266 |
|
267 if ( iRecursionDepth == 0 ) |
|
268 { |
|
269 __ASSERTD( !iFirstLevelItem, __FILE__, __LINE__ ); |
|
270 CleanupStack::Pop( item ); |
|
271 iFirstLevelItem = item; |
|
272 item = 0; // take ownership |
|
273 } |
|
274 |
|
275 HBufC8* recurringId = 0; |
|
276 |
|
277 |
|
278 if ( recurringId ) |
|
279 { |
|
280 // continue recursion ! |
|
281 ++iRecursionDepth; |
|
282 __LOG1( "RemoteItemResolver:ProcessResult - recur %d", |
|
283 iRecursionDepth ); |
|
284 iBrowsingSession.BrowseL( |
|
285 recurringId->Des(), iBrowseFilter, |
|
286 MUPnPAVBrowsingSession::EMetadata, |
|
287 0, 1, KSortNone ); |
|
288 CleanupStack::PopAndDestroy( recurringId ); |
|
289 } |
|
290 else |
|
291 { |
|
292 // finished browsing the item |
|
293 __ASSERTD( !iLastLevelItem, __FILE__, __LINE__ ); |
|
294 __LOG( "RemoteItemResolver:ProcessResult - finished" ); |
|
295 if ( iRecursionDepth > 0 ) |
|
296 { |
|
297 // pointed object is DIFFERENT from first level object |
|
298 iLastLevelItem = CUpnpItem::NewL(); |
|
299 iLastLevelItem->CopyL( *item ); |
|
300 } |
|
301 iResource = &res; |
|
302 Complete( KErrNone ); |
|
303 } |
|
304 |
|
305 if( item ) |
|
306 { |
|
307 CleanupStack::PopAndDestroy( item ); |
|
308 } |
|
309 } |
|
310 |
|
311 |
|
312 // -------------------------------------------------------------------------- |
|
313 // CUPnPRemoteItemResolver::Complete |
|
314 //--------------------------------------------------------------------------- |
|
315 void CUPnPRemoteItemResolver::Complete( TInt aError ) |
|
316 { |
|
317 __ASSERTD( iState == EStateActive, __FILE__, __LINE__ ); |
|
318 |
|
319 DisableSessionObserver(); |
|
320 MUPnPItemResolverObserver& observer = *iObserver; |
|
321 iObserver = 0; |
|
322 if ( aError == KErrNone ) |
|
323 { |
|
324 iState = EStateReady; |
|
325 } |
|
326 else |
|
327 { |
|
328 iState = EStateIdle; |
|
329 Cleanup(); |
|
330 } |
|
331 |
|
332 observer.ResolveComplete( *this, aError ); |
|
333 } |
|
334 |
|
335 // -------------------------------------------------------------------------- |
|
336 // CUPnPRemoteItemResolver::Cleanup |
|
337 //--------------------------------------------------------------------------- |
|
338 void CUPnPRemoteItemResolver::Cleanup() |
|
339 { |
|
340 DisableSessionObserver(); |
|
341 |
|
342 if ( iState == EStateActive ) |
|
343 { |
|
344 iBrowsingSession.CancelBrowse(); |
|
345 } |
|
346 |
|
347 iObserver = 0; |
|
348 |
|
349 delete iFirstLevelItem; |
|
350 iFirstLevelItem = 0; |
|
351 |
|
352 delete iLastLevelItem; |
|
353 iLastLevelItem = 0; |
|
354 |
|
355 iResource = 0; |
|
356 |
|
357 iState = EStateIdle; |
|
358 } |
|
359 |
|
360 |