Reorganized everything into new structure
[webos-internals:adamrmcd-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 @@ -94,9 +94,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 @@ -260,6 +266,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 @@ -63,6 +63,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 @@ -264,6 +275,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 @@ -521,6 +537,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 @@ -150,6 +199,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 @@ -434,7 +434,8 @@ 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 +                               data = $H(data);
384 +                               data = data.merge({playSoundOnly:true});
385                         }
386                 }
387                 return data;
388 Index: /usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
389 ===================================================================
390 --- .orig/usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
391 +++ /usr/palm/applications/com.palm.app.messaging/app/controllers/chatview-assistant.js
392 @@ -346,7 +346,8 @@ var ChatviewAssistant = Class.create({
393                 if(this.isScreenOn && data.chatThreadId == this.chatThreadId) {
394                         Mojo.Log.info("[CV] ****** chatview considerForNotification --- screen is on!");
395                         if(data.notificationType == this.Messaging.notificationTypes.newMessage) {
396 -                               data = {playSoundOnly:true};
397 +                               data = $H(data);
398 +                               data = data.merge({playSoundOnly:true});
399                         } else if( data.notificationType == this.Messaging.notificationTypes.sendFailure) {
400                                 data = {}; // wipe out the notification because we are in the chat
401                         }
402 Index: /usr/palm/applications/com.palm.app.messaging/app/models/messaging-luna-service.js
403 ===================================================================
404 --- .orig/usr/palm/applications/com.palm.app.messaging/app/models/messaging-luna-service.js
405 +++ /usr/palm/applications/com.palm.app.messaging/app/models/messaging-luna-service.js
406 @@ -993,5 +993,168 @@ var MessagingMojoService = {
407                   method: 'setSMSCAddressAndEmailGateway',
408                   parameters: {smscAddr:address, emailGateway: gateway}
409           });
410 +       },
411 +       
412 +               isNumberValid: function(number) {
413 +               return !(number === undefined
414 +                       || number == null
415 +                       || number == "" 
416 +                       || number == "unknown" 
417 +                       || number == "unknown caller"
418 +                       || number == "blocked caller") 
419 +       },
420 +       
421 +       // use contacts service and carrier book to perform reverse lookup on number.  stores results in passed contact object.
422 +       // runs callback when done.
423 +       // if the number isn't valid, marks contact lookup complete 
424 +       // if there's already one happening, or one already completed, just fires callback
425 +       // if there's a lateCallback provided, calls that if the result comes much later
426 +       rLookup: function(number, contact, callback, lateCallback){
427 +               
428 +               //Reset contact to always get the tone
429 +               contact = {};   
430 +               Mojo.Log.error("Current contact value: %j",contact);
431 +               Mojo.Log.error("SMS ID: %j",number);
432 +               
433 +               // bail if the number is invalid
434 +               if (!(this.isNumberValid(number))) {
435 +                               this.finishLookup(contact, callback);
436 +                               return;
437 +               }
438 +               
439 +               if (contact.lookupComplete) {
440 +                       callback(contact);      
441 +                       return;
442 +               }
443 +               
444 +               if (contact.lookupPending) {
445 +                       callback(contact);      
446 +                       return;
447 +               }
448 +               
449 +               
450 +               // use contacts service to perform lookup.
451 +               // if contact already has an id in it, use person lookup
452 +               // instead of doing reverse lookup on number
453 +               contact.lookupPending = true;
454 +               var method, params;
455 +               if (contact.initialId) {
456 +                       method = 'basicDetails'
457 +                       params =  {'id' : contact.initialId}
458 +                       delete contact.initialId;
459 +               } else {
460 +                       method = 'reverseLookup'
461 +                       params = {
462 +                'value': number,
463 +                'type': "phone"
464 +            }
465 +               }
466 +               this.lastRequest = new Mojo.Service.Request('palm://com.palm.contacts', {
467 +                       'method': method,
468 +            parameters: params,
469 +            onSuccess: this.onLookup.bind(this, number, contact, callback, lateCallback),
470 +                       onFailure: function() {
471 +                               // cancel previous lookup, so this doesn't fire on a service crash
472 +                               if (this.lastRequest) {
473 +                                       this.lastRequest.cancel();
474 +                                       this.lastRequest = undefined;
475 +                               }
476 +                               
477 +                               this.carrierBookLookup(number,contact);
478 +                               this.finishLookup(contact, callback);
479 +                       }.bind(this)
480 +        });
481 +               
482 +               // timeout if lookup hasn't completed in 4 seconds
483 +               this.lookupTimeout = setTimeout(this.onLookupTimeout.bind(this, contact, callback, lateCallback), 4000);
484 +    },
485 +       
486 +       // when contact lookup returns, check for valid result
487 +       // if valid result, grab name, ringtone; if there's a picture, start loading and set callback to measure it
488 +       // if no valid result, look in carrier book
489 +       // fire callback when done
490 +    onLookup: function(number, contact, callback, lateCallback, result){
491 +        Mojo.Log.info( "PhoneApp: Contact::onLookup CALLER ID LOOKUP %s RETURNED %j" , number , result);
492 +               var statusChange = "";
493 +               
494 +               // cancel previous lookup, so this doesn't fire on a service crash
495 +               if (this.lastRequest) {
496 +                       this.lastRequest.cancel();
497 +                       this.lastRequest = undefined;
498 +               }
499 +               
500 +               if (result.record) {
501 +                       /*              
502 +                       // don't match if the number we get back is different than the number
503 +                       // we passed in (provided the lengths are the same)
504 +                       if (!(result.record.number)
505 +                               || ( (result.record.number) && ( (result.record.number.length !== number.length) 
506 +                                       || (result.record.number.length === number.length 
507 +                                                && result.record.number === number)))) {
508 +                       */
509 +                       contact.id = result.record.id;
510 +                       
511 +       
512 +                       contact.ringtoneLoc = result.record.messagingRingtoneLoc;
513 +                       Mojo.Log.error("MSGTone: %j",contact.ringtoneLoc);                      
514 +
515 +               }
516 +               
517 +               this.finishLookup(contact, callback, lateCallback);
518 +    },
519 +       
520 +       
521 +
522 +       // mark complete; cancel timeout; fire callback if it hasn't fired yet
523 +       finishLookup: function(contact, callback, lateCallback) {
524 +               contact.lookupPending = false;
525 +               
526 +               // cancel lookup timeout
527 +               clearTimeout(this.lookupTimeout); 
528 +               this.lookupTimeout = undefined;
529 +               
530 +               if (!(contact.lookupComplete)) {
531 +                       contact.lookupComplete = true;
532 +                       callback(contact);
533 +               // if we have a late return, and we got a contact result, call
534 +               // the late return update 
535 +               } else if (lateCallback && contact.doLateCallback && contact.id) {
536 +                       contact.doLateCallback = false;
537 +                       lateCallback.delay(5, contact);
538 +               } else {
539 +               }
540 +               
541 +       },
542 +       
543 +       // flag lookup as done; proceed with callback
544 +       onLookupTimeout: function(contact, callback, lateCallback) {
545 +               
546 +               if (lateCallback) {
547 +                       contact.doLateCallback = true;
548 +               } else if (this.lastRequest && !lateCallback) {
549 +                       // cancel previous lookup, so this doesn't fire on a service crash
550 +                       this.lastRequest.cancel();
551 +                       this.lastRequest = undefined;
552 +               }
553 +               
554 +               // clear timeout
555 +               this.lookupTimeout = undefined;
556 +               
557 +               // flag done; fire callback if it hasn't yet
558 +               contact.lookupComplete = true;
559 +               var lookupWasPending = contact.lookupPending;
560 +               contact.lookupPending = false;
561 +               if (lookupWasPending) 
562 +                       callback(contact);
563 +       },
564 +       
565 +       getMessagetone:  function(callback) {
566 +               var request = new Mojo.Service.Request('palm://com.palm.systemservice', {
567 +                       method: 'getPreferences',
568 +                       parameters: {"keys":["messagetone"]},
569 +                       onSuccess: callback,
570 +                       onFailure: callback
571 +               });
572 +               return request;
573         }
574  };
575 \ No newline at end of file
576 Index: /usr/palm/applications/com.palm.app.messaging/app/controllers/notification-assistant.js
577 ===================================================================
578 --- .orig/usr/palm/applications/com.palm.app.messaging/app/controllers/notification-assistant.js
579 +++ /usr/palm/applications/com.palm.app.messaging/app/controllers/notification-assistant.js
580 @@ -27,6 +27,8 @@ function NotificationAssistant(controlle
581         };
582  }
583  
584 +var contact = {};
585 +
586  NotificationAssistant.prototype.subscribeToNotifications = function(){
587         this.messageNotificationRequest = MessagingMojoService.registerForIncomingMessages({onSuccess: this.sendNotification.bind(this, this.Messaging.notificationTypes.newMessage)});
588         this.sendErrorNotificationRequest = MessagingMojoService.registerForSendFailures(this.sendNotification.bind(this, this.Messaging.notificationTypes.sendFailure));
589 @@ -35,6 +37,37 @@ NotificationAssistant.prototype.subscrib
590         this.airplaneModeNotificationRequest = MessagingMojoService.registerForAirplaneModeNotifications(this.sendAirplaneModeNotification.bind(this));
591  };
592  
593 +NotificationAssistant.prototype.doBanner = function(bannerParams,bannerLaunchParams,bannerType,payload) {
594 +       if (payload.messagetone.fullPath)
595 +               bannerParams.soundFile = payload.messagetone.fullPath;
596 +       this.controller.showBanner(bannerParams,bannerLaunchParams,bannerType);
597 +};
598 +
599 +NotificationAssistant.prototype.playMessagetone = function(payload){
600 +       if (payload.messagetone.fullPath)
601 +               this.controller.playSoundNotification('alerts',payload.messagetone.fullPath);
602 +       else
603 +               this.controller.playSoundNotification('alerts','');
604 +};
605 +
606 +NotificationAssistant.prototype.doB = function(bannerParams,bannerLaunchParams,bannerType,contact) {
607 +        Mojo.Log.error("Banner Ringtone: %j",contact.ringtoneLoc);                                                                                                                          
608 +       if (contact.ringtoneLoc) {
609 +               bannerParams.soundFile = contact.ringtoneLoc;
610 +               this.controller.showBanner(bannerParams,bannerLaunchParams,bannerType);
611 +       } else {
612 +               MessagingMojoService.getMessagetone(this.doBanner.bind(this,bannerParams,bannerLaunchParams,'chat'));
613 +       }
614 +};
615 +
616 +NotificationAssistant.prototype.playmsgtone = function(contact){
617 +       Mojo.Log.error("Playmsgtone Ringtone: %j",contact.ringtoneLoc);
618 +       if (contact.ringtoneLoc)
619 +               this.controller.playSoundNotification('alerts',contact.ringtoneLoc);
620 +       else
621 +               MessagingMojoService.getMessagetone(this.playMessagetone.bind(this));
622 +};
623 +
624  NotificationAssistant.prototype.sendNotification = function(notificationType, resp){
625         if (window.PalmSystem && !resp.returnValue) {
626                 try {
627 @@ -140,7 +173,8 @@ NotificationAssistant.prototype.consider
628         
629         // check if we should only play a sound (when you are already in a chat & a new message comes in)
630         if(notificationData.get('playSoundOnly') && this.Messaging.messagingPrefs.enableNotificationSound) {
631 -               this.controller.playSoundNotification('alerts','');
632 +               var smsid = notificationData.get('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 @@ -176,10 +210,11 @@ NotificationAssistant.prototype.sendClas
638  
639         notificationData.set('alertTitle',alertTitle);
640         this.class0AlertData.list.push(notificationData);
641 -       this.renderClass0PopupAlert(true);
642 +       var smsid = notificationData.get('address');
643 +       MessagingMojoService.getMessagetone(this.renderClass0PopupAlert.bind(this,true));
644  };
645  
646 -NotificationAssistant.prototype.renderClass0PopupAlert = function(playSound) {
647 +NotificationAssistant.prototype.renderClass0PopupAlert = function(playSound,messageTone) {
648         var class0Stage = this.controller.getStageController(Class0AlertStageName);
649  
650         if(class0Stage) {
651 @@ -188,6 +223,8 @@ NotificationAssistant.prototype.renderCl
652                 var soundClass = 'none';
653                 if(playSound) {
654                         soundClass = 'alerts';
655 +                       if(messageTone)
656 +                               soundFile = messageTone;
657                 }               
658                 
659                 var pushClass0AlertScene = function(stageController) {
660 @@ -198,7 +235,8 @@ NotificationAssistant.prototype.renderCl
661                         name: Class0AlertStageName,
662                         lightweight: true,
663                         height: 300,
664 -                       soundclass: soundClass
665 +                       soundclass: soundClass,
666 +                       soundfile: soundFile
667                 }, pushClass0AlertScene, 'popupalert');         
668         }
669         
670 @@ -253,8 +291,6 @@ NotificationAssistant.prototype.sendNewM
671         var bannerParams = {
672                 messageText: notificationText
673         };
674 -       if (this.Messaging.messagingPrefs.enableNotificationSound)
675 -               bannerParams.soundClass = "alerts";
676         var bannerLaunchParams =  {
677                 chatThreadId: chatThreadId,
678                 clearBanner: true               
679 @@ -262,10 +298,17 @@ NotificationAssistant.prototype.sendNewM
680         
681         if (this.Messaging.DisplayState.isDisplayOn()) {
682                 Mojo.Log.info("notificationAssistant - executing full banner notification");    
683 -               this.controller.showBanner(bannerParams, bannerLaunchParams, 'chat');           
684 +               if (this.Messaging.messagingPrefs.enableNotificationSound) {
685 +                       var smsid = notificationData.get('address');                                                  
686 +                       bannerParams.soundClass = "alerts";
687 +                       MessagingMojoService.rLookup(smsid,contact,this.doB.bind(this,bannerParams,bannerLaunchParams,'chat'),this.doB.bind(this,bannerParams,bannerLaunchParams,'chat'));
688 +               } else {
689 +                       Mojo.Log.error("Setting banner params");        
690 +                       this.controller.showBanner(bannerParams, bannerLaunchParams, 'chat');
691 +               }       
692         } else if (this.Messaging.messagingPrefs.enableNotificationSound) {
693 -               Mojo.Log.info("notificationAssistant - playing sound notification only");
694 -               this.controller.playSoundNotification('alerts','');
695 +               var smsid = notificationData.get('address');                                                  
696 +               MessagingMojoService.rLookup(smsid,contact,this.playmsgtone.bind(this),this.playmsgtone.bind(this));
697         }
698         
699         // Store the data so it can be used in the dashboard
700 @@ -324,13 +367,9 @@ NotificationAssistant.prototype.sendNewM
701                 // delay creating the dashboard window for the case where the banner is clicked on
702                 // to take you to the chat view.  This will likely result in the dashboard data
703                 // being cleared.  If the dashboard data is empty, we do not need to create the dashboard.              
704 -               if (this.Messaging.DisplayState.isDisplayOn()) {
705 -                       if (!this.isNewMessageDashboardPending) {
706 -                               this.isNewMessageDashboardPending = true; 
707 -                               createDashboard.delay(5);
708 -                       }
709 -               } else {
710 -                       createDashboard(); // if the screen is off, create the dashboard right away
711 +               if (!this.isNewMessageDashboardPending) {
712 +                       this.isNewMessageDashboardPending = true; 
713 +                       createDashboard.delay(5);               
714                 }
715         }
716  };