1 /****************************************************************************************
2 * Copyright (c) 2008 Alejandro Wainzinger <aikawarazuni@gmail.com> *
3 * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org> *
4 * *
5 * This program is free software; you can redistribute it and/or modify it under *
6 * the terms of the GNU General Public License as published by the Free Software *
7 * Foundation; either version 2 of the License, or (at your option) any later *
8 * version. *
9 * *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY *
11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
12 * PARTICULAR PURPOSE. See the GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License along with *
15 * this program. If not, see <http://www.gnu.org/licenses/>. *
16 ****************************************************************************************/
17
18 #define DEBUG_PREFIX "MediaDeviceMonitor"
19
20 #include "MediaDeviceMonitor.h"
21
22 #include "MediaDeviceCache.h"
23 #include "core-impl/collections/mediadevicecollection/support/ConnectionAssistant.h"
24 #include "core/support/Debug.h"
25
26 #include <Solid/DeviceNotifier>
27 #include <Solid/Device>
28 #include <Solid/OpticalDisc>
29 #include <Solid/StorageAccess>
30 #include <Solid/StorageDrive>
31 #include <Solid/PortableMediaPlayer>
32 #include <Solid/OpticalDrive>
33
34 #include <QTimer>
35
36 MediaDeviceMonitor* MediaDeviceMonitor::s_instance = nullptr;
37
MediaDeviceMonitor()38 MediaDeviceMonitor::MediaDeviceMonitor() : QObject()
39 , m_udiAssistants()
40 , m_assistants()
41 , m_waitingassistants()
42 , m_nextassistant( 0 )
43 // NOTE: commented out, needs porting to new device framework
44 //, m_currentCdId( QString() )
45 {
46 DEBUG_BLOCK
47 s_instance = this;
48 init();
49 }
50
~MediaDeviceMonitor()51 MediaDeviceMonitor::~MediaDeviceMonitor()
52 {
53 s_instance = nullptr;
54 }
55
56 void
init()57 MediaDeviceMonitor::init()
58 {
59 DEBUG_BLOCK
60
61 // connect to device cache so new devices are tested too
62 connect( MediaDeviceCache::instance(), &MediaDeviceCache::deviceAdded,
63 this, &MediaDeviceMonitor::deviceAdded );
64 connect( MediaDeviceCache::instance(), &MediaDeviceCache::deviceRemoved,
65 this, &MediaDeviceMonitor::slotDeviceRemoved );
66 connect( MediaDeviceCache::instance(), &MediaDeviceCache::accessibilityChanged,
67 this, &MediaDeviceMonitor::slotAccessibilityChanged );
68 }
69
70 QStringList
getDevices()71 MediaDeviceMonitor::getDevices()
72 {
73 DEBUG_BLOCK
74 /* get list of devices */
75 MediaDeviceCache::instance()->refreshCache();
76 return MediaDeviceCache::instance()->getAll();
77
78 }
79
checkDevice(const QString & udi)80 void MediaDeviceMonitor::checkDevice(const QString& udi)
81 {
82 DEBUG_BLOCK
83
84 // First let the higher priority devices check
85
86 foreach( ConnectionAssistant* assistant, m_assistants )
87 {
88 checkOneDevice( assistant, udi );
89 }
90
91 // Then let the assistants that can wait check
92
93 foreach( ConnectionAssistant* assistant, m_waitingassistants )
94 {
95 checkOneDevice( assistant, udi );
96 }
97
98 }
99
checkOneDevice(ConnectionAssistant * assistant,const QString & udi)100 void MediaDeviceMonitor::checkOneDevice( ConnectionAssistant* assistant, const QString& udi )
101 {
102 // Ignore already identified devices
103 if( m_udiAssistants.keys().contains( udi ) )
104 {
105 debug() << "Device already identified with udi: " << udi;
106 return;
107 }
108
109 if( assistant->identify( udi ) )
110 {
111 debug() << "Device identified with udi: " << udi;
112 // keep track of which assistant deals with which device
113 m_udiAssistants.insert( udi, assistant );
114 // inform factory of new device identified
115 assistant->tellIdentified( udi );
116 return;
117 }
118 }
119
checkDevicesFor(ConnectionAssistant * assistant)120 void MediaDeviceMonitor::checkDevicesFor( ConnectionAssistant* assistant )
121 {
122 DEBUG_BLOCK
123
124 QStringList udiList = getDevices();
125
126 foreach( const QString &udi, udiList )
127 {
128 checkOneDevice( assistant, udi );
129 }
130
131 }
132
133 void
registerDeviceType(ConnectionAssistant * assistant)134 MediaDeviceMonitor::registerDeviceType( ConnectionAssistant* assistant )
135 {
136 DEBUG_BLOCK
137
138 // If the device wants to wait and give other device types
139 // a chance to recognize devices, put it in a queue for
140 // later device checking
141
142 if ( assistant->wait() )
143 {
144 // keep track of this type of device from now on
145 m_waitingassistants << assistant;
146
147 QTimer::singleShot( 1000, this, &MediaDeviceMonitor::slotDequeueWaitingAssistant );
148 }
149 else
150 {
151 // keep track of this type of device from now on
152 m_assistants << assistant;
153
154 // start initial check for devices of this type
155 checkDevicesFor( assistant );
156 }
157
158 }
159
160 void
deviceAdded(const QString & udi)161 MediaDeviceMonitor::deviceAdded( const QString &udi )
162 {
163 DEBUG_BLOCK
164
165 // check if device is a known device
166 checkDevice( udi );
167 }
168
169 void
slotDeviceRemoved(const QString & udi)170 MediaDeviceMonitor::slotDeviceRemoved( const QString &udi )
171 {
172 DEBUG_BLOCK
173
174 if ( m_udiAssistants.contains( udi ) )
175 {
176
177 m_udiAssistants.value( udi )->tellDisconnected( udi );
178
179 m_udiAssistants.remove( udi );
180 }
181
182
183 // Q_EMIT deviceRemoved( udi );
184 }
185
186 void
slotAccessibilityChanged(bool accessible,const QString & udi)187 MediaDeviceMonitor::slotAccessibilityChanged( bool accessible, const QString & udi)
188 {
189 // TODO: build a hack to force a device to become accessible or not
190 // This means auto-mounting of Ipod, and ejecting of it too
191
192 DEBUG_BLOCK
193 debug() << "Accessibility changed to: " << ( accessible ? "true":"false" );
194 if ( !accessible )
195 deviceRemoved( udi );
196 else
197 deviceAdded( udi );
198 }
199
200 void
slotDequeueWaitingAssistant()201 MediaDeviceMonitor::slotDequeueWaitingAssistant()
202 {
203 checkDevicesFor( m_waitingassistants.at( m_nextassistant++ ) );
204 }
205