messaging-sms-tone-per-contact for 1.3.5
[webos-internals:shivaramv-modifications.git] / messaging / messaging-sms-tone-per-contact.patch
1 Updated for 1.2
2 Index: /usr/palm/applications/com.palm.app.soundsandalerts/app/views/soundsalertsconfig/soundsalertsconfig-scene.html
3 ===================================================================
4 --- .orig/usr/palm/applications/com.palm.app.soundsandalerts/app/views/soundsalertsconfig/soundsalertsconfig-scene.html
5 +++ /usr/palm/applications/com.palm.app.soundsandalerts/app/views/soundsalertsconfig/soundsalertsconfig-scene.html
6 @@ -52,9 +52,27 @@
7                         </div>
8                     </div>
9              </div>
10 +           <div id='currentalertrow' class="palm-row" x-mojo-tap-highlight="momentary">
11 +               <div class="palm-row-wrapper">
12 +                               <div class="label" x-mojo-loc=''>Alert</div>
13 +                       <div id='currentalert' class="title"></div> 
14 +               </div>
15 +           </div>
16 +           <div id='currentnotificationrow' class="palm-row" x-mojo-tap-highlight="momentary">
17 +                       <div class="palm-row-wrapper">
18 +                               <div class="label" x-mojo-loc=''>Notification</div>
19 +                       <div id='currentnotification' class="title"></div>  
20 +               </div>
21 +           </div>
22 +           <div id='currentmessagerow' class="palm-row" x-mojo-tap-highlight="momentary">
23 +                       <div class="palm-row-wrapper">
24 +                               <div class="label" x-mojo-loc=''>Messages</div>
25 +                       <div id='currentmessage' class="title"></div>     
26 +               </div>
27 +           </div>            
28                         <div class="palm-row last">
29                                 <div class="palm-row-wrapper">
30 -                                       <div class="title" x-mojo-loc=''>Volume</div>
31 +                                       <div class="title" x-mojo-loc=''>System Volume</div>
32                                         <div x-mojo-element="Slider" id='systemvolume' class="palm-slider"></div>
33                     </div>
34              </div>
35 Index: /usr/palm/applications/com.palm.app.soundsandalerts/app/models/SystemService.js
36 ===================================================================
37 --- .orig/usr/palm/applications/com.palm.app.soundsandalerts/app/models/SystemService.js
38 +++ /usr/palm/applications/com.palm.app.soundsandalerts/app/models/SystemService.js
39 @@ -28,6 +28,60 @@ SystemService.getRingtone = function(cal
40         return request;
41  }
42  
43 +SystemService.getAlerts = function(callback) {
44 +       var request = new Mojo.Service.Request(SystemService.identifier, {
45 +               method: 'getPreferences',
46 +               parameters: {"keys":["alerttone"]}, 
47 +               onSuccess: callback,
48 +               onFailure: callback
49 +       });
50 +       return request;
51 +}
52 +
53 +SystemService.setAlerts = function(value){
54 +       var request = new Mojo.Service.Request(SystemService.identifier, {
55 +               method: 'setPreferences',
56 +               parameters: {"alerttone":value}, 
57 +       });
58 +       return request;
59 +}
60 +
61 +SystemService.getNotifications = function(callback) {
62 +       var request = new Mojo.Service.Request(SystemService.identifier, {
63 +               method: 'getPreferences',
64 +               parameters: {"keys":["notificationtone"]}, 
65 +               onSuccess: callback,
66 +               onFailure: callback
67 +       });
68 +       return request;
69 +}
70 +
71 +SystemService.setNotifications = function(value){
72 +       var request = new Mojo.Service.Request(SystemService.identifier, {
73 +               method: 'setPreferences',
74 +               parameters: {"notificationtone":value}, 
75 +       });
76 +       return request;
77 +}
78 +
79 +SystemService.getMessages = function(callback) {
80 +       var request = new Mojo.Service.Request(SystemService.identifier, {
81 +               method: 'getPreferences',
82 +               parameters: {"keys":["messagetone"]}, 
83 +               onSuccess: callback,
84 +               onFailure: callback
85 +       });
86 +       return request;
87 +}
88 +
89 +SystemService.setMessages = function(value){
90 +       var request = new Mojo.Service.Request(SystemService.identifier, {
91 +               method: 'setPreferences',
92 +               parameters: {"messagetone":value}, 
93 +       });
94 +       return request;
95 +}
96 +
97  SystemService.getSystemUISounds = function(callback) {
98         var request = new Mojo.Service.Request(SystemService.identifier, {
99                         method: 'getPreferences',
100 Index: /usr/palm/applications/com.palm.app.soundsandalerts/app/controllers/soundsalertsconfig-assistant.js
101 ===================================================================
102 --- .orig/usr/palm/applications/com.palm.app.soundsandalerts/app/controllers/soundsalertsconfig-assistant.js
103 +++ /usr/palm/applications/com.palm.app.soundsandalerts/app/controllers/soundsalertsconfig-assistant.js
104 @@ -96,9 +96,15 @@ var SoundsalertsconfigAssistant = Class.
105                 $('system_ui_sounds').observe('mojo-property-change', this.toggleSystemUISounds.bindAsEventListener(this));
106                 
107                 $('currentringtonerow').observe(Mojo.Event.tap, this.showAudioFilePicker.bindAsEventListener(this));
108 +               $('currentalertrow').observe(Mojo.Event.tap, this.showAlertFilePicker.bindAsEventListener(this));
109 +               $('currentnotificationrow').observe(Mojo.Event.tap, this.showNotificationFilePicker.bindAsEventListener(this));
110 +               $('currentmessagerow').observe(Mojo.Event.tap, this.showMessageFilePicker.bindAsEventListener(this));
111                                 
112                 this.getCurrentVolumes();
113                 this.getCurrentRingtone();
114 +               this.getCurrentAlert();
115 +               this.getCurrentNotification();
116 +               this.getCurrentMessage();
117                 this.getVibrateSettings();      
118                 this.getOtherSettings();
119                 
120 @@ -270,6 +276,84 @@ var SoundsalertsconfigAssistant = Class.
121                 $('currentringtone').innerHTML = file.name;
122         },
123         
124 +       // Alert Picking
125 +       getCurrentAlert: function() {
126 +       this.getCurrentAlertReq = SystemService.getAlerts(this.getCurrentAlertQuery.bind(this));
127 +       },
128 +       
129 +       getCurrentAlertQuery: function(payload) {
130 +       if (payload.alerttone) {
131 +       $('currentalert').innerHTML = payload.alerttone.name;
132 +       this.currAlertPath = payload.alerttone.fullPath;
133 +       }
134 +       else 
135 +       $('currentalert').innerHTML = $L("Pick an alert");
136 +       
137 +       },
138 +       
139 +       showAlertFilePicker: function(event) {
140 +       var params = {"kinds": ["ringtone"],"filePath":this.currAlertPath,"onSelect":this.selectedAlertFile.bind(this),actionType:"attach",actionName: $L("Done")};
141 +       Mojo.FilePicker.pickFile(params,Mojo.Controller.stageController);
142 +       },
143 +       
144 +       selectedAlertFile: function(file) {
145 +       //var params = {"fullPath": encodeURIComponent(file.fullPath), "name":file.name};
146 +       this.setAlertReq = SystemService.setAlerts(file);
147 +       $('currentalert').innerHTML = file.name;
148 +       },
149 +       
150 +       // Notification Picking
151 +       getCurrentNotification: function() {
152 +       this.getCurrentNotificationReq = SystemService.getNotifications(this.getCurrentNotificationQuery.bind(this));
153 +       },
154 +       
155 +       getCurrentNotificationQuery: function(payload) {
156 +       if (payload.notificationtone) {
157 +       $('currentnotification').innerHTML = payload.notificationtone.name;
158 +       this.currNotificationPath = payload.notificationtone.fullPath;
159 +       }
160 +       else 
161 +       $('currentnotification').innerHTML = $L("Pick a notification");
162 +       
163 +       },
164 +       
165 +       showNotificationFilePicker: function(event) {
166 +       var params = {"kinds": ["ringtone"],"filePath":this.currNotificationPath,"onSelect":this.selectedNotificationFile.bind(this),actionType:"attach",actionName: $L("Done")};
167 +       Mojo.FilePicker.pickFile(params,Mojo.Controller.stageController);
168 +       },
169 +       
170 +       selectedNotificationFile: function(file) {
171 +       //var params = {"fullPath": encodeURIComponent(file.fullPath), "name":file.name};
172 +       this.setNotificationReq = SystemService.setNotifications(file);
173 +       $('currentnotification').innerHTML = file.name;
174 +       },
175 +       
176 +       // Message Picking
177 +       getCurrentMessage: function() {
178 +               this.getCurrentMessageReq = SystemService.getMessages(this.getCurrentMessageQuery.bind(this));
179 +       },
180 +       
181 +       getCurrentMessageQuery: function(payload) {
182 +               if (payload.messagetone) {
183 +                       $('currentmessage').innerHTML = payload.messagetone.name;
184 +                       this.currMessagePath = payload.messagetone.fullPath;
185 +               }
186 +               else 
187 +               $('currentmessage').innerHTML = $L("Pick an message");
188 +       
189 +       },
190 +       
191 +       showMessageFilePicker: function(event) {
192 +               var params = {"kinds": ["ringtone"],"filePath":this.currMessagePath,"onSelect":this.selectedMessageFile.bind(this),actionType:"attach",actionName: $L("Done")};
193 +               Mojo.FilePicker.pickFile(params,Mojo.Controller.stageController);
194 +       },
195 +       
196 +       selectedMessageFile: function(file) {
197 +               //var params = {"fullPath": encodeURIComponent(file.fullPath), "name":file.name};
198 +               this.setMessageReq = SystemService.setMessages(file);
199 +               $('currentmessage').innerHTML = file.name;
200 +       },
201 +       
202         getVibrateSettings: function() {
203                 this.getVibrateSettingsReq = AudioService.getVibrateSettings(this.vibrateSettingsCB.bind(this),this);
204         },
205 Index: /usr/palm/applications/com.palm.app.contacts/app/controllers/edit-assistant.js
206 ===================================================================
207 --- .orig/usr/palm/applications/com.palm.app.contacts/app/controllers/edit-assistant.js
208 +++ /usr/palm/applications/com.palm.app.contacts/app/controllers/edit-assistant.js
209 @@ -64,6 +64,17 @@ EditAssistant = Class.create({
210                         template: "edit/ringtones"
211                 }));
212                 
213 +               if(this.person.messagingRingtoneName){
214 +                       this.person.MsgtoneDisplay = this.person.messagingRingtoneName;
215 +                       this.person.MsgtoneSet = "msgtone-set";
216 +               } else {
217 +                       this.person.MsgtoneDisplay = $L("Set a message tone");
218 +                       this.person.MsgtoneSet = "";
219 +               }
220 +               this.controller.get("MsgtoneBox").update(Mojo.View.render({
221 +                       object: this.person,
222 +                       template: "edit/msgtones"
223 +               }));            
224                 
225                 var that = this;
226                 
227 @@ -278,6 +289,11 @@ EditAssistant = Class.create({
228                                         object: {ringtoneDisplay:ringtoneName},
229                                         template: "edit/ringtones"
230                                 }));
231 +                               var messagingRingtoneName = this.person.messagingRingtoneName || $L("Set a message tone");
232 +                               this.controller.get("MsgtoneBox").update(Mojo.View.render({
233 +                                       object: {MsgtoneDisplay:messagingRingtoneName},
234 +                                       template: "edit/msgtones"
235 +                               }));
236                                 
237                         }
238                 }
239 @@ -543,6 +559,7 @@ EditAssistant = Class.create({
240                 this.controller.listen("NameSyncPickerWrapper", Mojo.Event.tap, this.popupContactChooser.bind(this));
241                 this.controller.get("edit-photo").observe(Mojo.Event.tap, this.attachFilePicker.bind(this));
242                 this.controller.get("RingtoneBox").observe(Mojo.Event.tap, this.attachRingtonePicker.bind(this));
243 +               this.controller.get("MsgtoneBox").observe(Mojo.Event.tap, this.attachMsgtonePicker.bind(this));
244                 this.renderLabels();
245                 this.setupContact();
246                 if (this.contact.readOnly) {
247 Index: /usr/palm/applications/com.palm.app.contacts/app/controllers/filepicker-behaviors.js
248 ===================================================================
249 --- .orig/usr/palm/applications/com.palm.app.contacts/app/controllers/filepicker-behaviors.js
250 +++ /usr/palm/applications/com.palm.app.contacts/app/controllers/filepicker-behaviors.js
251 @@ -56,6 +56,55 @@ var FilepickerBehaviors = {
252                         Mojo.FilePicker.pickFile(params, this.controller.stageController);
253  
254         },
255 +
256 +       attachMsgtonePicker: function(event){
257 +               if(this.person.messagingRingtoneLoc){
258 +                       this.controller.popupSubmenu( {
259 +                               onChoose:function(c){
260 +                                       if(c == "CHANGE"){
261 +                                               this.pushMsgtonePicker();
262 +                                       } else if(c == "DELETE"){
263 +                                               this.clearMsgtone();
264 +                                       }
265 +                               }.bind(this),
266 +                               placeNear:event.target,
267 +                               items:[
268 +                                       {label:$L("Change Msgtone"), command:'CHANGE'},
269 +                                       {label:$L("Delete Msgtone"), command:'DELETE'}
270 +                               ]
271 +                       })                      
272 +               } else {
273 +                       this.pushMsgtonePicker();
274 +               }
275 +               
276 +       },
277 +       
278 +       clearMsgtone:function(){
279 +               this.person.messagingRingtoneLoc = "";
280 +               this.person.messagingRingtoneName = "";
281 +               this.person.MsgtoneDisplay = $L("Set a message tone");
282 +               this.person.MsgtoneSet = "";
283 +               this.person.dirty = true;
284 +               this.controller.get("MsgtoneBox").update(Mojo.View.render({
285 +                       object:this.person,
286 +                       template:"edit/msgtones"
287 +               }));
288 +       },
289 +       
290 +       pushMsgtonePicker:function(){
291 +                       var params = {
292 +                               actionType: 'attach',
293 +                               kinds: ['ringtone'],
294 +                               defaultKind: 'ringtone',
295 +                               filePath:this.person.messagingRingtoneLoc,
296 +                               onSelect: function(file){
297 +                                       this.attachMsgtone(this.sanitizeSystemPath(file.fullPath), file.name);
298 +                               }.bind(this)
299 +                       };
300 +                       //Mojo.Log.info("ContactMulti Picking a msgtone for " + this.contact.firstName + " " + this.contact.lastName);
301 +                       Mojo.FilePicker.pickFile(params, this.controller.stageController);
302 +
303 +       },
304         
305         attachFilePicker: function(event){
306                 if(this.contact.readOnly){
307 @@ -153,6 +202,20 @@ var FilepickerBehaviors = {
308                         template:"edit/ringtones"
309                       }));
310                 }
311 +       },
312 +       
313 +       attachMsgtone: function(msgtonePath, name){
314 +               if (msgtonePath) {
315 +                       this.person.dirty = true;
316 +                       this.person.messagingRingtoneName = name;
317 +                       this.person.MsgtoneDisplay = name;
318 +                       this.person.MsgtoneSet = "msgtone-set";
319 +                       this.person.messagingRingtoneLoc = msgtonePath;
320 +                       this.controller.get("MsgtoneBox").update(Mojo.View.render({
321 +                       object:this.person,
322 +                       template:"edit/msgtones"
323 +                     }));
324 +               }
325         }
326  }
327  
328 Index: /usr/palm/applications/com.palm.app.contacts/app/views/edit/lists-fake.html
329 ===================================================================
330 --- .orig/usr/palm/applications/com.palm.app.contacts/app/views/edit/lists-fake.html
331 +++ /usr/palm/applications/com.palm.app.contacts/app/views/edit/lists-fake.html
332 @@ -32,6 +32,20 @@
333          </div>
334      </div>
335  </div>
336 +<div>
337 +<div id="MsgtoneBox" class="">
338 +    <div class="palm-group unlabeled">
339 +        <div class="palm-list">
340 +            <div class="palm-row single" id="MsgtoneButton" x-mojo-tap-highlight="momentary">
341 +                <div class="palm-row-wrapper">
342 +                    <div class="title"  x-mojo-loc="">
343 +                        Set a message tone
344 +                    </div>
345 +                </div>
346 +            </div>
347 +        </div>
348 +    </div>
349 +</div>
350  </div>
351  <div>
352  <div id="emailList" name="emailList" class="contactPointList" >
353 Index: /usr/palm/applications/com.palm.app.contacts/app/views/edit/msgtones.html
354 ===================================================================
355 --- /dev/null
356 +++ /usr/palm/applications/com.palm.app.contacts/app/views/edit/msgtones.html
357 @@ -0,0 +1,16 @@
358 +<div class="palm-group unlabeled">
359 +  <div class="palm-list">
360 +    <div class="palm-row single #{MsgtoneSet} msgtone-button" id="MsgtoneButton" x-mojo-tap-highlight="momentary">
361 +      <div class="palm-row-wrapper">
362 +        <div class="label right truncating-text" x-mojo-loc=''>
363 +          Msgtone
364 +        </div>
365 +        <div class="title">
366 +          <div class="truncating-text">
367 +            #{MsgtoneDisplay}
368 +          </div>
369 +        </div>
370 +      </div>
371 +    </div>
372 +  </div>
373 +</div>
374 Index: /usr/palm/applications/com.palm.app.messaging/app/controllers/listview-assistant.js
375 ===================================================================
376 --- .orig/usr/palm/applications/com.palm.app.messaging/app/controllers/listview-assistant.js
377 +++ /usr/palm/applications/com.palm.app.messaging/app/controllers/listview-assistant.js
378 @@ -436,7 +436,7 @@ var ListviewAssistant = Class.create(App
379                 // if we are in the history view and the screen is on, do not display a banner + dashboard, just play a notification sound
380                 if (this.isScreenOn) { 
381                         if (data.notificationType == this.Messaging.notificationTypes.newMessage && this.currentListView == this.Messaging.Views.HISTORY) {
382 -                               data = {playSoundOnly:true};
383 +                               Object.extend(data, {playSoundOnly:true});
384                         }
385                 }
386                 return data;
387 Index: /usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
388 ===================================================================
389 --- .orig/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
390 +++ /usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
391 @@ -354,7 +354,7 @@ var ChatviewAssistant = Class.create({
392                 if (this.isScreenOn && data.chatThreadId == this.chatThreadId) {
393                         Mojo.Log.info("[CV] ****** chatview considerForNotification --- screen is on!");
394                         if (data.notificationType == this.Messaging.notificationTypes.newMessage) {
395 -                               data = {playSoundOnly:true};
396 +                               Object.extend(data, {playSoundOnly:true});
397                         } else if (data.notificationType == this.Messaging.notificationTypes.sendFailure) {
398                                 data = {}; // wipe out the notification because we are in the chat
399                         }
400 Index: /usr/palm/applications/com.palm.app.messaging/app/models/messaging-luna-service.js
401 ===================================================================
402 --- .orig/usr/palm/applications/com.palm.app.messaging/app/models/messaging-luna-service.js
403 +++ /usr/palm/applications/com.palm.app.messaging/app/models/messaging-luna-service.js
404 @@ -1002,5 +1002,168 @@ var MessagingMojoService = {
405                   method: 'setSMSCAddressAndEmailGateway',
406                   parameters: {smscAddr:address, emailGateway: gateway}
407           });
408 +       },
409 +       
410 +               isNumberValid: function(number) {
411 +               return !(number === undefined
412 +                       || number == null
413 +                       || number == "" 
414 +                       || number == "unknown" 
415 +                       || number == "unknown caller"
416 +                       || number == "blocked caller") 
417 +       },
418 +       
419 +       // use contacts service and carrier book to perform reverse lookup on number.  stores results in passed contact object.
420 +       // runs callback when done.
421 +       // if the number isn't valid, marks contact lookup complete 
422 +       // if there's already one happening, or one already completed, just fires callback
423 +       // if there's a lateCallback provided, calls that if the result comes much later
424 +       rLookup: function(number, contact, callback, lateCallback){
425 +               
426 +               //Reset contact to always get the tone
427 +               contact = {};   
428 +               Mojo.Log.error("Current contact value: %j",contact);
429 +               Mojo.Log.error("SMS ID: %j",number);
430 +               
431 +               // bail if the number is invalid
432 +               if (!(this.isNumberValid(number))) {
433 +                               this.finishLookup(contact, callback);
434 +                               return;
435 +               }
436 +               
437 +               if (contact.lookupComplete) {
438 +                       callback(contact);      
439 +                       return;
440 +               }
441 +               
442 +               if (contact.lookupPending) {
443 +                       callback(contact);      
444 +                       return;
445 +               }
446 +               
447 +               
448 +               // use contacts service to perform lookup.
449 +               // if contact already has an id in it, use person lookup
450 +               // instead of doing reverse lookup on number
451 +               contact.lookupPending = true;
452 +               var method, params;
453 +               if (contact.initialId) {
454 +                       method = 'basicDetails'
455 +                       params =  {'id' : contact.initialId}
456 +                       delete contact.initialId;
457 +               } else {
458 +                       method = 'reverseLookup'
459 +                       params = {
460 +                'value': number,
461 +                'type': "phone"
462 +            }
463 +               }
464 +               this.lastRequest = new Mojo.Service.Request('palm://com.palm.contacts', {
465 +                       'method': method,
466 +            parameters: params,
467 +            onSuccess: this.onLookup.bind(this, number, contact, callback, lateCallback),
468 +                       onFailure: function() {
469 +                               // cancel previous lookup, so this doesn't fire on a service crash
470 +                               if (this.lastRequest) {
471 +                                       this.lastRequest.cancel();
472 +                                       this.lastRequest = undefined;
473 +                               }
474 +                               
475 +                               this.carrierBookLookup(number,contact);
476 +                               this.finishLookup(contact, callback);
477 +                       }.bind(this)
478 +        });
479 +               
480 +               // timeout if lookup hasn't completed in 4 seconds
481 +               this.lookupTimeout = setTimeout(this.onLookupTimeout.bind(this, contact, callback, lateCallback), 4000);
482 +    },
483 +       
484 +       // when contact lookup returns, check for valid result
485 +       // if valid result, grab name, ringtone; if there's a picture, start loading and set callback to measure it
486 +       // if no valid result, look in carrier book
487 +       // fire callback when done
488 +    onLookup: function(number, contact, callback, lateCallback, result){
489 +        Mojo.Log.info( "PhoneApp: Contact::onLookup CALLER ID LOOKUP %s RETURNED %j" , number , result);
490 +               var statusChange = "";
491 +               
492 +               // cancel previous lookup, so this doesn't fire on a service crash
493 +               if (this.lastRequest) {
494 +                       this.lastRequest.cancel();
495 +                       this.lastRequest = undefined;
496 +               }
497 +               
498 +               if (result.record) {
499 +                       /*              
500 +                       // don't match if the number we get back is different than the number
501 +                       // we passed in (provided the lengths are the same)
502 +                       if (!(result.record.number)
503 +                               || ( (result.record.number) && ( (result.record.number.length !== number.length) 
504 +                                       || (result.record.number.length === number.length 
505 +                                                && result.record.number === number)))) {
506 +                       */
507 +                       contact.id = result.record.id;
508 +                       
509 +       
510 +                       contact.ringtoneLoc = result.record.messagingRingtoneLoc;
511 +                       Mojo.Log.error("MSGTone: %j",contact.ringtoneLoc);                      
512 +
513 +               }
514 +               
515 +               this.finishLookup(contact, callback, lateCallback);
516 +    },
517 +       
518 +       
519 +
520 +       // mark complete; cancel timeout; fire callback if it hasn't fired yet
521 +       finishLookup: function(contact, callback, lateCallback) {
522 +               contact.lookupPending = false;
523 +               
524 +               // cancel lookup timeout
525 +               clearTimeout(this.lookupTimeout); 
526 +               this.lookupTimeout = undefined;
527 +               
528 +               if (!(contact.lookupComplete)) {
529 +                       contact.lookupComplete = true;
530 +                       callback(contact);
531 +               // if we have a late return, and we got a contact result, call
532 +               // the late return update 
533 +               } else if (lateCallback && contact.doLateCallback && contact.id) {
534 +                       contact.doLateCallback = false;
535 +                       lateCallback.delay(5, contact);
536 +               } else {
537 +               }
538 +               
539 +       },
540 +       
541 +       // flag lookup as done; proceed with callback
542 +       onLookupTimeout: function(contact, callback, lateCallback) {
543 +               
544 +               if (lateCallback) {
545 +                       contact.doLateCallback = true;
546 +               } else if (this.lastRequest && !lateCallback) {
547 +                       // cancel previous lookup, so this doesn't fire on a service crash
548 +                       this.lastRequest.cancel();
549 +                       this.lastRequest = undefined;
550 +               }
551 +               
552 +               // clear timeout
553 +               this.lookupTimeout = undefined;
554 +               
555 +               // flag done; fire callback if it hasn't yet
556 +               contact.lookupComplete = true;
557 +               var lookupWasPending = contact.lookupPending;
558 +               contact.lookupPending = false;
559 +               if (lookupWasPending) 
560 +                       callback(contact);
561 +       },
562 +       
563 +       getMessagetone:  function(callback) {
564 +               var request = new Mojo.Service.Request('palm://com.palm.systemservice', {
565 +                       method: 'getPreferences',
566 +                       parameters: {"keys":["messagetone"]},
567 +                       onSuccess: callback,
568 +                       onFailure: callback
569 +               });
570 +               return request;
571         }
572  };
573 \ No newline at end of file
574 Index: /usr/palm/applications/com.palm.app.messaging/app/controllers/notification-assistant.js
575 ===================================================================
576 --- .orig/usr/palm/applications/com.palm.app.messaging/app/controllers/notification-assistant.js
577 +++ /usr/palm/applications/com.palm.app.messaging/app/controllers/notification-assistant.js
578 @@ -27,6 +27,8 @@
579         };
580  }
581  
582 +var contact = {};
583 +
584  NotificationAssistant.prototype.subscribeToNotifications = function(){
585         this.messageNotificationRequest = MessagingMojoService.registerForIncomingMessages({onSuccess: this.sendNotification.bind(this, this.Messaging.notificationTypes.newMessage)});
586         this.sendErrorNotificationRequest = MessagingMojoService.registerForSendFailures(this.sendNotification.bind(this, this.Messaging.notificationTypes.sendFailure));
587 @@ -35,6 +35,37 @@
588         this.airplaneModeNotificationRequest = MessagingMojoService.registerForAirplaneModeNotifications(this.sendAirplaneModeNotification.bind(this));
589  };
590  
591 +NotificationAssistant.prototype.doBanner = function(bannerParams,bannerLaunchParams,bannerType,payload) {
592 +       if (payload.messagetone.fullPath)
593 +               bannerParams.soundFile = payload.messagetone.fullPath;
594 +       this.controller.showBanner(bannerParams,bannerLaunchParams,bannerType);
595 +};
596 +
597 +NotificationAssistant.prototype.playMessagetone = function(payload){
598 +       if (payload.messagetone.fullPath)
599 +               this.controller.playSoundNotification('alerts',payload.messagetone.fullPath);
600 +       else
601 +               this.controller.playSoundNotification('alerts','');
602 +};
603 +
604 +NotificationAssistant.prototype.doB = function(bannerParams,bannerLaunchParams,bannerType,contact) {
605 +        Mojo.Log.error("Banner Ringtone: %j",contact.ringtoneLoc);                                                                                                                          
606 +       if (contact.ringtoneLoc) {
607 +               bannerParams.soundFile = contact.ringtoneLoc;
608 +               this.controller.showBanner(bannerParams,bannerLaunchParams,bannerType);
609 +       } else {
610 +               MessagingMojoService.getMessagetone(this.doBanner.bind(this,bannerParams,bannerLaunchParams,'chat'));
611 +       }
612 +};
613 +
614 +NotificationAssistant.prototype.playmsgtone = function(contact){
615 +       Mojo.Log.error("Playmsgtone Ringtone: %j",contact.ringtoneLoc);
616 +       if (contact.ringtoneLoc)
617 +               this.controller.playSoundNotification('alerts',contact.ringtoneLoc);
618 +       else
619 +               MessagingMojoService.getMessagetone(this.playMessagetone.bind(this));
620 +};
621 +
622  NotificationAssistant.prototype.sendNotification = function(notificationType, resp){
623         if (window.PalmSystem && !resp.returnValue) {
624                 try {
625 @@ -149,9 +149,8 @@
626         
627         // check if we should only play a sound (when you are already in a chat & a new message comes in)
628         if(notificationData.playSoundOnly && this.Messaging.messagingPrefs.enableNotificationSound) {
629 -               var notifParams = {};
630 -               this.setNotificationSound(notifParams);
631 -               this.controller.playSoundNotification(notifParams.soundClass, notifParams.soundFile);
632 +               var smsid = notificationData.address;
633 +               MessagingMojoService.rLookup(smsid,contact,this.playmsgtone.bind(this),this.playmsgtone.bind(this));
634                 return; // don't display any visual notification
635         }       
636         
637 @@ -186,7 +186,8 @@
638  
639         notificationData.carrierName = carrierName;
640         this.class0AlertData.list.push(notificationData);
641 -       this.renderClass0PopupAlert(true);
642 +       var smsid = notificationData.address;
643 +       MessagingMojoService.getMessagetone(this.renderClass0PopupAlert.bind(this,true));
644  };
645  
646  NotificationAssistant.prototype.renderClass0PopupAlert = function(playSound) {
647 @@ -189,7 +189,7 @@
648         this.renderClass0PopupAlert(true);
649  };
650  
651 -NotificationAssistant.prototype.renderClass0PopupAlert = function(playSound) {
652 +NotificationAssistant.prototype.renderClass0PopupAlert = function(playSound,messageTone) {
653         var class0Stage = this.controller.getStageController(Class0AlertStageName);
654  
655         if(class0Stage) {
656 @@ -195,7 +195,7 @@
657         if(class0Stage) {
658                 class0Stage.swapScene('class0Alert', this.class0AlertData);
659                 if (playSound){
660 -                       this.controller.playSoundNotification('alerts','');
661 +                       this.controller.playSoundNotification('alerts',contact.ringtoneLoc);
662                 }
663         } else {
664                 var soundClass = 'none';
665 @@ -201,6 +201,9 @@
666                 var soundClass = 'none';
667                 if(playSound) {
668                         soundClass = 'alerts';
669 +                       if(messageTone) {
670 +                               soundFile = messageTone;
671 +                       }
672                 }               
673                 
674                 var pushClass0AlertScene = function(stageController) {
675 @@ -211,7 +211,8 @@
676                         name: Class0AlertStageName,
677                         lightweight: true,
678                         height: Math.floor(Mojo.Environment.DeviceInfo.screenHeight * 0.50),
679 -                       soundclass: soundClass
680 +                       soundclass: soundClass,
681 +                       soundfile: soundFile
682                 }, pushClass0AlertScene, 'popupalert');         
683         }
684  
685 @@ -279,7 +279,7 @@
686         var bannerParams = {
687                 messageText: notificationText
688         };
689 -       this.setNotificationSound(bannerParams);
690 +       //this.setNotificationSound(bannerParams);
691         var bannerLaunchParams =  {
692                 chatThreadId: chatThreadId,
693                 clearBanner: true               
694 @@ -284,9 +284,14 @@
695                 chatThreadId: chatThreadId,
696                 clearBanner: true               
697         };
698 -       
699 -       this.controller.showBanner(bannerParams, bannerLaunchParams, 'chat');
700 -       
701 +       if (this.Messaging.messagingPrefs.enableNotificationSound) {
702 +                       var smsid = notificationData.address;                                                  
703 +               bannerParams.soundClass = "alerts";
704 +               MessagingMojoService.rLookup(smsid,contact,this.doB.bind(this,bannerParams,bannerLaunchParams,'chat'),this.doB.bind(this,bannerParams,bannerLaunchParams,'chat'));
705 +       } else {
706 +               Mojo.Log.error("Setting banner params");        
707 +               this.controller.showBanner(bannerParams, bannerLaunchParams, 'chat');
708 +       }       
709         // Store the data so it can be used in the dashboard
710         var data = {
711                 chatThreadId: chatThreadId,
712 @@ -343,13 +343,9 @@
713                 // delay creating the dashboard window for the case where the banner is clicked on
714                 // to take you to the chat view.  This will likely result in the dashboard data
715                 // being cleared.  If the dashboard data is empty, we do not need to create the dashboard.              
716 -               if (this.Messaging.DisplayState.isDisplayOn()) {
717 -                       if (!this.isNewMessageDashboardPending) {
718 -                               this.isNewMessageDashboardPending = true; 
719 -                               createDashboard.delay(5);
720 -                       }
721 -               } else {
722 -                       createDashboard(); // if the screen is off, create the dashboard right away
723 +               if (!this.isNewMessageDashboardPending) {
724 +                       this.isNewMessageDashboardPending = true;
725 +                       createDashboard.delay(5); 
726                 }
727         }
728  };