~smaioli/azureus/ubuntu-experimental

« back to all changes in this revision

Viewing changes to com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java

MergedĀ VuzeĀ 4.2.0.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Created on Jan 27, 2009
 
3
 * Created by Paul Gardner
 
4
 * 
 
5
 * Copyright 2009 Vuze, Inc.  All rights reserved.
 
6
 * 
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; version 2 of the License only.
 
10
 * 
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
14
 * GNU General Public License for more details.
 
15
 * 
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
19
 */
 
20
 
 
21
 
 
22
package com.aelitis.azureus.core.devices.impl;
 
23
 
 
24
import java.net.URL;
 
25
import java.util.*;
 
26
 
 
27
import org.gudy.azureus2.core3.config.COConfigurationManager;
 
28
import org.gudy.azureus2.core3.config.ParameterListener;
 
29
import org.gudy.azureus2.core3.util.AEDiagnostics;
 
30
import org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator;
 
31
import org.gudy.azureus2.core3.util.AEDiagnosticsLogger;
 
32
import org.gudy.azureus2.core3.util.AERunnable;
 
33
import org.gudy.azureus2.core3.util.AESemaphore;
 
34
import org.gudy.azureus2.core3.util.AEThread2;
 
35
import org.gudy.azureus2.core3.util.Debug;
 
36
import org.gudy.azureus2.core3.util.DelayedEvent;
 
37
import org.gudy.azureus2.core3.util.FileUtil;
 
38
import org.gudy.azureus2.core3.util.IndentWriter;
 
39
import org.gudy.azureus2.core3.util.SimpleTimer;
 
40
import org.gudy.azureus2.core3.util.TimerEvent;
 
41
import org.gudy.azureus2.core3.util.TimerEventPerformer;
 
42
import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 
43
import org.gudy.azureus2.plugins.ipc.IPCInterface;
 
44
 
 
45
import com.aelitis.azureus.core.AzureusCore;
 
46
import com.aelitis.azureus.core.AzureusCoreFactory;
 
47
import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
 
48
import com.aelitis.azureus.core.devices.*;
 
49
import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
 
50
import com.aelitis.azureus.core.util.*;
 
51
 
 
52
public class 
 
53
DeviceManagerImpl 
 
54
        implements DeviceManager, AEDiagnosticsEvidenceGenerator
 
