1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 function Loader(pages) { 6 this.pages_ = pages; 7 this.pagesLoaded_ = false; 8 this.loadedCount_ = false; 9 } 10 11 // Global instance. 12 Loader.instance_ = null; 13 14 // static. 15 Loader.getInstance = function() { 16 if (!Loader.instance_) { 17 if (!g_pages) 18 console.log('Warning: Undefined g_pages.'); 19 Loader.instance_ = new Loader(g_pages); 20 } 21 22 return Loader.instance_; 23 }; 24 25 Loader.prototype = { 26 // Alarm name. 27 ALARM_NAME: 'CrOSBkgLoaderAlarm', 28 29 // Initial delay. 30 DELAY_IN_MINUTES: 1, 31 32 // Periodic wakeup delay. 33 PERIOD_IN_MINUTES: 60, 34 35 // Delayed closing of the background page once when all iframes are loaded. 36 maxDelayMS_: 10000, 37 38 // Loader start up. Kicks off alarm initialization if needed. 39 initialize: function() { 40 if (!g_pages || !g_pages.length) { 41 window.close(); 42 return; 43 } 44 45 chrome.alarms.onAlarm.addListener(this.onAlarm_.bind(this)); 46 // Check if this alarm already exists, if not then create it. 47 chrome.alarms.get(this.ALARM_NAME, function(alarm) { 48 if (!alarm) { 49 chrome.alarms.create(this.ALARM_NAME, 50 {delayInMinutes: this.DELAY_IN_MINUTES}); 51 window.close(); 52 return; 53 } 54 }.bind(this)); 55 }, 56 57 onAlarm_: function(alarm) { 58 if (alarm.name != this.ALARM_NAME) 59 return; 60 61 this.preparePages_(); 62 }, 63 64 onMessage_: function(event) { 65 var msg = event.data; 66 if (msg.method == 'validate') { 67 var replyMsg = { 68 method: 'validationResults', 69 os: 'ChromeOS' 70 }; 71 event.source.postMessage(replyMsg, event.origin); 72 } else { 73 console.log('#### Loader.onMessage_: unknown message'); 74 } 75 }, 76 77 // Find an extension in the |list| with matching extension |id|. 78 getExtensionById_: function(list, id) { 79 for (var i = 0; i < list.length; i++) { 80 if (list[i].id == id) 81 return list[i]; 82 } 83 return null; 84 }, 85 86 preparePages_: function() { 87 if (this.pagesLoaded_) 88 return; 89 90 window.addEventListener('message', this.onMessage_.bind(this), false); 91 chrome.management.getAll(function(list) { 92 // Get total count first. 93 var pagesToLoad = []; 94 for (var i = 0; i < this.pages_.length; i++) { 95 var page = this.pages_[i]; 96 if (page.oneTime && page.initialized) 97 continue; 98 99 var extension = this.getExtensionById_(list, page.extensionId); 100 if (!extension || !extension.enabled) { 101 page.initialized = true; 102 continue; 103 } 104 105 page.initialized = true; 106 if (page.unloadDelayMS > this.maxDelayMS_) 107 this.maxDelayMS_ = page.unloadDelayMS; 108 109 pagesToLoad.push(page); 110 } 111 this.loadFrames_(pagesToLoad); 112 this.pagesLoaded_ = true; 113 }.bind(this)); 114 }, 115 116 loadFrames_: function(pages) { 117 this.load_target_ = pages.length; 118 for (var i = 0; i < pages.length; i++) { 119 this.loadLuncherFrame_(i, pages[i].pageUrl); 120 } 121 }, 122 123 incrementLoadCounter_: function() { 124 this.loadedCount_++; 125 if (this.loadedCount_ < this.load_target_) 126 return; 127 128 // Delay closing. 129 setInterval(function() { 130 window.close(); 131 }.bind(this), this.maxDelayMS_); 132 }, 133 134 loadLuncherFrame_: function(index, pageUrl) { 135 var iframe = document.createElement('iframe'); 136 iframe.onload = function() { 137 this.incrementLoadCounter_(); 138 }.bind(this); 139 iframe.src = pageUrl; 140 iframe.name = 'frame_' + index; 141 document.body.appendChild(iframe); 142 } 143 }; 144 145 Loader.getInstance().initialize(); 146