27 #include <hbdevicedialogserverdefs_p.h> |
27 #include <hbdevicedialogserverdefs_p.h> |
28 #include <apacmdln.h> |
28 #include <apacmdln.h> |
29 |
29 |
30 #include "hbdevicedialogclientsession_p.h" |
30 #include "hbdevicedialogclientsession_p.h" |
31 |
31 |
32 _LIT(KSemaName, "hbdevdlgcli_"); |
32 // Check if the client is running in device dialog server |
|
33 static bool IsDeviceDialogServer() |
|
34 { |
|
35 const TUid ServerUid = {0x20022FC5}; |
|
36 return RProcess().SecureId().operator TUid() == ServerUid; |
|
37 } |
|
38 |
|
39 // Preallocate 1 message slot for sessions |
|
40 static const int KNumAsyncMessageSlots = 1; |
33 |
41 |
34 /*! |
42 /*! |
35 \internal |
43 \internal |
36 */ |
44 */ |
37 RHbDeviceDialogClientSession::RHbDeviceDialogClientSession() |
45 RHbDeviceDialogClientSession::RHbDeviceDialogClientSession() |
50 } |
58 } |
51 |
59 |
52 TInt RHbDeviceDialogClientSession::Connect(TRequestStatus *aStatus) |
60 TInt RHbDeviceDialogClientSession::Connect(TRequestStatus *aStatus) |
53 { |
61 { |
54 TRACE_ENTRY |
62 TRACE_ENTRY |
|
63 // Check server is not trying to connect to itself |
|
64 if (IsDeviceDialogServer()) { |
|
65 return KErrNotSupported; |
|
66 } |
|
67 |
55 TInt error = KErrNone; |
68 TInt error = KErrNone; |
56 if (ServerRunning()) { |
69 if (ServerRunning()) { |
57 if (!Handle()) { |
70 if (!Handle()) { |
58 TUid serviceUid = { 0x10009822 }; |
71 TVersion serverVersion(KHbServerMajor, KHbServerMinor, KHbServerBuild); |
59 error = CreateSession(KHbServerName, *reinterpret_cast<TVersion*>(&serviceUid), |
72 error = CreateSession(KHbServerName, serverVersion, KNumAsyncMessageSlots, |
60 -1, EIpcSession_Unsharable, 0, aStatus); |
73 EIpcSession_Unsharable, 0, aStatus); |
61 } |
74 } |
62 } else { |
75 } else { |
63 error = Connect(); |
76 error = Connect(); |
64 User::RequestComplete(aStatus, error); |
77 User::RequestComplete(aStatus, error); |
65 } |
78 } |
81 */ |
94 */ |
82 TInt RHbDeviceDialogClientSession::Connect() |
95 TInt RHbDeviceDialogClientSession::Connect() |
83 { |
96 { |
84 TRACE_ENTRY |
97 TRACE_ENTRY |
85 |
98 |
|
99 // Check server is not trying to connect to itself |
|
100 if (IsDeviceDialogServer()) { |
|
101 return KErrNotSupported; |
|
102 } |
|
103 |
86 TInt error = KErrNone; |
104 TInt error = KErrNone; |
87 |
|
88 // Create semaphore. Sserver application signals it after server object is created. Also |
|
89 // existence of the semaphore tells server app that connection is in the progress and it |
|
90 // should not start exiting. |
|
91 RSemaphore serverStartedSema; |
|
92 TBuf<sizeof(KSemaName) + 16> semaName(KSemaName); // name + thread id |
|
93 semaName.AppendNum(RThread().Id().Id(), EHex); |
|
94 error = serverStartedSema.CreateGlobal(semaName, 0, EOwnerProcess); |
|
95 if (error != KErrNone) { |
|
96 return error; |
|
97 } |
|
98 |
105 |
99 TInt retry(3); |
106 TInt retry(3); |
100 if (!Handle()) { |
107 if (!Handle()) { |
101 TUid serviceUid = { 0x10009822 }; |
|
102 |
|
103 forever { |
108 forever { |
104 error = CreateSession(KHbServerName, *reinterpret_cast<TVersion*>(&serviceUid)); |
109 TVersion serverVersion(KHbServerMajor, KHbServerMinor, KHbServerBuild); |
|
110 error = CreateSession(KHbServerName, serverVersion, KNumAsyncMessageSlots); |
105 |
111 |
106 if (error != KErrNotFound && error != KErrServerTerminated) { |
112 if (error != KErrNotFound && error != KErrServerTerminated) { |
107 // KErrNone, KErrPermissionDenied or other serious error. |
113 // KErrNone, KErrPermissionDenied or other serious error. |
108 break; |
114 break; |
109 } |
115 } |
111 if (--retry == 0) { |
117 if (--retry == 0) { |
112 // We have tried enough, return an error. |
118 // We have tried enough, return an error. |
113 break; |
119 break; |
114 } |
120 } |
115 |
121 |
116 error = StartServer(serverStartedSema); |
122 error = StartServer(); |
117 |
|
118 if (error != KErrNone && error != KErrAlreadyExists) { |
123 if (error != KErrNone && error != KErrAlreadyExists) { |
119 // Unrecoverable error, return an error. |
124 // Unrecoverable error, return an error. |
120 break; |
125 break; |
121 } |
126 } |
122 } // for-loop end |
127 } // for-loop end |
123 } |
128 } |
124 serverStartedSema.Close(); |
|
125 TRACE_EXIT |
129 TRACE_EXIT |
126 return error; |
130 return error; |
127 } |
131 } |
128 |
132 |
129 /*! |
133 /*! |
130 \internal |
134 \internal |
131 */ |
135 */ |
132 TInt RHbDeviceDialogClientSession::StartServer(RSemaphore &aServerStartedSema) |
136 TInt RHbDeviceDialogClientSession::StartServer() |
133 { |
137 { |
134 TRACE_ENTRY |
138 TRACE_ENTRY |
135 TInt error(KErrNone); |
139 TInt error(KErrNone); |
136 |
140 |
137 TFindServer findHbServer(KHbServerName); |
141 if (ServerRunning()) { |
138 TFullName name; |
|
139 |
|
140 error = findHbServer.Next(name); |
|
141 |
|
142 if (error == KErrNone) { |
|
143 // Already running, return error. |
142 // Already running, return error. |
144 return KErrAlreadyExists; |
143 return KErrAlreadyExists; |
145 } |
144 } |
146 |
145 |
147 RProcess process; |
146 RProcess process; |
193 error = KErrGeneral; |
192 error = KErrGeneral; |
194 } else { |
193 } else { |
195 error = status.Int(); |
194 error = status.Int(); |
196 } |
195 } |
197 |
196 |
198 // QApplication calls Rendezvous() before device dialog server has created server object. |
|
199 // Therefore we wait here for server app to create the server object. |
|
200 if (error == KErrNone || error == KErrAlreadyExists) { |
|
201 forever { |
|
202 findHbServer.Find(KHbServerName); |
|
203 error = findHbServer.Next(name); |
|
204 if (error != KErrNotFound) { |
|
205 break; |
|
206 } |
|
207 if (process.ExitType() != EExitPending) { |
|
208 error = KErrGeneral; |
|
209 break; |
|
210 } |
|
211 const TInt KTimeout = 1000000; // 1 s |
|
212 aServerStartedSema.Wait(KTimeout); |
|
213 } |
|
214 } |
|
215 process.Close(); |
197 process.Close(); |
216 TRACE_EXIT |
198 TRACE_EXIT |
217 return error; |
199 return error; |
218 } |
200 } |
219 |
201 |