Home | History | Annotate | Download | only in scripts
      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