55
{
 
56
        private static final String     LOGGER_NAME                     = "Devices";
 
57
        private static final String     CONFIG_FILE                     = "devices.config";
 
58
        private static final String     AUTO_SEARCH_CONFIG_KEY  = "devices.config.auto_search";
 
59
        
 
60
        protected static final int      DEVICE_UPDATE_PERIOD    = 5*1000;
 
61
        
 
62
        private static DeviceManagerImpl                singleton;
 
63
        
 
64
        public static void
 
65
        preInitialise()
 
66
        {
 
67
        }
 
68
        
 
69
        public static DeviceManager
 
70
        getSingleton()
 
71
        {
 
72
                synchronized( DeviceManagerImpl.class ){
 
73
                        
 
74
                        if ( singleton == null ){
 
75
                                
 
76
                                singleton = new DeviceManagerImpl();
 
77
                        }
 
78
                }
 
79
                
 
80
                return( singleton );
 
81
        }
 
82
        
 
83
        
 
84
        
 
85
        private List<DeviceImpl>                        device_list = new ArrayList<DeviceImpl>();
 
86
        private Map<String,DeviceImpl>          device_map      = new HashMap<String, DeviceImpl>();
 
87
        
 
88
        private DeviceManagerUPnPImpl   upnp_manager;
 
89
        
 
90
        private CopyOnWriteList<DeviceManagerListener>  listeners       = new CopyOnWriteList<DeviceManagerListener>();
 
91
        
 
92
        private boolean auto_search;
 
93
        private boolean closing;
 
94
        
 
95
        private boolean config_unclean;
 
96
        private boolean config_dirty;
 
97
        
 
98
        private int             explicit_search;
 
99
        
 
100
        private TranscodeManagerImpl    transcode_manager;
 
101
        
 
102
        private AEDiagnosticsLogger             logger;
 
103
        
 
104
        protected
 
105
        DeviceManagerImpl()
 
106
        {
 
107
                AEDiagnostics.addEvidenceGenerator( this );
 
108
 
 
109
                upnp_manager = new DeviceManagerUPnPImpl( this );
 
110
 
 
111
                loadConfig();
 
112
                
 
113
                new DeviceiTunesManager( this );
 
114
                
 
115
                transcode_manager = new TranscodeManagerImpl( this );
 
116
                
 
117
                COConfigurationManager.addAndFireParameterListener(
 
118
                        AUTO_SEARCH_CONFIG_KEY,
 
119
                        new ParameterListener()
 
120
                        {
 
121
                                public void 
 
122
                                parameterChanged(
 
123
                                        String name ) 
 
124
                                {
 
125
                                        auto_search = COConfigurationManager.getBooleanParameter( name, true );
 
126
                                }
 
127
                        });
 
128
                
 
129
                AzureusCoreFactory.getSingleton().addLifecycleListener(
 
130
                        new AzureusCoreLifecycleAdapter()
 
131
                        {
 
132
                                public void
 
133
                                stopping(
 
134
                                        AzureusCore             core )
 
135
                                {                                       
 
136
                                        synchronized( DeviceManagerImpl.this ){
 
137
                                
 
138
                                                if ( config_dirty || config_unclean ){
 
139
                                                        
 
140
                                                        saveConfig();
 
141
                                                }
 
142
                                                
 
143
                                                closing = true;
 
144
                                                
 
145
                                                transcode_manager.close();
 
146
                                                
 
147
                                                DeviceImpl[] devices = getDevices();
 
148
                                                
 
149
                                                for ( DeviceImpl device: devices ){
 
150
                                                        
 
151
                                                        device.close();
 
152
                                                }
 
153
                                        }
 
154
                                }
 
155
                        });
 
156
                
 
157
                upnp_manager.initialise();
 
158
                
 
159
                SimpleTimer.addPeriodicEvent(
 
160
                                "DeviceManager:update",
 
161
                                DEVICE_UPDATE_PERIOD,
 
162
                                new TimerEventPerformer()
 
163
                                {
 
164
                                        private int tick_count = 0;
 
165
                                        
 
166
                                        public void 
 
167
                                        perform(
 
168
                                                TimerEvent event ) 
 
169
                                        {
 
170
                                                List<DeviceImpl> copy;
 
171
                                                
 
172
                                                tick_count++;
 
173
                                                
 
174
                                                transcode_manager.updateStatus( tick_count );
 
175
                                                
 
176
                                                synchronized( DeviceManagerImpl.this ){
 
177
 
 
178
                                                        if( device_list.size() == 0 ){
 
179
                                                                
 
180
                                                                return;
 
181
                                                        }
 
182
                                                        
 
183
                                                        copy = new ArrayList<DeviceImpl>( device_list );
 
184
                                                }
 
185
                                                
 
186
                                                for ( DeviceImpl device: copy ){
 
187
                                                        
 
188
                                                        device.updateStatus( tick_count );
 
189
                                                }
 
190
                                        }
 
191
                                });
 
192
        }
 
193
        
 
194
        protected DeviceManagerUPnPImpl 
 
195
        getUPnPManager()
 
196
        {
 
197
                return( upnp_manager );
 
198
        }
 
199
        
 
200
        public Device
 
201
        createDevice(
 
202
                int                                             device_type,
 
203
                String                                  name )
 
204
        
 
205
                throws DeviceManagerException
 
206
        {
 
207
                if ( device_type == Device.DT_MEDIA_RENDERER ){
 
208
                        
 
209
                        DeviceImpl res = new DeviceMediaRendererImpl( this, name );
 
210
                        
 
211
                        addDevice( res );
 
212
                        
 
213
                        return( res );
 
214
                        
 
215
                }else{
 
216
                        
 
217
                        throw( new DeviceManagerException( "Can't manually create this device type" ));
 
218
                }
 
219
        }
 
220
        
 
221
        public void
 
222
        search(
 
223
                final int                                       millis,
 
224
                final DeviceSearchListener      listener )
 
225
        {
 
226
                new AEThread2( "DM:search", true )
 
227
                {
 
228
                        public void
 
229
                        run()
 
230
                        {
 
231
                                synchronized( DeviceManagerImpl.this ){
 
232
                                
 
233
                                        explicit_search++;
 
234
                                }
 
235
                                
 
236
                                AESemaphore     sem = new AESemaphore( "DM:search" );
 
237
                                
 
238
                                DeviceManagerListener   dm_listener =
 
239
                                        new DeviceManagerListener()
 
240
                                        {
 
241
                                                public void
 
242
                                                deviceAdded(
 
243
                                                        Device          device )
 
244
                                                {
 
245
                                                        listener.deviceFound( device );
 
246
                                                }
 
247
                                                
 
248
                                                public void
 
249
                                                deviceChanged(
 
250
                                                        Device          device )
 
251
                                                {
 
252
                                                }
 
253
                                                
 
254
                                                public void
 
255
                                                deviceAttentionRequest(
 
256
                                                        Device          device )
 
257
                                                {       
 
258
                                                }
 
259
                                                
 
260
                                                public void
 
261
                                                deviceRemoved(
 
262
                                                        Device          device )
 
263
                                                {
 
264
                                                }
 
265
                                        };
 
266
                                        
 
267
                                try{
 
268
                                        addListener( dm_listener );
 
269
                                
 
270
                                        upnp_manager.search();
 
271
                                        
 
272
                                        sem.reserve( millis );
 
273
                                        
 
274
                                }finally{
 
275
                                        
 
276
                                        synchronized( DeviceManagerImpl.this ){
 
277
                                                
 
278
                                                explicit_search--;
 
279
                                        }
 
280
                                        
 
281
                                        removeListener( dm_listener );
 
282
                                        
 
283
                                        listener.complete();
 
284
                                }
 
285
                        }
 
286
                }.start();
 
287
        }
 
288
        
 
289
        protected DeviceImpl
 
290
        getDevice(
 
291
                String          id )
 
292
        {
 
293
                synchronized( this ){
 
294
 
 
295
                        return( device_map.get( id ));
 
296
                }
 
297
        }
 
298
        
 
299
        protected DeviceImpl
 
300
        addDevice(
 
301
                DeviceImpl              device )
 
302
        {
 
303
                        // for xbox (currently) we automagically replace a manual entry with an auto one as we may have
 
304
                        // added the manual one when receiving a previous browse before getting the UPnP renderer details
 
305
                        
 
306
                DeviceImpl      existing = null;
 
307
                
 
308
                synchronized( this ){
 
309
                                                
 
310
                        existing = device_map.get( device.getID());
 
311
                        
 
312
                        if ( existing != null ){
 
313
                                
 
314
                                existing.updateFrom( device );
 
315
                                                                                                
 
316
                        }else{
 
317
                        
 
318
                                if ( device.getType() == Device.DT_MEDIA_RENDERER ){
 
319
                                        
 
320
                                        DeviceMediaRenderer renderer = (DeviceMediaRenderer)device;
 
321
                                        
 
322
                                        if ( renderer.getRendererSpecies() == DeviceMediaRenderer.RS_XBOX && !renderer.isManual()){
 
323
                                                
 
324
                                                for ( DeviceImpl d: device_list ){
 
325
                                                        
 
326
                                                        if ( d.getType() == Device.DT_MEDIA_RENDERER ){
 
327
                                                                
 
328
                                                                DeviceMediaRenderer r = (DeviceMediaRenderer)d;
 
329
                                                                
 
330
                                                                if ( r.getRendererSpecies() == DeviceMediaRenderer.RS_XBOX && r.isManual()){
 
331
                                                                        
 
332
                                                                        existing = d;
 
333
 
 
334
                                                                        log( "Merging " + device.getString() + " -> " + existing.getString());
 
335
                                                                                
 
336
                                                                        String  secondary_id = device.getID();
 
337
                                                                        
 
338
                                                                        existing.setSecondaryID( secondary_id );
 
339
                                                                        
 
340
                                                                        existing.updateFrom( device );
 
341
                                                                }
 
342
                                                        }
 
343
                                                }
 
344
                                        }
 
345
                                }
 
346
                        }
 
347
                        
 
348
                        if ( existing == null ){
 
349
                        
 
350
                                device_list.add( device );
 
351
                                
 
352
                                device_map.put( device.getID(), device );
 
353
                        }
 
354
                }
 
355
                
 
356
                if ( existing != null ){
 
357
                        
 
358
                                // don't trigger config save here, if anything has changed it will have been handled
 
359
                                // by the updateFrom call above
 
360
                        
 
361
                        deviceChanged( existing, false );
 
362
                        
 
363
                        return( existing );
 
364
                }
 
365
                                        
 
366
                device.initialise();
 
367
                
 
368
                device.alive();
 
369
                
 
370
                deviceAdded( device );
 
371
                
 
372
                configDirty();
 
373
                
 
374
                return( device );
 
375
        }
 
376
        
 
377
        protected void
 
378
        removeDevice(
 
379
                DeviceImpl              device )
 
380
        {
 
381
                synchronized( this ){
 
382
                        
 
383
                        DeviceImpl existing = device_map.remove( device.getID());
 
384
                        
 
385
                        if ( existing == null ){
 
386
                                
 
387
                                return;
 
388
                        }
 
389
                        
 
390
                        device_list.remove( device );
 
391
                        
 
392
                        String secondary_id = device.getSecondaryID();
 
393
                        
 
394
                        if ( secondary_id != null ){
 
395
                                
 
396
                                device_map.remove( secondary_id );
 
397
                        }
 
398
                }
 
399
                
 
400
                device.destroy();
 
401
                
 
402
                deviceRemoved( device );
 
403
                
 
404
                configDirty();
 
405
        }
 
406
 
 
407
        public DeviceImpl[]
 
408
        getDevices()
 
409
        {
 
410
                synchronized( this ){
 
411
                        
 
412
                        return( device_list.toArray( new DeviceImpl[ device_list.size()] ));
 
413
                }
 
414
        }
 
415
                
 
416
        public boolean
 
417
        getAutoSearch()
 
418
        {
 
419
                return( auto_search );
 
420
        }
 
421
        
 
422
        public void
 
423
        setAutoSearch(
 
424
                boolean auto )
 
425
        {
 
426
                COConfigurationManager.setParameter( AUTO_SEARCH_CONFIG_KEY, auto );
 
427
        }
 
428
        
 
429
        protected boolean
 
430
        isExplicitSearch()
 
431
        {
 
432
                synchronized( this ){
 
433
                        
 
434
                        return( explicit_search > 0 );
 
435
                }
 
436
        }
 
437
        
 
438
        protected boolean
 
439
        isClosing()
 
440
        {
 
441
                return( closing );
 
442
        }
 
443
        
 
444
        protected void
 
445
        loadConfig()
 
446
        {
 
447
                if ( !FileUtil.resilientConfigFileExists( CONFIG_FILE )){
 
448
                        
 
449
                        return;
 
450
                }
 
451
                
 
452
                log( "Loading configuration" );
 
453
                                
 
454
                synchronized( this ){
 
455
                        
 
456
                        Map map = FileUtil.readResilientConfigFile( CONFIG_FILE );
 
457
                        
 
458
                        List    l_devices = (List)map.get( "devices" );
 
459
                        
 
460
                        if ( l_devices != null ){
 
461
                                
 
462
                                for (int i=0;i<l_devices.size();i++){
 
463
                                        
 
464
                                        Map     m = (Map)l_devices.get(i);
 
465
                                        
 
466
                                        try{
 
467
                                                DeviceImpl device = DeviceImpl.importFromBEncodedMapStatic(this,  m );
 
468
                                                
 
469
                                                device_list.add( device );
 
470
                                                
 
471
                                                device_map.put( device.getID(), device );
 
472
                                                
 
473
                                                String secondary_id = device.getSecondaryID();
 
474
                                                
 
475
                                                if ( secondary_id != null ){
 
476
                                                        
 
477
                                                        device_map.put( secondary_id, device );
 
478
                                                }
 
479
                                                        
 
480
                                                device.initialise();
 
481
                                        
 
482
                                                log( "    loaded " + device.getString());
 
483
                                                
 
484
                                        }catch( Throwable e ){
 
485
                                                
 
486
                                                log( "Failed to import subscription from " + m, e );
 
487
                                        }
 
488
                                }
 
489
                        }
 
490
                }
 
491
        }
 
492
        
 
493
        protected void
 
494
        configDirty(
 
495
                DeviceImpl              device,
 
496
                boolean                 save_changes )
 
497
        {
 
498
                deviceChanged( device, save_changes );
 
499
        }
 
500
        
 
501
        protected void
 
502
        configDirty()
 
503
        {
 
504
                synchronized( this ){
 
505
                        
 
506
                        if ( config_dirty ){
 
507
                                
 
508
                                return;
 
509
                        }
 
510
                        
 
511
                        config_dirty = true;
 
512
                
 
513
                        new DelayedEvent( 
 
514
                                "Subscriptions:save", 5000,
 
515
                                new AERunnable()
 
516
                                {
 
517
                                        public void 
 
518
                                        runSupport() 
 
519
                                        {
 
520
                                                synchronized( DeviceManagerImpl.this ){
 
521
                                                        
 
522
                                                        if ( !config_dirty ){
 
523
 
 
524
                                                                return;
 
525
                                                        }
 
526
                                                        
 
527
                                                        saveConfig();
 
528
                                                }       
 
529
                                        }
 
530
                                });
 
531
                }
 
532
        }
 
533
        
 
534
        protected void
 
535
        saveConfig()
 
536
        {
 
537
                log( "Saving configuration" );
 
538
                
 
539
                synchronized( this ){
 
540
                        
 
541
                        if ( closing ){
 
542
                                
 
543
                                        // to late to try writing
 
544
                                
 
545
                                return;
 
546
                        }
 
547
                        
 
548
                        config_dirty    = false;
 
549
                        config_unclean  = false;
 
550
                        
 
551
                        if ( device_list.size() == 0 ){
 
552
                                
 
553
                                FileUtil.deleteResilientConfigFile( CONFIG_FILE );
 
554
                                
 
555
                        }else{
 
556
                                
 
557
                                Map map = new HashMap();
 
558
                                
 
559
                                List    l_devices = new ArrayList();
 
560
                                
 
561
                                map.put( "devices", l_devices );
 
562
                                
 
563
                                Iterator<DeviceImpl>    it = device_list.iterator();
 
564
                                
 
565
                                while( it.hasNext()){
 
566
                                        
 
567
                                        DeviceImpl device = it.next();
 
568
                                                
 
569
                                        try{
 
570
                                                Map d = new HashMap();
 
571
                                                
 
572
                                                device.exportToBEncodedMap( d );
 
573
                                                
 
574
                                                l_devices.add( d );
 
575
                                                
 
576
                                        }catch( Throwable e ){
 
577
                                                
 
578
                                                log( "Failed to save device " + device.getString(), e );
 
579
                                        }
 
580
                                }
 
581
                                
 
582
                                FileUtil.writeResilientConfigFile( CONFIG_FILE, map );
 
583
                        }
 
584
                }
 
585
        }
 
586
        
 
587
        protected void
 
588
        deviceAdded(
 
589
                DeviceImpl              device )
 
590
        {
 
591
                configDirty();
 
592
                
 
593
                // I'd rather put this in a listener, but for now this will ensure
 
594
                // it gets QOS'd even before any listeners are added
 
595
                try {
 
596
                        PlatformDevicesMessenger.qosFoundDevice(device);
 
597
                } catch (Exception e) {
 
598
                        Debug.out(e);
 
599
                }
 
600
                
 
601
                for ( DeviceManagerListener listener: listeners ){
 
602
                        
 
603
                        try{
 
604
                                listener.deviceAdded( device );
 
605
                                
 
606
                        }catch( Throwable e ){
 
607
                                
 
608
                                Debug.out( e );
 
609
                        }
 
610
                }
 
611
        }
 
612
        
 
613
        
 
614
        protected void
 
615
        deviceChanged(
 
616
                DeviceImpl              device,
 
617
                boolean                 save_changes )
 
618
        {
 
619
                if ( save_changes ){
 
620
                        
 
621
                        configDirty();
 
622
                        
 
623
                }else{
 
624
                        
 
625
                        config_unclean = true;
 
626
                }
 
627
                
 
628
                for ( DeviceManagerListener listener: listeners ){
 
629
                        
 
630
                        try{
 
631
                                listener.deviceChanged( device );
 
632
                                
 
633
                        }catch( Throwable e ){
 
634
                                
 
635
                                Debug.out( e );
 
636
                        }
 
637
                }
 
638
        }
 
639
        
 
640
        protected void
 
641
        deviceRemoved(
 
642
                DeviceImpl              device )
 
643
        {
 
644
                configDirty();
 
645
                
 
646
                for ( DeviceManagerListener listener: listeners ){
 
647
                        
 
648
                        try{
 
649
                                listener.deviceRemoved( device );
 
650
                                
 
651
                        }catch( Throwable e ){
 
652
                                
 
653
                                Debug.out( e );
 
654
                        }
 
655
                }
 
656
        }
 
657
        
 
658
        protected void
 
659
        requestAttention(
 
660
                DeviceImpl              device )
 
661
        {
 
662
                for ( DeviceManagerListener listener: listeners ){
 
663
                        
 
664
                        try{
 
665
                                listener.deviceAttentionRequest( device );
 
666
                                
 
667
                        }catch( Throwable e ){
 
668
                                
 
669
                                Debug.out( e );
 
670
                        }
 
671
                }
 
672
        }
 
673
        
 
674
        protected URL
 
675
        getStreamURL(
 
676
                TranscodeFileImpl               file )
 
677
        {
 
678
                IPCInterface ipc = upnp_manager.getUPnPAVIPC();
 
679
                
 
680
                if ( ipc != null ){
 
681
 
 
682
                        try{
 
683
                                DiskManagerFileInfo f = file.getTargetFile();
 
684
                                
 
685
                                String str = (String)ipc.invoke( "getContentURL", new Object[]{ f });
 
686
                                
 
687
                                if ( str != null && str.length() > 0 ){
 
688
                                        
 
689
                                        return( new URL( str ));
 
690
                                }
 
691
                        }catch( Throwable e ){
 
692
                                
 
693
                        }
 
694
                }
 
695
                
 
696
                return( null );
 
697
        }
 
698
        
 
699
        public TranscodeManagerImpl
 
700
        getTranscodeManager()
 
701
        {
 
702
                return( transcode_manager );
 
703
        }
 
704
        
 
705
        public UnassociatedDevice[]
 
706
        getUnassociatedDevices()
 
707
        {
 
708
                return( upnp_manager.getUnassociatedDevices());
 
709
        }
 
710
        
 
711
        public void
 
712
        addListener(
 
713
                DeviceManagerListener           listener )
 
714
        {
 
715
                listeners.add( listener );
 
716
        }
 
717
        
 
718
        public void
 
719
        removeListener(
 
720
                DeviceManagerListener           listener )
 
721
        {
 
722
                listeners.remove( listener );
 
723
        }
 
724
        
 
725
        protected synchronized AEDiagnosticsLogger
 
726
        getLogger()
 
727
        {
 
728
                if ( logger == null ){
 
729
                        
 
730
                        logger = AEDiagnostics.getLogger( LOGGER_NAME );
 
731
                }
 
732
                
 
733
                return( logger );
 
734
        }
 
735
        
 
736
        public void 
 
737
        log(
 
738
                String          s,
 
739
                Throwable       e )
 
740
        {
 
741
                AEDiagnosticsLogger diag_logger = getLogger();
 
742
                
 
743
                diag_logger.log( s );
 
744
                diag_logger.log( e );
 
745
        }
 
746
        
 
747
        public void 
 
748
        log(
 
749
                String  s )
 
750
        {
 
751
                AEDiagnosticsLogger diag_logger = getLogger();
 
752
                
 
753
                diag_logger.log( s );
 
754
        }
 
755
        
 
756
        public void
 
757
        generate(
 
758
                IndentWriter            writer )
 
759
        {
 
760
                writer.println( "Devices" );
 
761
                        
 
762
                try{
 
763
                        writer.indent();
 
764
                        
 
765
                        DeviceImpl[] devices = getDevices();
 
766
                        
 
767
                        for ( DeviceImpl device: devices ){
 
768
                                
 
769
                                device.generate( writer );
 
770
                        }
 
771
                        
 
772
                        transcode_manager.generate( writer );
 
773
                }finally{
 
774
                        
 
775
                        writer.exdent();
 
776
                }
 
777
        }
 
778
}