2 * Copyright (c) 2007 Jeff Mitchell <kde-dev@emailgoeshere.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #define DEBUG_PREFIX "MediaDeviceCache"
22 #include <solid/device.h>
23 #include <solid/deviceinterface.h>
24 #include <solid/devicenotifier.h>
25 #include <solid/portablemediaplayer.h>
26 #include <solid/storageaccess.h>
27 #include <solid/storagedrive.h>
28 #include <solid/storagevolume.h>
34 #include "MediaDeviceCache.h"
37 MediaDeviceCache
* MediaDeviceCache::s_instance
= 0;
39 MediaDeviceCache::MediaDeviceCache() : QObject()
46 connect( Solid::DeviceNotifier::instance(), SIGNAL( deviceAdded( const QString
& ) ),
47 this, SLOT( slotAddSolidDevice( const QString
& ) ) );
48 connect( Solid::DeviceNotifier::instance(), SIGNAL( deviceRemoved( const QString
& ) ),
49 this, SLOT( slotRemoveSolidDevice( const QString
& ) ) );
52 MediaDeviceCache::~MediaDeviceCache()
58 MediaDeviceCache::refreshCache()
63 QList
<Solid::Device
> deviceList
= Solid::Device::listFromType( Solid::DeviceInterface::PortableMediaPlayer
);
65 foreach( Solid::Device device
, deviceList
)
67 if( device
.as
<Solid::StorageDrive
>() )
69 debug() << "Found Solid PMP that is also a StorageDrive, skipping";
72 debug() << "Found Solid::DeviceInterface::PortableMediaPlayer with udi = " << device
.udi();
73 debug() << "Device name is = " << device
.product() << " and was made by " << device
.vendor();
74 m_type
[device
.udi()] = MediaDeviceCache::SolidPMPType
;
75 m_name
[device
.udi()] = device
.vendor() + " - " + device
.product();
77 deviceList
= Solid::Device::listFromType( Solid::DeviceInterface::StorageAccess
);
78 foreach( Solid::Device device
, deviceList
)
80 debug() << "Found Solid::DeviceInterface::StorageAccess with udi = " << device
.udi();
81 debug() << "Device name is = " << device
.product() << " and was made by " << device
.vendor();
82 Solid::StorageAccess
* ssa
= device
.as
<Solid::StorageAccess
>();
85 if( !m_volumes
.contains( device
.udi() ) )
87 connect( ssa
, SIGNAL( accessibilityChanged(bool, const QString
&) ),
88 this, SLOT( slotAccessibilityChanged(bool, const QString
&) ) );
89 m_volumes
.append( device
.udi() );
91 if( ssa
->isAccessible() )
93 m_type
[device
.udi()] = MediaDeviceCache::SolidVolumeType
;
94 m_name
[device
.udi()] = device
.parent().vendor() + " - " + device
.parent().product();
98 debug() << "Solid device is not accessible, will wait until it is to consider it added.";
102 KConfigGroup config
= Amarok::config( "PortableDevices" );
103 QMap
<QString
, QString
> manualDevices
= config
.entryMap();
104 foreach( const QString
&udi
, manualDevices
.keys() )
106 if( udi
.startsWith( "manual" ) )
108 debug() << "Found manual device with udi = " << udi
;
109 m_type
[udi
] = MediaDeviceCache::ManualType
;
110 m_name
[udi
] = udi
.split( '|' )[1];
116 MediaDeviceCache::slotAddSolidDevice( const QString
&udi
)
119 Solid::Device
device( udi
);
120 debug() << "Found new Solid device with udi = " << device
.udi();
121 debug() << "Device name is = " << device
.product() << " and was made by " << device
.vendor();
122 if( m_type
.contains( udi
) )
124 debug() << "Duplicate UDI trying to be added: " << udi
;
127 if( device
.as
<Solid::StorageDrive
>() )
129 debug() << "Storage drive found, will wait for the volume";
132 else if( device
.as
<Solid::StorageAccess
>() )
134 debug() << "volume is generic storage";
135 if( !m_volumes
.contains( device
.udi() ) )
137 connect( device
.as
<Solid::StorageAccess
>(), SIGNAL( accessibilityChanged(bool, const QString
&) ),
138 this, SLOT( slotAccessibilityChanged(bool, const QString
&) ) );
139 m_volumes
.append( device
.udi() );
141 if( device
.as
<Solid::StorageAccess
>()->isAccessible() )
143 m_type
[udi
] = MediaDeviceCache::SolidVolumeType
;
144 m_name
[udi
] = device
.parent().vendor() + " - " + device
.parent().product();
148 debug() << "storage volume is not accessible right now, not adding.";
152 else if( device
.as
<Solid::PortableMediaPlayer
>() )
154 debug() << "device is a PMP";
155 m_type
[udi
] = MediaDeviceCache::SolidPMPType
;
156 m_name
[udi
] = device
.vendor() + " - " + device
.product();
160 debug() << "udi " << udi
<< " does not describe a portable media player or storage volume";
163 emit
deviceAdded( udi
);
167 MediaDeviceCache::slotRemoveSolidDevice( const QString
&udi
)
170 debug() << "udi is: " << udi
;
171 Solid::Device
device( udi
);
172 if( m_volumes
.contains( udi
) )
174 disconnect( device
.as
<Solid::StorageAccess
>(), SIGNAL( accessibilityChanged(bool, const QString
&) ),
175 this, SLOT( slotAccessibilityChanged(bool, const QString
&) ) );
176 m_volumes
.removeAll( udi
);
178 if( m_type
.contains( udi
) )
180 m_type
.remove( udi
);
181 m_name
.remove( udi
);
182 emit
deviceRemoved( udi
);
185 debug() << "Odd, got a deviceRemoved at udi " << udi
<< " but it didn't seem to exist in the first place...";
189 MediaDeviceCache::slotAccessibilityChanged( bool accessible
, const QString
&udi
)
192 debug() << "accessibility of device " << udi
<< " has changed to accessible = " << (accessible
? "true":"false");
195 Solid::Device
device( udi
);
196 m_type
[udi
] = MediaDeviceCache::SolidVolumeType
;
197 m_name
[udi
] = device
.parent().vendor() + " - " + device
.parent().product();
198 emit
deviceAdded( udi
);
203 if( m_type
.contains( udi
) )
205 m_type
.remove( udi
);
206 m_name
.remove( udi
);
207 emit
deviceRemoved( udi
);
210 debug() << "Got accessibility changed to false but wasn't there in the first place...";
214 const MediaDeviceCache::DeviceType
215 MediaDeviceCache::deviceType( const QString
&udi
) const
218 if( m_type
.contains( udi
) )
222 return MediaDeviceCache::InvalidType
;
226 MediaDeviceCache::deviceName( const QString
&udi
) const
229 if( m_name
.contains( udi
) )
233 return "ERR_NO_NAME"; //Should never happen!
237 MediaDeviceCache::isGenericEnabled( const QString
&udi
) const
240 if( m_type
[udi
] != MediaDeviceCache::SolidVolumeType
)
242 debug() << "Not SolidVolumeType, returning false";
245 Solid::Device
device( udi
);
246 Solid::StorageAccess
* ssa
= device
.as
<Solid::StorageAccess
>();
247 if( !ssa
|| !ssa
->isAccessible() )
249 debug() << "Not able to convert to StorageAccess or not accessible, returning false";
252 if( device
.parent().as
<Solid::PortableMediaPlayer
>() )
254 debug() << "Could convert parent to PortableMediaPlayer, returning true";
257 KIO::UDSEntry udsentry
;
258 if( !KIO::NetAccess::stat( ssa
->filePath() + "/.is_audio_player", udsentry
, Amarok::mainWindow() ) )
260 debug() << "Did not stat .is_audio_player successfully, returning false";
263 debug() << "Returning true";
268 MediaDeviceCache::volumeMountPoint( const QString
&udi
) const
271 Solid::Device
device( udi
);
272 Solid::StorageAccess
* ssa
= device
.as
<Solid::StorageAccess
>();
273 if( !ssa
|| !ssa
->isAccessible() )
275 debug() << "Not able to convert to StorageAccess or not accessible, returning empty";
278 return ssa
->filePath();
281 #include "MediaDeviceCache.moc"