|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-55629D12-06C9-412C-86FE-442577156A3B" xml:lang="en"><title>Implementing |
|
13 the CPosPrivacyNotifier Subclass</title><shortdesc>To use the Privacy Query and Notification API to create a notifier |
|
14 a licensee must first implement a single notifier class that derives from |
|
15 the Privacy Query and Notification API base class <apiname>CPosPrivacyNotifier</apiname>.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
16 <p>The <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita"><apiname>CPosPrivacyNotifier</apiname></xref> subclass must implement the |
|
17 virtual functions of the base class: </p> |
|
18 <ul> |
|
19 <li><p><xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-33E317F9-A8C0-34AF-B17A-72D46B2E4DBD"><apiname>CPosPrivacyNotifier::HandleNewRequestL()</apiname></xref></p></li> |
|
20 <li><p><xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-3417B07B-DE69-3719-8634-B979CBA77AFE"><apiname>CPosPrivacyNotifier::HandleRequestCancelled()</apiname></xref></p></li> |
|
21 <li><p><xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-6D3C8687-6FEC-34FF-9846-1508C9DF4E72"><apiname>CPosPrivacyNotifier::HandleAllRequestsCancelled()</apiname></xref></p></li> |
|
22 </ul> |
|
23 <section> <title>Implementing HandleNewRequestL()</title> <p>New |
|
24 privacy verification query and notification requests are received by the notifier |
|
25 through <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-33E317F9-A8C0-34AF-B17A-72D46B2E4DBD"><apiname>CPosPrivacyNotifier::HandleNewRequestL()</apiname></xref>. The example |
|
26 code below shows how the notifier handles requests sequentially by simply |
|
27 calling a helper function <xref href="GUID-BEB6299A-9BA4-36BB-8E43-52855B753A04.dita"><apiname>HandleNextRequestL()</apiname></xref> to get the |
|
28 next request.</p> <codeblock xml:space="preserve">void CMyPrivacyNotifier::HandleNewRequestL(TPosQNRequestId /*aRequestId*/) |
|
29 { |
|
30 if (iIsBusy) // TBool flag which specifies if the notifier is already |
|
31 { // handling a request. If it is, do nothing for now. |
|
32 return; |
|
33 } |
|
34 |
|
35 // Handle the request |
|
36 HandleNextRequestL(); |
|
37 }</codeblock></section> |
|
38 <section><title>HandleNextRequestL() </title><p>The example code below shows |
|
39 how the notifier gets the next request to be processed. The code shows how |
|
40 the notifier: </p><ul> |
|
41 <li><p>Gets an array of all waiting requests by calling <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-4E117090-89E5-33DA-AC4B-494906B4BAF9"><apiname>CPosPrivacyNotifier::GetRequestsL()</apiname></xref>. </p></li> |
|
42 <li><p>Gets the first request in the array and sets it as the current request |
|
43 by calling <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-A041F06C-8A22-37D3-B634-894AFE9B7FF0"><apiname>CPosPrivacyNotifier::SetCurrentRequestL()</apiname></xref>. </p></li> |
|
44 <li><p>Checks if the request is a notification, and if so, checks if the request |
|
45 type is supported by calling <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-22FFC3B2-A6B9-3501-AD89-1DB31027F53C"><apiname>CPosPrivacyNotifier::NotificationReason()</apiname></xref>. |
|
46 If the request type is not supported the request is completed by calling <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-57739A9E-F6CD-3079-8B6F-9B80AAFE4D8B"><apiname>CPosPrivacyNotifier::CompleteRequest()</apiname></xref>. </p></li> |
|
47 <li><p>Checks if the type of request is a privacy verification (<codeph>EQuery</codeph>) |
|
48 or a notification (<codeph>ENotification</codeph>) and launches the appropriate |
|
49 dialog for each case. </p><note><codeph>LauchQueryDialog()</codeph> and <codeph>LaunchNotificationDialog()</codeph> show |
|
50 the dialogs. Dialog code varies between licensee platforms but it is important |
|
51 that these methods do not launch modal dialogs. The methods must return quickly |
|
52 and not wait for the dialogs to be dismissed. </note></li> |
|
53 </ul><codeblock xml:space="preserve">void CMyPrivacyNotifier::HandleNextRequestL() |
|
54 { |
|
55 // Read the next request |
|
56 RArray<TPosQNRequestId> requests; |
|
57 CleanupClosePushL(requests); |
|
58 GetRequestsL(requests); |
|
59 |
|
60 // Choose next request to handle |
|
61 TBool requestFound = EFalse; |
|
62 while (!requestFound) |
|
63 { |
|
64 if (requests.Count() == 0) |
|
65 { // There are no requests to handle. Do nothing. |
|
66 CleanupStack::PopAndDestroy(); // requests |
|
67 return; |
|
68 } |
|
69 // Read information about the active request |
|
70 iActiveRequest = requests[0]; |
|
71 SetCurrentRequestL(iActiveRequest); |
|
72 |
|
73 // In case of notification request, check that notification reason is |
|
74 // supported, otherwise complete the request with KErrNotSupported. |
|
75 if (RequestTypeL(iActiveRequest) == ENotification && |
|
76 !(NotificationReason() == EPosDecisionByRequestSource || |
|
77 NotificationReason() == EPosVerificationTimeout)) |
|
78 { // The notification reason is not supported by the UI. |
|
79 CompleteRequest(iActiveRequest, KErrNotSupported); |
|
80 requests.Remove(0); |
|
81 } |
|
82 else |
|
83 { |
|
84 requestFound = ETrue; |
|
85 } |
|
86 } |
|
87 CleanupStack::PopAndDestroy(); // requests |
|
88 |
|
89 iIsBusy = ETrue; |
|
90 |
|
91 CDesCArrayFlat* requestors = new (ELeave) CDesCArrayFlat |
|
92 (KRequestorGranularity); |
|
93 CleanupStack::PushL(requestors); |
|
94 |
|
95 TInt nofRequestors = RequestorCountL(); |
|
96 for (TInt I = 0; I < nofRequestors; I++) |
|
97 { |
|
98 CPosRequestor* requestor = RequestorLC(I); |
|
99 requestors->AppendL(requestor->RequestorIdString()); |
|
100 CleanupStack::PopAndDestroy(requestor); |
|
101 } |
|
102 |
|
103 // Check whether the request is a query or a notification |
|
104 if (RequestTypeL(iActiveRequest) == EQuery) |
|
105 { |
|
106 LaunchQueryDialogL(requestors); // takes array ownership |
|
107 } |
|
108 else // RequestTypeL(iActiveRequest) == ENotification |
|
109 { |
|
110 LaunchNotificationDialogL(requestors); // takes array ownership |
|
111 } |
|
112 CleanupStack::Pop(requestors); |
|
113 }</codeblock></section> |
|
114 <section><title>Implementing a method to handle dialog closure</title><p>When |
|
115 the mobile device user has responded to the dialog, the notifier must send |
|
116 a response back to the LBS subsystem. In the example code below, the method <codeph>DialogDismissed()</codeph> is |
|
117 called when the dialog is closed. The type of request (<codeph>EQuery</codeph> or <codeph>ENotification</codeph>) |
|
118 and the reason why the dialog was closed is passed as an input parameter to |
|
119 the method. </p><note>It is important to note that <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-57739A9E-F6CD-3079-8B6F-9B80AAFE4D8B"><apiname>CPosPrivacyNotifier::CompleteRequest()</apiname></xref> must |
|
120 be called for both privacy verification (query) requests and privacy notification |
|
121 requests.</note><p>Note also how requests are handled sequentially in the |
|
122 code: CPosPrivacyNotifier::HandleNextRequest() is called to process the next |
|
123 request only when the current request is completed.</p><codeblock xml:space="preserve">void CMyPrivacyNotifier::DialogDismissed(TRequestType aRequestType, TInt aDismissReason) |
|
124 { |
|
125 |
|
126 iIsBusy = EFalse; |
|
127 |
|
128 // Complete the request with correct completion code. |
|
129 TInt completionCode = KErrNone; |
|
130 if (aRequestType == EQuery) |
|
131 { |
|
132 switch (aDismissReason) |
|
133 { |
|
134 case EUserChooseAccept : completionCode = KErrNone; break; |
|
135 case EUserChooseReject : completionCode = KErrAccessDenied; break; |
|
136 case EDialogTimedOut : completionCode = KErrTimedOut; break; |
|
137 default : completionCode = KErrGeneral; |
|
138 } |
|
139 } |
|
140 else // aRequestType == ENotification |
|
141 { |
|
142 switch (aDismissReason) |
|
143 { |
|
144 case EUserPressedOk : completionCode = KErrNone; break; |
|
145 case EDialogTimedOut : completionCode = KErrTimedOut; break; |
|
146 default : completionCode = KErrGeneral; |
|
147 } |
|
148 } |
|
149 CompleteRequest(iActiveRequest, completionCode); |
|
150 |
|
151 // Handle the next request |
|
152 HandleNextRequest(); |
|
153 } |
|
154 |
|
155 // Non leaving method for handling the next request |
|
156 void CMyPrivacyNotifier::HandleNextRequest() |
|
157 { |
|
158 TRAPD(err, HandleNextRequestL()); |
|
159 if (err) |
|
160 { |
|
161 CompleteAllRequests(err); |
|
162 } |
|
163 }</codeblock></section> |
|
164 <section><title>Implementing HandleRequestCancelled() </title><p>A privacy |
|
165 request can be cancelled by the network. The LBS subsystem calls <xref href="GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C.dita#GUID-56C8D5AB-7D9A-3B20-B699-07F17A87A61C/GUID-3417B07B-DE69-3719-8634-B979CBA77AFE"><apiname>CPosPrivacyNotifier::HandleRequestCancelled()</apiname></xref> on |
|
166 the notifier to cancel the request. The code example below shows an implementation. </p><codeblock xml:space="preserve">void CMyPrivacyNotifier::HandleRequestCancelled(TPosQNRequestId aRequestId) |
|
167 { |
|
168 switch (CancelReason()) |
|
169 { |
|
170 case EPosCancelReasonTimeout: |
|
171 // Notify the user that the query timed out. |
|
172 break; |
|
173 default: // Do nothing |
|
174 break; |
|
175 } |
|
176 |
|
177 // We only need to do anything if the request is the one which is currently |
|
178 // handled. |
|
179 if (iActiveRequest == aRequestId) |
|
180 { |
|
181 // Close the active dialog |
|
182 DismissDialog(); |
|
183 HandleNextRequest(); |
|
184 } |
|
185 }</codeblock></section> |
|
186 <section><title>Implementing HandleAllRequestsCancelled()</title><p>The notifier |
|
187 must implement this method to allow all outstanding requests to be cancelled. </p><codeblock xml:space="preserve">void CMyPrivacyNotifier::HandleAllRequestCancelled() |
|
188 { |
|
189 // Close the active dialog |
|
190 DismissDialog(); |
|
191 }</codeblock></section> |
|
192 </conbody></concept> |