File indexing completed on 2024-04-21 04:47:52
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Alejandro Wainzinger <aikawarazuni@gmail.com> * 0003 * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify it under * 0006 * the terms of the GNU General Public License as published by the Free Software * 0007 * Foundation; either version 2 of the License, or (at your option) any later * 0008 * version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0012 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License along with * 0015 * this program. If not, see <http://www.gnu.org/licenses/>. * 0016 ****************************************************************************************/ 0017 0018 #define DEBUG_PREFIX "MediaDeviceMonitor" 0019 0020 #include "MediaDeviceMonitor.h" 0021 0022 #include "MediaDeviceCache.h" 0023 #include "core-impl/collections/mediadevicecollection/support/ConnectionAssistant.h" 0024 #include "core/support/Debug.h" 0025 0026 #include <Solid/DeviceNotifier> 0027 #include <Solid/Device> 0028 #include <Solid/OpticalDisc> 0029 #include <Solid/StorageAccess> 0030 #include <Solid/StorageDrive> 0031 #include <Solid/PortableMediaPlayer> 0032 #include <Solid/OpticalDrive> 0033 0034 #include <QTimer> 0035 0036 MediaDeviceMonitor* MediaDeviceMonitor::s_instance = nullptr; 0037 0038 MediaDeviceMonitor::MediaDeviceMonitor() : QObject() 0039 , m_udiAssistants() 0040 , m_assistants() 0041 , m_waitingassistants() 0042 , m_nextassistant( 0 ) 0043 // NOTE: commented out, needs porting to new device framework 0044 //, m_currentCdId( QString() ) 0045 { 0046 DEBUG_BLOCK 0047 s_instance = this; 0048 init(); 0049 } 0050 0051 MediaDeviceMonitor::~MediaDeviceMonitor() 0052 { 0053 s_instance = nullptr; 0054 } 0055 0056 void 0057 MediaDeviceMonitor::init() 0058 { 0059 DEBUG_BLOCK 0060 0061 // connect to device cache so new devices are tested too 0062 connect( MediaDeviceCache::instance(), &MediaDeviceCache::deviceAdded, 0063 this, &MediaDeviceMonitor::deviceAdded ); 0064 connect( MediaDeviceCache::instance(), &MediaDeviceCache::deviceRemoved, 0065 this, &MediaDeviceMonitor::slotDeviceRemoved ); 0066 connect( MediaDeviceCache::instance(), &MediaDeviceCache::accessibilityChanged, 0067 this, &MediaDeviceMonitor::slotAccessibilityChanged ); 0068 } 0069 0070 QStringList 0071 MediaDeviceMonitor::getDevices() 0072 { 0073 DEBUG_BLOCK 0074 /* get list of devices */ 0075 MediaDeviceCache::instance()->refreshCache(); 0076 return MediaDeviceCache::instance()->getAll(); 0077 0078 } 0079 0080 void MediaDeviceMonitor::checkDevice(const QString& udi) 0081 { 0082 DEBUG_BLOCK 0083 0084 // First let the higher priority devices check 0085 0086 foreach( ConnectionAssistant* assistant, m_assistants ) 0087 { 0088 checkOneDevice( assistant, udi ); 0089 } 0090 0091 // Then let the assistants that can wait check 0092 0093 foreach( ConnectionAssistant* assistant, m_waitingassistants ) 0094 { 0095 checkOneDevice( assistant, udi ); 0096 } 0097 0098 } 0099 0100 void MediaDeviceMonitor::checkOneDevice( ConnectionAssistant* assistant, const QString& udi ) 0101 { 0102 // Ignore already identified devices 0103 if( m_udiAssistants.keys().contains( udi ) ) 0104 { 0105 debug() << "Device already identified with udi: " << udi; 0106 return; 0107 } 0108 0109 if( assistant->identify( udi ) ) 0110 { 0111 debug() << "Device identified with udi: " << udi; 0112 // keep track of which assistant deals with which device 0113 m_udiAssistants.insert( udi, assistant ); 0114 // inform factory of new device identified 0115 assistant->tellIdentified( udi ); 0116 return; 0117 } 0118 } 0119 0120 void MediaDeviceMonitor::checkDevicesFor( ConnectionAssistant* assistant ) 0121 { 0122 DEBUG_BLOCK 0123 0124 QStringList udiList = getDevices(); 0125 0126 foreach( const QString &udi, udiList ) 0127 { 0128 checkOneDevice( assistant, udi ); 0129 } 0130 0131 } 0132 0133 void 0134 MediaDeviceMonitor::registerDeviceType( ConnectionAssistant* assistant ) 0135 { 0136 DEBUG_BLOCK 0137 0138 // If the device wants to wait and give other device types 0139 // a chance to recognize devices, put it in a queue for 0140 // later device checking 0141 0142 if ( assistant->wait() ) 0143 { 0144 // keep track of this type of device from now on 0145 m_waitingassistants << assistant; 0146 0147 QTimer::singleShot( 1000, this, &MediaDeviceMonitor::slotDequeueWaitingAssistant ); 0148 } 0149 else 0150 { 0151 // keep track of this type of device from now on 0152 m_assistants << assistant; 0153 0154 // start initial check for devices of this type 0155 checkDevicesFor( assistant ); 0156 } 0157 0158 } 0159 0160 void 0161 MediaDeviceMonitor::deviceAdded( const QString &udi ) 0162 { 0163 DEBUG_BLOCK 0164 0165 // check if device is a known device 0166 checkDevice( udi ); 0167 } 0168 0169 void 0170 MediaDeviceMonitor::slotDeviceRemoved( const QString &udi ) 0171 { 0172 DEBUG_BLOCK 0173 0174 if ( m_udiAssistants.contains( udi ) ) 0175 { 0176 0177 m_udiAssistants.value( udi )->tellDisconnected( udi ); 0178 0179 m_udiAssistants.remove( udi ); 0180 } 0181 0182 0183 // Q_EMIT deviceRemoved( udi ); 0184 } 0185 0186 void 0187 MediaDeviceMonitor::slotAccessibilityChanged( bool accessible, const QString & udi) 0188 { 0189 // TODO: build a hack to force a device to become accessible or not 0190 // This means auto-mounting of Ipod, and ejecting of it too 0191 0192 DEBUG_BLOCK 0193 debug() << "Accessibility changed to: " << ( accessible ? "true":"false" ); 0194 if ( !accessible ) 0195 deviceRemoved( udi ); 0196 else 0197 deviceAdded( udi ); 0198 } 0199 0200 void 0201 MediaDeviceMonitor::slotDequeueWaitingAssistant() 0202 { 0203 checkDevicesFor( m_waitingassistants.at( m_nextassistant++ ) ); 0204 }