16 */ |
16 */ |
17 |
17 |
18 |
18 |
19 #include <e32base.h> |
19 #include <e32base.h> |
20 #include <f32file.h> |
20 #include <f32file.h> |
|
21 #include <driveinfo.h> |
21 #include <mpxlog.h> |
22 #include <mpxlog.h> |
22 #include "mpxmediaremovalmonitor.h" |
23 #include "mpxmediaremovalmonitor.h" |
23 |
24 |
24 // --------------------------------------------------------------------------- |
25 // --------------------------------------------------------------------------- |
25 // C++ Constructor |
26 // C++ Constructor |
26 // --------------------------------------------------------------------------- |
27 // --------------------------------------------------------------------------- |
27 // |
28 // |
28 CMPXMediaRemovalMonitor::CMPXMediaRemovalMonitor |
29 CMPXMediaRemovalMonitor::CMPXMediaRemovalMonitor |
29 ( TInt aDrive, RFs& aFs, MMPXSystemEventObserver& aObserver ) |
30 ( TInt aDrive, RFs& aFs, MMPXSystemEventObserver& aObserver ) |
30 : CActive(EPriorityHigh), |
31 : iDrive( aDrive ), |
31 iDrive( aDrive ), |
|
32 iFs( aFs ), |
32 iFs( aFs ), |
33 iDiskRemoved( EFalse ), |
33 iDiskRemoved( EFalse ), |
34 iObserver( aObserver ) |
34 iObserver( aObserver ) |
35 |
35 |
36 { |
36 { |
37 CActiveScheduler::Add(this); |
|
38 } |
37 } |
39 |
38 |
40 |
39 |
41 // --------------------------------------------------------------------------- |
40 // --------------------------------------------------------------------------- |
42 // 2nd Phase Constructor |
41 // 2nd Phase Constructor |
43 // --------------------------------------------------------------------------- |
42 // --------------------------------------------------------------------------- |
44 // |
43 // |
45 void CMPXMediaRemovalMonitor::ConstructL() |
44 void CMPXMediaRemovalMonitor::ConstructL() |
46 { |
45 { |
47 MPX_DEBUG1(_L("CMPXMediaRemovalMonitor::ConstructL <---")); |
46 MPX_FUNC("CMPXMediaRemovalMonitor::ConstructL"); |
|
47 iDiskNotifyHandler = CDiskNotifyHandler::NewL(*this, iFs); |
|
48 CheckDriveStatus(); |
48 |
49 |
49 // Initial state |
50 iDiskNotifyHandler->NotifyDisk(); |
50 TDriveInfo drive; |
|
51 User::LeaveIfError(iFs.Drive(drive, TInt(iDrive))); |
|
52 iDiskRemoved = (drive.iType == EMediaNotPresent); |
|
53 |
|
54 // Start listening |
|
55 TNotifyType notType(ENotifyDisk); |
|
56 iFs.NotifyChange( notType, iStatus ); |
|
57 SetActive(); |
|
58 |
|
59 MPX_DEBUG1(_L("CMPXMediaRemovalMonitor::ConstructL --->")); |
|
60 } |
51 } |
61 |
52 |
62 |
53 |
63 // --------------------------------------------------------------------------- |
54 // --------------------------------------------------------------------------- |
64 // Two-Phased Constructor |
55 // Two-Phased Constructor |
97 // Destructor |
88 // Destructor |
98 // --------------------------------------------------------------------------- |
89 // --------------------------------------------------------------------------- |
99 // |
90 // |
100 CMPXMediaRemovalMonitor::~CMPXMediaRemovalMonitor() |
91 CMPXMediaRemovalMonitor::~CMPXMediaRemovalMonitor() |
101 { |
92 { |
102 Cancel(); |
93 delete iDiskNotifyHandler; |
|
94 } |
|
95 |
|
96 void CMPXMediaRemovalMonitor::CheckDriveStatus() |
|
97 { |
|
98 TDriveList driveList; |
|
99 TInt driveCount(0); |
|
100 TInt error = DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ); |
|
101 if ( error != KErrNone ) |
|
102 { |
|
103 MPX_DEBUG2("CMPXMediaRemovalMonitor::CheckDriveStatus GetUserVisibleDrives failed, error %d", error); |
|
104 return; |
|
105 } |
|
106 for( TInt driveNum = EDriveA; driveNum < EDriveZ; driveNum++ ) |
|
107 { |
|
108 if ( driveNum != EDriveC && driveList[driveNum] ) |
|
109 { |
|
110 TDriveInfo driveInfo; |
|
111 if (iFs.Drive(driveInfo, driveNum) == KErrNone) |
|
112 { |
|
113 if ( (driveInfo.iType != EMediaNotPresent) && ! (driveInfo.iDriveAtt & KDriveAttRemote) ) |
|
114 { |
|
115 TInt error = iDiskNotifyHandler->NotifyDismount( driveNum ); |
|
116 MPX_DEBUG3("CMPXMediaRemovalMonitor::CheckDriveStatus monitoring drive %d for dismounts, error %d", driveNum, error); |
|
117 } |
|
118 } |
|
119 if ( driveNum == iDrive ) |
|
120 { |
|
121 iDiskRemoved = driveInfo.iType == EMediaNotPresent; |
|
122 } |
|
123 } |
|
124 } |
103 } |
125 } |
104 |
126 |
105 |
|
106 // --------------------------------------------------------------------------- |
127 // --------------------------------------------------------------------------- |
107 // Service the request |
128 // Callback when disk state has changed |
108 // --------------------------------------------------------------------------- |
129 // --------------------------------------------------------------------------- |
109 // |
130 // |
110 void CMPXMediaRemovalMonitor::RunL() |
131 void CMPXMediaRemovalMonitor::HandleNotifyDisk( TInt aError, const TDiskEvent& aEvent ) |
111 { |
132 { |
112 MPX_DEBUG1(_L("CMPXMediaRemovalMonitor::RunL <---")); |
133 MPX_DEBUG4("-->CMPXMediaRemovalMonitor::HandleNotifyDisk aError=%d event=%d drive=%d", aError, aEvent.iType, aEvent.iDrive); |
113 |
134 if ( aError == KErrNone ) |
114 // Re-subscribe to event. |
135 { |
115 TNotifyType notType(ENotifyDisk); |
136 if ( aEvent.iType == EDiskRemoved |
116 iFs.NotifyChange( notType, iStatus ); |
137 || aEvent.iType == EDiskStatusChanged && aEvent.iInfo.iType == EMediaNotPresent ) |
117 SetActive(); |
138 { |
118 |
139 if ( aEvent.iDrive == iDrive && !iDiskRemoved ) |
119 // Check state |
|
120 TDriveInfo drive; |
|
121 User::LeaveIfError(iFs.Drive(drive, TInt(iDrive))); |
|
122 |
|
123 // Notify Observer |
|
124 switch(drive.iType) |
|
125 { |
|
126 case EMediaNotPresent: |
|
127 { |
|
128 if (!iDiskRemoved) |
|
129 { |
140 { |
130 iObserver.HandleSystemEventL( EDiskRemovedEvent, iDrive ); |
141 iObserver.HandleSystemEventL( EDiskRemovedEvent, iDrive ); |
|
142 iDiskRemoved = ETrue; |
131 } |
143 } |
132 iDiskRemoved = ETrue; |
144 |
133 break; |
145 } |
134 } |
146 else if ( ( aEvent.iType == EDiskAdded || aEvent.iType == EDiskStatusChanged ) |
135 default: |
147 && aEvent.iInfo.iType != EMediaNotPresent ) |
136 { |
148 { |
137 if ( iDiskRemoved && |
149 if ( aEvent.iDrive == iDrive |
138 ( drive.iMediaAtt & ( KMediaAttLockable|KMediaAttLocked|KMediaAttHasPassword ) ) != |
150 && iDiskRemoved |
139 ( KMediaAttLockable|KMediaAttLocked|KMediaAttHasPassword ) ) |
151 && ( aEvent.iInfo.iMediaAtt & ( KMediaAttLockable|KMediaAttLocked|KMediaAttHasPassword ) ) |
|
152 != ( KMediaAttLockable|KMediaAttLocked|KMediaAttHasPassword ) ) |
140 { |
153 { |
141 iObserver.HandleSystemEventL( EDiskInsertedEvent, iDrive ); |
154 iObserver.HandleSystemEventL( EDiskInsertedEvent, iDrive ); |
142 iDiskRemoved = EFalse; |
155 iDiskRemoved = EFalse; |
143 } |
156 } |
144 break; |
157 |
145 } |
158 if ( !( aEvent.iInfo.iDriveAtt & KDriveAttRemote ) ) |
|
159 { |
|
160 TInt error = iDiskNotifyHandler->NotifyDismount( aEvent.iDrive ); |
|
161 MPX_DEBUG3("CMPXMediaRemovalMonitor::HandleNotifyDisk monitoring drive %d for dismounts, error %d", aEvent.iDrive, error); |
|
162 } |
|
163 } |
146 } |
164 } |
147 |
165 |
|
166 MPX_DEBUG1("<--CMPXMediaRemovalMonitor::HandleNotifyDisk"); |
|
167 } |
148 |
168 |
149 MPX_DEBUG1(_L("CMPXMediaRemovalMonitor::RunL --->")); |
|
150 } |
|
151 |
169 |
152 // --------------------------------------------------------------------------- |
170 // --------------------------------------------------------------------------- |
153 // Cancel NotifyChange request from file system |
171 // Callback when disk is about to be dismounted |
154 // --------------------------------------------------------------------------- |
172 // --------------------------------------------------------------------------- |
155 // |
173 // |
156 void CMPXMediaRemovalMonitor::DoCancel() |
174 void CMPXMediaRemovalMonitor::HandleNotifyDismount( TInt aError, const TDismountEvent& aEvent ) |
157 { |
175 { |
158 iFs.NotifyChangeCancel(); |
176 MPX_DEBUG3("-->CMPXMediaRemovalMonitor::HandleNotifyDismount aError=%d drive=%d", aError, aEvent.iDrive); |
|
177 if (aError == KErrNone) |
|
178 { |
|
179 TRAP_IGNORE( iObserver.HandleSystemEventL( EDiskDismountEvent, aEvent.iDrive ) ); |
|
180 TInt error = iDiskNotifyHandler->AllowDismount( aEvent.iDrive ); |
|
181 MPX_DEBUG3("CMPXMediaRemovalMonitor::HandleNotifyDismount allowed dismount of drive %d, error %d", aEvent.iDrive, error); |
|
182 } |
|
183 MPX_DEBUG1("<--CMPXMediaRemovalMonitor::HandleNotifyDismount"); |
159 } |
184 } |
160 |
|
161 // ---------------------------------------------------------------------------- |
|
162 // Handles a leave occurring in the request completion event handler RunL() |
|
163 // Don't care if client has a User::Leave() in RunL(), keep monitoring for events |
|
164 // ---------------------------------------------------------------------------- |
|
165 // |
|
166 TInt CMPXMediaRemovalMonitor::RunError(TInt aError) |
|
167 { |
|
168 MPX_DEBUG2("CMPXMediaRemovalMonitor::RunError(%d)", aError ); |
|
169 (void) aError; // avoid compile warning in urel |
|
170 |
|
171 return KErrNone; |
|
172 } |
|