summaryrefslogtreecommitdiffstats
path: root/dom/browser-element/mochitest/priority/test_HighPriority.html
blob: d3396d65b6d628d61c510c8d95bcb4bdb6440983 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!DOCTYPE HTML>
<html>
<!--
Test that frames with mozapptype=critical which hold the "high-priority" or
"cpu" wake locks get elevated process priority.
-->
<head>
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="application/javascript" src="../browserElementTestHelpers.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>

<script type="application/javascript;version=1.7">
"use strict";

SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.enableProcessPriorityManager();

function runTest() {
  // To test bug 870480, run this test while holding the CPU and high-priority
  // wake locks.  Without the fix for bug 870480, we won't set the priority of
  // the child process if the main process holds these wake locks and the test
  // will hang.
  navigator.requestWakeLock('cpu');
  navigator.requestWakeLock('high-priority');

  var iframe = document.createElement('iframe');
  iframe.setAttribute('mozbrowser', true);
  iframe.setAttribute('mozapptype', 'critical');
  iframe.src = 'file_HighPriority.html';

  // We expect the following to happen:
  //
  // - Process is created.
  // - Its priority is set to FOREGROUND (when the process starts).
  // - wait_alert('step0', FOREGROUND_HIGH)
  // - wait_alert('step1', FOREGROUND)
  // - wait_alert('step2', FOREGROUND_HIGH)
  //
  // Where wait_alert(M, P) means that we expect the subprocess to
  //   * do alert(M) and
  //   * be set to priority P
  // in some order.  If the alert occurs before the priority change, we block
  // the alert until we observe the priority change.  So the subprocess only
  // has to do
  //
  //   // set priority to FOREGROUND_HIGH
  //   alert('step0');
  //   // set priority to FOREGROUND
  //   alert('step1');
  //
  // etc.

  var childID = null;
  var alertTimes = [];

  // Return a promise that's resolved once the child process calls alert() and
  // we get a priority change, in some order.
  //
  // We check that the text of the alert is |"step" + index|.
  //
  // If gracePeriod is given, we check that the priority change occurred at
  // least gracePeriod ms since the alert from the previous step (with a fudge
  // factor to account for inaccurate timers).
  function expectAlertAndPriorityChange(index, priority, /* optional */ gracePeriod) {
    function checkAlertInfo(e) {
      is(e.detail.message, 'step' + index, 'alert() number ' + index);
      alertTimes.push(new Date());

      // Block the alert; we'll unblock it by calling e.detail.unblock() later.
      e.preventDefault();
      return Promise.resolve(e.detail.unblock);
    }

    function checkGracePeriod() {
      if (gracePeriod) {
        var msSinceLastAlert = (new Date()) - alertTimes[index - 1];

        // 50ms fudge factor.  This test is set up so that, if nsITimers are
        // accurate, we don't need any fudge factor.  Unfortunately our timers
        // are not accurate!  There's little we can do here except fudge.
        // Thankfully all we're trying to test is that we get /some/ delay; the
        // exact amount of delay isn't so important.
        ok(msSinceLastAlert + 50 >= gracePeriod,
           msSinceLastAlert + "ms since last alert >= (" + gracePeriod + " - 50ms)");
      }
    }

    return Promise.all([
      new Promise(function(resolve, reject) {
        iframe.addEventListener('mozbrowsershowmodalprompt', function check(e) {
          iframe.removeEventListener('mozbrowsershowmodalprompt', check);
          resolve(checkAlertInfo(e));
        });
      }),
      expectPriorityChange(childID, priority).then(checkGracePeriod)
    ]).then(function(results) {
      // checkAlertInfo returns the function to call to unblock the alert.
      // It comes to us as the first element of the results array.
      results[0]();
    });
  }

  expectProcessCreated('FOREGROUND').then(function(chid) {
    childID = chid;
  }).then(function() {
    return expectAlertAndPriorityChange(0, 'FOREGROUND_HIGH');
  }).then(function() {
    return expectAlertAndPriorityChange(1, 'FOREGROUND', priorityChangeGracePeriod);
  }).then(function() {
    return expectAlertAndPriorityChange(2, 'FOREGROUND_HIGH');
  }).then(function() {
    return expectAlertAndPriorityChange(3, 'FOREGROUND', priorityChangeGracePeriod);
  }).then(SimpleTest.finish);

  document.body.appendChild(iframe);
}

const priorityChangeGracePeriod = 100;
addEventListener('testready', function() {
  SpecialPowers.pushPrefEnv(
    {set: [['dom.ipc.processPriorityManager.backgroundGracePeriodMS',
            priorityChangeGracePeriod],
           ['dom.wakelock.enabled', true]]},
    runTest);
});

</script>
</body>
</html>