Bug 1449277 [wpt PR 10198] - Enable WPT tests for the Generic Sensor classes, a=testonly
authorMikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
Tue, 15 May 2018 13:35:31 +0000
changeset 418490 b8ae1c026c8a586bd2afc5d66e9eb0e75062fb59
parent 418489 b6f443bc0763622e0c969b40758b344be28740c2
child 418491 7bb553acbd3d857eccd0f15d0f0fd6191d0b49df
push id103318
push userwptsync@mozilla.com
push dateWed, 16 May 2018 15:06:09 +0000
treeherdermozilla-inbound@51f1ecd79ebe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1449277, 10198, 816462, 980886, 550586
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1449277 [wpt PR 10198] - Enable WPT tests for the Generic Sensor classes, a=testonly Automatic update from web-platform-testsEnable WPT tests for the Generic Sensor classes This patch introduces mock implementations of the Sensor and SensorProvider mojo interfaces to the WPT tests for Chromium. The ongoing WPT issue for the Generic Sensor tests automation: https://github.com/w3c/web-platform-tests/issues/9686 Bug: 816462 Change-Id: I8e4880ee5269b07f0bf68a2752038e128d166c55 Reviewed-on: https://chromium-review.googlesource.com/980886 Reviewed-by: Mike West <mkwst@chromium.org> Reviewed-by: Philip J├Ągenstedt <foolip@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Reviewed-by: Alexander Shalamov <alexander.shalamov@intel.com> Commit-Queue: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> Cr-Commit-Position: refs/heads/master@{#550586} -- wpt-commits: b55a93ab1fa441d8998fcfb1173d00dab4b733c0 wpt-pr: 10198
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/accelerometer/Accelerometer-disabled-by-feature-policy.https.html
testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html
testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy-attribute.https.html
testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy.https.html
testing/web-platform/tests/accelerometer/Accelerometer-enabled-on-self-origin-by-feature-policy.https.html
testing/web-platform/tests/accelerometer/Accelerometer.https.html
testing/web-platform/tests/accelerometer/Accelerometer_onerror-manual.https.html
testing/web-platform/tests/generic-sensor/README.md
testing/web-platform/tests/generic-sensor/generic-sensor-feature-policy-test.sub.js
testing/web-platform/tests/generic-sensor/generic-sensor-tests.js
testing/web-platform/tests/gyroscope/Gyroscope-disabled-by-feature-policy.https.html
testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy-attribute-redirect-on-load.https.html
testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy-attribute.https.html
testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy.https.html
testing/web-platform/tests/gyroscope/Gyroscope-enabled-on-self-origin-by-feature-policy.https.html
testing/web-platform/tests/gyroscope/Gyroscope.https.html
testing/web-platform/tests/gyroscope/Gyroscope_onerror-manual.https.html
testing/web-platform/tests/lint.whitelist
testing/web-platform/tests/magnetometer/Magnetometer-disabled-by-feature-policy.https.html
testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html
testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy-attribute.https.html
testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy.https.html
testing/web-platform/tests/magnetometer/Magnetometer-enabled-on-self-origin-by-feature-policy.https.html
testing/web-platform/tests/magnetometer/Magnetometer.https.html
testing/web-platform/tests/magnetometer/Magnetometer_onerror-manual.https.html
testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-disabled-by-feature-policy.https.html
testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html
testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute.https.html
testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy.https.html
testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html
testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor.https.html
testing/web-platform/tests/orientation-sensor/OrientationSensor.https.html
testing/web-platform/tests/orientation-sensor/OrientationSensor_onerror-manual.https.html
testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-disabled-by-feature-policy.https.html
testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html
testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute.https.html
testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy.https.html
testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html
testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor.https.html
testing/web-platform/tests/orientation-sensor/orientation-sensor-tests.js
testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js
testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js.headers
testing/web-platform/tests/resources/chromium/sensor.mojom.js
testing/web-platform/tests/resources/chromium/sensor_provider.mojom.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -276219,16 +276219,21 @@
      {}
     ]
    ],
    "generic-sensor/OWNERS": [
     [
      {}
     ]
    ],
+   "generic-sensor/README.md": [
+    [
+     {}
+    ]
+   ],
    "generic-sensor/generic-sensor-feature-policy-test.sub.js": [
     [
      {}
     ]
    ],
    "generic-sensor/generic-sensor-tests.js": [
     [
      {}
@@ -290684,16 +290689,21 @@
      {}
     ]
    ],
    "orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html.headers": [
     [
      {}
     ]
    ],
+   "orientation-sensor/orientation-sensor-tests.js": [
+    [
+     {}
+    ]
+   ],
    "page-visibility/OWNERS": [
     [
      {}
     ]
    ],
    "page-visibility/resources/blank_page_green.html": [
     [
      {}
@@ -356199,19 +356209,19 @@
     ]
    ],
    "orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html": [
     [
      "/orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html",
      {}
     ]
    ],
-   "orientation-sensor/OrientationSensor.https.html": [
-    [
-     "/orientation-sensor/OrientationSensor.https.html",
+   "orientation-sensor/AbsoluteOrientationSensor.https.html": [
+    [
+     "/orientation-sensor/AbsoluteOrientationSensor.https.html",
      {}
     ]
    ],
    "orientation-sensor/OrientationSensor_insecure_context.html": [
     [
      "/orientation-sensor/OrientationSensor_insecure_context.html",
      {}
     ]
@@ -356241,16 +356251,22 @@
     ]
    ],
    "orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html": [
     [
      "/orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html",
      {}
     ]
    ],
+   "orientation-sensor/RelativeOrientationSensor.https.html": [
+    [
+     "/orientation-sensor/RelativeOrientationSensor.https.html",
+     {}
+    ]
+   ],
    "orientation-sensor/idlharness.https.html": [
     [
      "/orientation-sensor/idlharness.https.html",
      {}
     ]
    ],
    "page-visibility/idlharness.html": [
     [
@@ -398455,17 +398471,17 @@
    "766bb4d66deef9bcb90339d76e3280abb36103df",
    "support"
   ],
   "./check_stability.ini": [
    "f8af4287f3b0f6925a2a6c5c75b3788e24de1680",
    "support"
   ],
   "./lint.whitelist": [
-   "531f46c08646b67c6d85095fdd48f5aa9fa7cb18",
+   "b740ea6ee933d028f6b2bef92cc473778b76002f",
    "support"
   ],
   "./serve.py": [
    "0efa39b1f26f86d73f2fce4f9e46003d62057b41",
    "support"
   ],
   "./server-side.md": [
    "c51b17fbac2a2e3121dc74f7badbd2873ce92f61",
@@ -405291,57 +405307,57 @@
    "df0462ed34e1cf026321f9174870b334af445e56",
    "support"
   ],
   "WebIDL/valid/xml/variadic-operations.widlprocxml": [
    "e31231c6db703a58c03160bc81e1c935019c1f17",
    "support"
   ],
   "accelerometer/Accelerometer-disabled-by-feature-policy.https.html": [
-   "96e5a86bf78239f3aa4a79b32bb4308de0d5f60e",
+   "efa020e5d2384a3b753d41d32fd9e62337b5fd9e",
    "testharness"
   ],
   "accelerometer/Accelerometer-disabled-by-feature-policy.https.html.headers": [
    "bde03e5f36844e0818f4d1092c4fe6788cb4e194",
    "support"
   ],
   "accelerometer/Accelerometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html": [
-   "f20f89a31daf399a7946b928e8deca9651d38487",
+   "0e27e5bad61367dcc348aef1ac813e70a2e2aa36",
    "testharness"
   ],
   "accelerometer/Accelerometer-enabled-by-feature-policy-attribute.https.html": [
-   "7ce8c39f0af6c932d1e6b6f75843c090f7274b80",
+   "5e072aa513efc16946b2f93ecb815d45dd6cadd2",
    "testharness"
   ],
   "accelerometer/Accelerometer-enabled-by-feature-policy.https.html": [
-   "dbda7cfa838c1f2d4296b545034d42f0064f331a",
+   "59207b5dbc249addf4a9c0c5886e1486a2d6eb94",
    "testharness"
   ],
   "accelerometer/Accelerometer-enabled-by-feature-policy.https.html.headers": [
    "18a6f86070b21bff87cc9dc37194cdb6113af198",
    "support"
   ],
   "accelerometer/Accelerometer-enabled-on-self-origin-by-feature-policy.https.html": [
-   "b8fb07cdd23dce9690de719387b9d505382772f5",
+   "fe9960de7b6ac203a36096f90ede31131e38cb1b",
    "testharness"
   ],
   "accelerometer/Accelerometer-enabled-on-self-origin-by-feature-policy.https.html.headers": [
    "c1723ad9944cf2393a5519a91e4e47a0255bcaf4",
    "support"
   ],
   "accelerometer/Accelerometer.https.html": [
-   "3ff5f61b25c52142e9796f3903d7f2bcaa30314c",
+   "bef928057d49b59c2ede3916e49abdd730dc9582",
    "testharness"
   ],
   "accelerometer/Accelerometer_insecure_context.html": [
    "82be1b9a5c6e75291fdc1aabe230af28e22823a8",
    "testharness"
   ],
   "accelerometer/Accelerometer_onerror-manual.https.html": [
-   "c82f9595dc2582b2da40549a358da1c3fc2ff820",
+   "f6a624b70b401c0802c5f189c89e85d63fe58795",
    "manual"
   ],
   "accelerometer/LinearAccelerationSensor-shake-threshold-manual.https.html": [
    "30e8588ff49a1d526d65aac89bc80f4782715914",
    "manual"
   ],
   "accelerometer/OWNERS": [
    "b119dbb984792f33c6e7463f3105d37c3c3b7ad8",
@@ -562078,26 +562094,30 @@
   "gamepad/timestamp-manual.html": [
    "b2432e7ea263fb80be42e7eecf93a9d885c0205d",
    "manual"
   ],
   "generic-sensor/OWNERS": [
    "b1349055762c7d44414c0c11fb8500d5eee9a75f",
    "support"
   ],
+  "generic-sensor/README.md": [
+   "48615c1b9e70e02c02ea0246eb7ca1953bab0c68",
+   "support"
+  ],
   "generic-sensor/SensorErrorEvent-constructor.https.html": [
    "99bcfb42c91e084a3b847ab4bab2bad80e548540",
    "testharness"
   ],
   "generic-sensor/generic-sensor-feature-policy-test.sub.js": [
-   "c7c9c4d1c578f267cbb4241d7ea7a981be6f49ee",
+   "f90a08bd96c729c5c166fd628e69f01c3413a78c",
    "support"
   ],
   "generic-sensor/generic-sensor-tests.js": [
-   "6364f1838215eaafd91b86690039da41d4c19cd1",
+   "a23c776f7536e3f406c78a5aa02359c7dde8c745",
    "support"
   ],
   "generic-sensor/idlharness.https.html": [
    "02c734b907075c8abb7504fc7e2b93730ac80a0c",
    "testharness"
   ],
   "geolocation-API/OWNERS": [
    "84c4182ceed0f75ada11e63c3dfc2acc2939cbb6",
@@ -562239,57 +562259,57 @@
    "be301a3a71514708c547fa033eab0271367a3fb9",
    "manual"
   ],
   "graphics-aam/graphics-symbol_on_svg_element-manual.html": [
    "52b2e48333492373708b86cf558e578b04ac5977",
    "manual"
   ],
   "gyroscope/Gyroscope-disabled-by-feature-policy.https.html": [
-   "bc6f85cb3506d3e3e062eef43dca88bf3a4ebe89",
+   "64db7d9fe9726d6c04e97802f2328e3cfe6e2585",
    "testharness"
   ],
   "gyroscope/Gyroscope-disabled-by-feature-policy.https.html.headers": [
    "b4767ccc5e319ec08705af56990c8d8093640ff0",
    "support"
   ],
   "gyroscope/Gyroscope-enabled-by-feature-policy-attribute-redirect-on-load.https.html": [
-   "cc1f4082fa420a9076f929d88268f5a1d921a44a",
+   "6f9c2974d9fa82d85ecc299990295f7bb44fbced",
    "testharness"
   ],
   "gyroscope/Gyroscope-enabled-by-feature-policy-attribute.https.html": [
-   "75429c87bbebd19df7b4edaddc5869c6202b3fab",
+   "413cad8e563dd38decb5e388a3a10363417cd413",
    "testharness"
   ],
   "gyroscope/Gyroscope-enabled-by-feature-policy.https.html": [
-   "5129c05f9b226650a9b7fed4841871045525bf15",
+   "5c723e19f2f67d50d7e5d1ea75a5c09b4eeec4a3",
    "testharness"
   ],
   "gyroscope/Gyroscope-enabled-by-feature-policy.https.html.headers": [
    "b0ce79c08e8b5908485a8bb4c6d86e8d20b2a44c",
    "support"
   ],
   "gyroscope/Gyroscope-enabled-on-self-origin-by-feature-policy.https.html": [
-   "2603bd858929ae6f84ebbe0cce34c5417ccdae06",
+   "3b6cc272c04aee446ce8dffbe041330e5c2298ea",
    "testharness"
   ],
   "gyroscope/Gyroscope-enabled-on-self-origin-by-feature-policy.https.html.headers": [
    "59acbd3ef447d2197c4a9af2837dbacdf1e31885",
    "support"
   ],
   "gyroscope/Gyroscope.https.html": [
-   "504abfa42529e08576e49c3296464bcea5fe0b8a",
+   "e2b1919195d0af74bb7733a6d8a299adf43f4ee4",
    "testharness"
   ],
   "gyroscope/Gyroscope_insecure_context.html": [
    "74e51a1efc06bf8180db430b418d484fc50c07f9",
    "testharness"
   ],
   "gyroscope/Gyroscope_onerror-manual.https.html": [
-   "1e15b883bd317ca83783864fc563794cb0f6df8e",
+   "c8f346f00bbc296e89e132926f974ee408d66fcf",
    "manual"
   ],
   "gyroscope/OWNERS": [
    "b119dbb984792f33c6e7463f3105d37c3c3b7ad8",
    "support"
   ],
   "gyroscope/idlharness.https.html": [
    "8b9b8fcdc6d33fb20c174b67306a182bdbb707fd",
@@ -582671,57 +582691,57 @@
    "903bb60746deebd8f39ee8ea1a84b40e17884c3c",
    "testharness"
   ],
   "longtask-timing/shared-renderer/resources/frame-with-longtask.html": [
    "2901b02184fb36d620782fb7fd4a565124580e81",
    "support"
   ],
   "magnetometer/Magnetometer-disabled-by-feature-policy.https.html": [
-   "9af542095f2fcd57691c0432ef3248b04a0207a0",
+   "33e6cbd89ec34e729d84f5a50bd7f75c47fa42e8",
    "testharness"
   ],
   "magnetometer/Magnetometer-disabled-by-feature-policy.https.html.headers": [
    "9a930b1268bf30ce845ba6671dbb2f44faa92bb2",
    "support"
   ],
   "magnetometer/Magnetometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html": [
-   "47829ff5747eed99ba22e79b12ddfff288fd031e",
+   "3686719c3eab1867e5f5755dea11734f52123a68",
    "testharness"
   ],
   "magnetometer/Magnetometer-enabled-by-feature-policy-attribute.https.html": [
-   "3b6314e9176a24976d9d882644c30f00554eed6d",
+   "8c61e61e1a7b43a080991d12c7b469e30613a165",
    "testharness"
   ],
   "magnetometer/Magnetometer-enabled-by-feature-policy.https.html": [
-   "05128cdb7171ba230143e7b68b09968a484b602a",
+   "806b736a6320c82d5c6f10fae30ba5c35e695e10",
    "testharness"
   ],
   "magnetometer/Magnetometer-enabled-by-feature-policy.https.html.headers": [
    "2be01ba1805ae8fd8038a70763b29e2070a96f78",
    "support"
   ],
   "magnetometer/Magnetometer-enabled-on-self-origin-by-feature-policy.https.html": [
-   "3240dafd2bc810dea0dc1ebc31728c86a29f2ec5",
+   "5871a3396ac4030f2202ea27f48fcb715de26236",
    "testharness"
   ],
   "magnetometer/Magnetometer-enabled-on-self-origin-by-feature-policy.https.html.headers": [
    "2099d254fa4bb019404df56ec1a99e84459c77e2",
    "support"
   ],
   "magnetometer/Magnetometer.https.html": [
-   "240e7d0af55b8681f2f45ca22283634acc406325",
+   "85b033df53fcaec4a55175f6a9438bd2abf5e6ff",
    "testharness"
   ],
   "magnetometer/Magnetometer_insecure_context.html": [
    "0eeb95340d7c74a0243eac8d3f004b6e06b87a92",
    "testharness"
   ],
   "magnetometer/Magnetometer_onerror-manual.https.html": [
-   "da4e6b8975beecdcae24da26920a56a652f781e4",
+   "5da81d90bd6960c94d5b3dd7592aa4c93d996e1a",
    "manual"
   ],
   "magnetometer/OWNERS": [
    "b119dbb984792f33c6e7463f3105d37c3c3b7ad8",
    "support"
   ],
   "magnetometer/idlharness.https.html": [
    "d5ba7fe95ed2740eec56757dfe3b0a900f3ea4c4",
@@ -591811,99 +591831,107 @@
    "c75b1abe106111ace7f213ee84087daf17f0f48d",
    "manual"
   ],
   "orientation-event/t028-manual.html": [
    "6948dbbdc88ffd9aa84ad5a6c822b354809561b2",
    "manual"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-disabled-by-feature-policy.https.html": [
-   "0c7657e32b46c64e5f050f04e40ccfc0dce32e47",
+   "d0ad686df1fc6e176a23f827f5afb61c55a7754b",
    "testharness"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-disabled-by-feature-policy.https.html.headers": [
    "86af2e7ee455898629df466e7084ab6e909ec313",
    "support"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html": [
-   "71a6966fb91f8ddfe15ee690c843e4621a3b4720",
+   "c666593365dba60ccf03a354f997bb86cab6581c",
    "testharness"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute.https.html": [
-   "9bbe39e1be4a669f31f0fb3960aca22d7d159c5e",
+   "cd0c5fb506d123dea5e162994e68e908b8e18fa0",
    "testharness"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy.https.html": [
-   "9f110b8ceca3dd3ce3d2a9e2567d92a3fc6462bf",
+   "260958b236c47b8d8796c8003ce3c1b1cedbe162",
    "testharness"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy.https.html.headers": [
    "f96008f4d28eec8c158a31c8e5c2bbc9ff55ef05",
    "support"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html": [
-   "c4404cf0b16c4d9ad15308392ecf52caee445b86",
+   "7d7709582f6fcfadd7000b79114a36adbf1c7dde",
    "testharness"
   ],
   "orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html.headers": [
    "cb27e0f09caa38fc80b29580be4b0c06c1024a18",
    "support"
   ],
+  "orientation-sensor/AbsoluteOrientationSensor.https.html": [
+   "c482c21d4336decf5d4c47b4e6911dc2b03a19e9",
+   "testharness"
+  ],
   "orientation-sensor/OWNERS": [
    "b119dbb984792f33c6e7463f3105d37c3c3b7ad8",
    "support"
   ],
-  "orientation-sensor/OrientationSensor.https.html": [
-   "ea9a61f9d526183071a0336e11ca844f59c284a9",
-   "testharness"
-  ],
   "orientation-sensor/OrientationSensor_insecure_context.html": [
    "eb64da888f1bedf9d5ed8b11edc1626da88b322b",
    "testharness"
   ],
   "orientation-sensor/OrientationSensor_onerror-manual.https.html": [
-   "6f0eb976affc21e49f48c42c1bd9d9eb0083ee40",
+   "c7d57da56142057f23503da971875df46ef6d137",
    "manual"
   ],
   "orientation-sensor/RelativeOrientationSensor-disabled-by-feature-policy.https.html": [
-   "8c6c5f8f3bc4421f5143a3e4fab287564cf4907d",
+   "c45d0a4cbfa68431c97e6d6288a9e57161100733",
    "testharness"
   ],
   "orientation-sensor/RelativeOrientationSensor-disabled-by-feature-policy.https.html.headers": [
    "8795ff5458374246ec69928cf9545cb17be3c641",
    "support"
   ],
   "orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html": [
-   "34a79c9033a41c0aceab3fa6a470dd5a76f2ac81",
+   "fb57e3d552c56f9b7e21f461b4938d850c5c9d8a",
    "testharness"
   ],
   "orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute.https.html": [
-   "0e6260ccdaa8163b8db96516960be226a4d85ba7",
+   "04bf99c095016b4f39a99819f0cf3b5742c7e436",
    "testharness"
   ],
   "orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy.https.html": [
-   "243b2d60d4c528a77e9cfb68fa256b35234e7346",
+   "2286335655c89a9428193cd42a42ec1df7ddf333",
    "testharness"
   ],
   "orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy.https.html.headers": [
    "644b0398e76ea06dd5cd012338555b608da02122",
    "support"
   ],
   "orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html": [
-   "c9f234f6508fb778fdf91277bb8950c99479979d",
+   "4b529302141beb7cdf2b6569a0f836dc378ba062",
    "testharness"
   ],
   "orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html.headers": [
    "e6e93a77c618e8477d79f6cf1ff05d0f5865821c",
    "support"
   ],
+  "orientation-sensor/RelativeOrientationSensor.https.html": [
+   "9bf83c64eb5dcf284eb6c45db8ac278ab3c637a2",
+   "testharness"
+  ],
   "orientation-sensor/idlharness.https.html": [
    "1f94329cb330a1a904d409a6e158a5fe9f8dd709",
    "testharness"
   ],
+  "orientation-sensor/orientation-sensor-tests.js": [
+   "250d6009213e72069acd56e847fc9509c52c1d90",
+   "support"
+  ],
   "page-visibility/OWNERS": [
    "b82f9756b15ef3ea45fb250e304031d9ceaee9c7",
    "support"
   ],
   "page-visibility/idlharness.html": [
    "e3f97d7f03caf99d71e9528c6db75c13c477b4eb",
    "testharness"
   ],
--- a/testing/web-platform/tests/accelerometer/Accelerometer-disabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer-disabled-by-feature-policy.https.html
@@ -3,13 +3,13 @@
 <title>Accelerometer Feature Policy Test: Disabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_disabled(Accelerometer);
-run_fp_tests_disabled(LinearAccelerationSensor);
-run_fp_tests_disabled(GravitySensor);
+run_fp_tests_disabled('Accelerometer');
+run_fp_tests_disabled('LinearAccelerationSensor');
+run_fp_tests_disabled('GravitySensor');
 </script>
 </body>
--- a/testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html
@@ -3,13 +3,13 @@
 <title>Accelerometer Feature Policy Test: Enabled by attribute redirect on load</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute_redirect_on_load(Accelerometer);
-run_fp_tests_enabled_by_attribute_redirect_on_load(LinearAccelerationSensor);
-run_fp_tests_enabled_by_attribute_redirect_on_load(GravitySensor);
+run_fp_tests_enabled_by_attribute_redirect_on_load('Accelerometer');
+run_fp_tests_enabled_by_attribute_redirect_on_load('LinearAccelerationSensor');
+run_fp_tests_enabled_by_attribute_redirect_on_load('GravitySensor');
 </script>
 </body>
--- a/testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy-attribute.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy-attribute.https.html
@@ -3,13 +3,13 @@
 <title>Accelerometer Feature Policy Test: Enabled by attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute(Accelerometer);
-run_fp_tests_enabled_by_attribute(LinearAccelerationSensor);
-run_fp_tests_enabled_by_attribute(GravitySensor);
+run_fp_tests_enabled_by_attribute('Accelerometer');
+run_fp_tests_enabled_by_attribute('LinearAccelerationSensor');
+run_fp_tests_enabled_by_attribute('GravitySensor');
 </script>
 </body>
--- a/testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer-enabled-by-feature-policy.https.html
@@ -3,13 +3,13 @@
 <title>Accelerometer Feature Policy Test: Enabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled(Accelerometer);
-run_fp_tests_enabled(LinearAccelerationSensor);
-run_fp_tests_enabled(GravitySensor);
+run_fp_tests_enabled('Accelerometer');
+run_fp_tests_enabled('LinearAccelerationSensor');
+run_fp_tests_enabled('GravitySensor');
 </script>
 </body>
--- a/testing/web-platform/tests/accelerometer/Accelerometer-enabled-on-self-origin-by-feature-policy.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer-enabled-on-self-origin-by-feature-policy.https.html
@@ -3,13 +3,13 @@
 <title>Accelerometer Feature Policy Test: Enabled on self origin</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_on_self_origin(Accelerometer);
-run_fp_tests_enabled_on_self_origin(LinearAccelerationSensor);
-run_fp_tests_enabled_on_self_origin(GravitySensor);
+run_fp_tests_enabled_on_self_origin('Accelerometer');
+run_fp_tests_enabled_on_self_origin('LinearAccelerationSensor');
+run_fp_tests_enabled_on_self_origin('GravitySensor');
 </script>
 </body>
--- a/testing/web-platform/tests/accelerometer/Accelerometer.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer.https.html
@@ -4,13 +4,13 @@
 <link rel="author" title="Intel" href="http://www.intel.com">
 <link rel="help" href="https://www.w3.org/TR/accelerometer/">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/generic-sensor/generic-sensor-tests.js"></script>
 <div id="log"></div>
 <script>
 
-runGenericSensorTests(Accelerometer);
-runGenericSensorTests(GravitySensor);
-runGenericSensorTests(LinearAccelerationSensor);
+runGenericSensorTests('Accelerometer');
+runGenericSensorTests('GravitySensor');
+runGenericSensorTests('LinearAccelerationSensor');
 
 </script>
--- a/testing/web-platform/tests/accelerometer/Accelerometer_onerror-manual.https.html
+++ b/testing/web-platform/tests/accelerometer/Accelerometer_onerror-manual.https.html
@@ -10,13 +10,13 @@
 <h2>Precondition</h2>
 <ol>
   <li>
     Disable the Accelerometer Sensor or run test on a device without Accelerometer Sensor.
   </li>
 </ol>
 <script>
 
-runGenericSensorOnerror(Accelerometer);
-runGenericSensorOnerror(GravitySensor);
-runGenericSensorOnerror(LinearAccelerationSensor);
+runGenericSensorOnerror('Accelerometer');
+runGenericSensorOnerror('GravitySensor');
+runGenericSensorOnerror('LinearAccelerationSensor');
 
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/generic-sensor/README.md
@@ -0,0 +1,20 @@
+The `generic-sensor-tests.js` tests require an implementation of
+the `GenericSensorTest` interface, which should emulate platform
+sensor backends. The `GenericSensorTest` interface is defined as:
+
+```
+  class GenericSensorTest {
+    async initialize();  // Sets up the testing enviroment.
+    async reset(); // Frees the resources.
+  };
+```
+
+The Chromium implementation of the `GenericSensorTest` interface is located in
+[generic_sensor_mocks.js](../resources/chromium/generic_sensor_mocks.js).
+
+Other browser vendors should provide their own implementations of
+the `GenericSensorTest` interface.
+
+[Known issue](https://github.com/w3c/web-platform-tests/issues/9686): a
+WebDriver extension is a better approach for the Generic Sensor tests
+automation.
--- a/testing/web-platform/tests/generic-sensor/generic-sensor-feature-policy-test.sub.js
+++ b/testing/web-platform/tests/generic-sensor/generic-sensor-feature-policy-test.sub.js
@@ -12,148 +12,159 @@ const feature_policies = {
 };
 
 const same_origin_src =
   "/feature-policy/resources/feature-policy-generic-sensor.html#";
 const cross_origin_src =
   "https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src;
 const base_src = "/feature-policy/resources/redirect-on-load.html#";
 
-function run_fp_tests_disabled(sensorType) {
-  const sensorName = sensorType.name;
+function run_fp_tests_disabled(sensorName) {
+  const sensorType = self[sensorName];
   const featureNameList = feature_policies[sensorName];
   const header = "Feature-Policy header " + featureNameList.join(" 'none';") + " 'none'";
   const desc = "'new " + sensorName + "()'";
 
   test(() => {
+    assert_true(sensorName in self);
     assert_throws("SecurityError", () => {new sensorType()});
   }, `${sensorName}: ${header} disallows the top-level document.`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       same_origin_src + sensorName,
       expect_feature_unavailable_default
     );
   }, `${sensorName}: ${header} disallows same-origin iframes.`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       cross_origin_src + sensorName,
       expect_feature_unavailable_default
     );
   }, `${sensorName}: ${header} disallows cross-origin iframes.`);
 }
 
-function run_fp_tests_enabled(sensorType) {
-  const sensorName = sensorType.name;
+function run_fp_tests_enabled(sensorName) {
+  const sensorType = self[sensorName];
   const featureNameList = feature_policies[sensorName];
   const header = "Feature-Policy header " + featureNameList.join(" *;") + " *";
   const desc = "'new " + sensorName + "()'";
 
   test(() => {
-    assert_true(sensorName in window);
+    assert_true(sensorName in self);
   }, `${sensorName}: ${header} allows the top-level document.`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       same_origin_src + sensorName,
       expect_feature_available_default
     );
   }, `${sensorName}: ${header} allows same-origin iframes.`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       cross_origin_src + sensorName,
       expect_feature_available_default
     );
   }, `${sensorName}: ${header} allows cross-origin iframes.`);
 }
 
-function run_fp_tests_enabled_by_attribute(sensorType) {
-  const sensorName = sensorType.name;
+function run_fp_tests_enabled_by_attribute(sensorName) {
+  const sensorType = self[sensorName];
   const featureNameList = feature_policies[sensorName];
   const header = "Feature-Policy allow='" + featureNameList.join(" ") + "' attribute";
   const desc = "'new " + sensorName + "()'";
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       same_origin_src + sensorName,
       expect_feature_available_default,
       featureNameList.join(";")
     );
   }, `${sensorName}: ${header} allows same-origin iframe`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       cross_origin_src + sensorName,
       expect_feature_available_default,
       featureNameList.join(";")
     );
   }, `${sensorName}: ${header} allows cross-origin iframe`);
 }
 
-function run_fp_tests_enabled_by_attribute_redirect_on_load(sensorType) {
-  const sensorName = sensorType.name;
+function run_fp_tests_enabled_by_attribute_redirect_on_load(sensorName) {
+  const sensorType = self[sensorName];
   const featureNameList = feature_policies[sensorName];
   const header = "Feature-Policy allow='" + featureNameList.join(" ") + "' attribute";
   const desc = "'new " + sensorName + "()'";
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       base_src + same_origin_src + sensorName,
       expect_feature_available_default,
       featureNameList.join(";")
     );
   }, `${sensorName}: ${header} allows same-origin relocation`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       base_src + cross_origin_src + sensorName,
       expect_feature_unavailable_default,
       featureNameList.join(";")
     );
   }, `${sensorName}: ${header} disallows cross-origin relocation`);
 }
 
-function run_fp_tests_enabled_on_self_origin(sensorType) {
-  const sensorName = sensorType.name;
+function run_fp_tests_enabled_on_self_origin(sensorName) {
+  const sensorType = self[sensorName];
   const featureNameList = feature_policies[sensorName];
   const header = "Feature-Policy header " + featureNameList.join(" 'self';") + " 'self'";
   const desc = "'new " + sensorName + "()'";
 
   test(() => {
-    assert_true(sensorName in window);
+    assert_true(sensorName in self);
   }, `${sensorName}: ${header} allows the top-level document.`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       same_origin_src + sensorName,
       expect_feature_available_default
     );
   }, `${sensorName}: ${header} allows same-origin iframes.`);
 
   async_test(t => {
+    assert_true(sensorName in self);
     test_feature_availability(
       desc,
       t,
       cross_origin_src + sensorName,
       expect_feature_unavailable_default
     );
   }, `${sensorName}: ${header} disallows cross-origin iframes.`);
 }
--- a/testing/web-platform/tests/generic-sensor/generic-sensor-tests.js
+++ b/testing/web-platform/tests/generic-sensor/generic-sensor-tests.js
@@ -1,8 +1,59 @@
+// These tests rely on the User Agent providing an implementation of
+// platform sensor backends.
+//
+// In Chromium-based browsers this implementation is provided by a polyfill
+// in order to reduce the amount of test-only code shipped to users. To enable
+// these tests the browser must be run with these options:
+//
+//   --enable-blink-features=MojoJS,MojoJSTest
+let loadChromiumResources = Promise.resolve().then(() => {
+  if (!MojoInterfaceInterceptor) {
+    // Do nothing on non-Chromium-based browsers or when the Mojo bindings are
+    // not present in the global namespace.
+    return;
+  }
+
+  let chain = Promise.resolve();
+  [
+    '/resources/chromium/mojo_bindings.js',
+    '/resources/chromium/string16.mojom.js',
+    '/resources/chromium/sensor.mojom.js',
+    '/resources/chromium/sensor_provider.mojom.js',
+    '/resources/chromium/generic_sensor_mocks.js',
+  ].forEach(path => {
+    let script = document.createElement('script');
+    script.src = path;
+    script.async = false;
+    chain = chain.then(() => new Promise(resolve => {
+      script.onload = resolve;
+    }));
+    document.head.appendChild(script);
+  });
+
+  return chain;
+});
+
+function sensor_test(func, name, properties) {
+  promise_test(async (t) => {
+    if (typeof GenericSensorTest === 'undefined') {
+      await loadChromiumResources;
+    }
+    assert_true(typeof GenericSensorTest !== 'undefined');
+    let sensorTest = new GenericSensorTest();
+    await sensorTest.initialize();
+    try {
+      await func(t);
+    } finally {
+      await sensorTest.reset();
+    };
+  }, name, properties);
+}
+
 const properties = {
   'AmbientLightSensor' : ['timestamp', 'illuminance'],
   'Accelerometer' : ['timestamp', 'x', 'y', 'z'],
   'LinearAccelerationSensor' : ['timestamp', 'x', 'y', 'z'],
   "GravitySensor" : ['timestamp', 'x', 'y', 'z'],
   'Gyroscope' : ['timestamp', 'x', 'y', 'z'],
   'Magnetometer' : ['timestamp', 'x', 'y', 'z'],
   "UncalibratedMagnetometer" : ['timestamp', 'x', 'y', 'z',
@@ -40,32 +91,36 @@ function reading_to_array(sensor) {
   const arr = new Array();
   for (let property in properties[sensor.constructor.name]) {
     let propertyName = properties[sensor.constructor.name][property];
     arr[property] = sensor[propertyName];
   }
   return arr;
 }
 
-function runGenericSensorTests(sensorType) {
-  promise_test(async t => {
+function runGenericSensorTests(sensorName) {
+  const sensorType = self[sensorName];
+
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
     sensor.start();
 
     await sensorWatcher.wait_for("reading");
     assert_reading_not_null(sensor);
     assert_true(sensor.hasReading);
 
     sensor.stop();
     assert_reading_null(sensor);
     assert_false(sensor.hasReading);
-  }, `${sensorType.name}: Test that 'onreading' is called and sensor reading is valid`);
+  }, `${sensorName}: Test that 'onreading' is called and sensor reading is valid`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor1 = new sensorType();
     const sensor2 = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor1, ["reading", "error"]);
     sensor2.start();
     sensor1.start();
 
     await sensorWatcher.wait_for("reading");
     // Reading values are correct for both sensors.
@@ -74,128 +129,137 @@ function runGenericSensorTests(sensorTyp
 
     //After first sensor stops its reading values are null,
     //reading values for the second sensor remains
     sensor1.stop();
     assert_reading_null(sensor1);
     assert_reading_not_null(sensor2);
     sensor2.stop();
     assert_reading_null(sensor2);
-  }, `${sensorType.name}: sensor reading is correct`);
+  }, `${sensorName}: sensor reading is correct`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
     sensor.start();
 
     await sensorWatcher.wait_for("reading");
     const cachedTimeStamp1 = sensor.timestamp;
 
     await sensorWatcher.wait_for("reading");
     const cachedTimeStamp2 = sensor.timestamp;
 
     assert_greater_than(cachedTimeStamp2, cachedTimeStamp1);
     sensor.stop();
-  }, `${sensorType.name}: sensor timestamp is updated when time passes`);
+  }, `${sensorName}: sensor timestamp is updated when time passes`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
     assert_false(sensor.activated);
     sensor.start();
     assert_false(sensor.activated);
 
     await sensorWatcher.wait_for("activate");
     assert_true(sensor.activated);
 
     sensor.stop();
     assert_false(sensor.activated);
-  }, `${sensorType.name}: Test that sensor can be successfully created and its states are correct.`);
+  }, `${sensorName}: Test that sensor can be successfully created and its states are correct.`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
     const start_return = sensor.start();
 
     await sensorWatcher.wait_for("activate");
     assert_equals(start_return, undefined);
     sensor.stop();
-  }, `${sensorType.name}: sensor.start() returns undefined`);
+  }, `${sensorName}: sensor.start() returns undefined`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
     sensor.start();
     sensor.start();
 
     await sensorWatcher.wait_for("activate");
     assert_true(sensor.activated);
     sensor.stop();
-  }, `${sensorType.name}: no exception is thrown when calling start() on already started sensor`);
+  }, `${sensorName}: no exception is thrown when calling start() on already started sensor`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
     sensor.start();
 
     await sensorWatcher.wait_for("activate");
     const stop_return = sensor.stop();
     assert_equals(stop_return, undefined);
-  }, `${sensorType.name}: sensor.stop() returns undefined`);
+  }, `${sensorName}: sensor.stop() returns undefined`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
     sensor.start();
 
     await sensorWatcher.wait_for("activate");
     sensor.stop();
     sensor.stop();
     assert_false(sensor.activated);
-  }, `${sensorType.name}: no exception is thrown when calling stop() on already stopped sensor`);
+  }, `${sensorName}: no exception is thrown when calling stop() on already stopped sensor`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
     sensor.start();
 
     await sensorWatcher.wait_for("reading");
     assert_true(sensor.hasReading);
     const timestamp = sensor.timestamp;
     sensor.stop();
     assert_false(sensor.hasReading);
 
     sensor.start();
     await sensorWatcher.wait_for("reading");
     assert_true(sensor.hasReading);
     assert_greater_than(timestamp, 0);
     assert_greater_than(sensor.timestamp, timestamp);
     sensor.stop();
-  }, `${sensorType.name}: Test that fresh reading is fetched on start()`);
+  }, `${sensorName}: Test that fresh reading is fetched on start()`);
 
-  promise_test(async t => {
-    const sensor = new sensorType();
-    const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
-    const visibilityChangeWatcher = new EventWatcher(t, document, "visibilitychange");
-    sensor.start();
+//  TBD file a WPT issue: visibilityChangeWatcher times out.
+//  sensor_test(async t => {
+//    const sensor = new sensorType();
+//    const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+//    const visibilityChangeWatcher = new EventWatcher(t, document, "visibilitychange");
+//    sensor.start();
 
-    await sensorWatcher.wait_for("reading");
-    assert_reading_not_null(sensor);
-    const cachedSensor1 = reading_to_array(sensor);
+//    await sensorWatcher.wait_for("reading");
+//    assert_reading_not_null(sensor);
+//    const cachedSensor1 = reading_to_array(sensor);
+
+//    const win = window.open('', '_blank');
+//    await visibilityChangeWatcher.wait_for("visibilitychange");
+//    const cachedSensor2 = reading_to_array(sensor);
 
-    const win = window.open('', '_blank');
-    await visibilityChangeWatcher.wait_for("visibilitychange");
-    const cachedSensor2 = reading_to_array(sensor);
+//    win.close();
+//    sensor.stop();
+//    assert_object_equals(cachedSensor1, cachedSensor2);
+//  }, `${sensorName}: sensor readings can not be fired on the background tab`);
 
-    win.close();
-    sensor.stop();
-    assert_object_equals(cachedSensor1, cachedSensor2);
-  }, `${sensorType.name}: sensor readings can not be fired on the background tab`);
-
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const fastSensor = new sensorType({frequency: 30});
     const slowSensor = new sensorType({frequency: 5});
     slowSensor.start();
 
     const fastCounter = await new Promise((resolve, reject) => {
       let fastCounter = 0;
       let slowCounter = 0;
 
@@ -212,19 +276,20 @@ function runGenericSensorTests(sensorTyp
           resolve(fastCounter);
         }
       }
       fastSensor.onerror = reject;
       slowSensor.onerror = reject;
     });
     assert_greater_than(fastCounter, 2,
                         "Fast sensor overtakes the slow one");
-  }, `${sensorType.name}: frequency hint works`);
+  }, `${sensorName}: frequency hint works`);
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     // Create a focused editbox inside a cross-origin iframe,
     // sensor notification must suspend.
     const iframeSrc = 'data:text/html;charset=utf-8,<html><body>'
                     + '<input type="text" autofocus></body></html>';
     const iframe = document.createElement('iframe');
     iframe.src = encodeURI(iframeSrc);
 
     const sensor = new sensorType();
@@ -243,89 +308,95 @@ function runGenericSensorTests(sensorTyp
     assert_array_equals(cachedSensor1, cachedSensor2);
 
     iframe.remove();
     await sensorWatcher.wait_for("reading");
     const cachedSensor3 = reading_to_array(sensor);
     assert_greater_than(sensor.timestamp, cachedTimestamp);
 
     sensor.stop();
-  }, `${sensorType.name}: sensor receives suspend / resume notifications when\
+  }, `${sensorName}: sensor receives suspend / resume notifications when\
   cross-origin subframe is focused`);
 
+//  Re-enable after https://github.com/w3c/sensors/issues/361 is fixed.
+//  test(() => {
+//     assert_throws("NotSupportedError", () => { new sensorType({invalid: 1}) });
+//     assert_throws("NotSupportedError", () => { new sensorType({frequency: 60, invalid: 1}) });
+//     if (spatialSensors.indexOf(sensorName) == -1) {
+//       assert_throws("NotSupportedError", () => { new sensorType({referenceFrame: "screen"}) });
+//     }
+//  }, `${sensorName}: throw 'NotSupportedError' for an unsupported sensor option`);
+
   test(() => {
-     assert_throws("NotSupportedError", () => { new sensorType({invalid: 1}) });
-     assert_throws("NotSupportedError", () => { new sensorType({frequency: 60, invalid: 1}) });
-     if (spatialSensors.indexOf(sensorType.name) == -1) {
-       assert_throws("NotSupportedError", () => { new sensorType({referenceFrame: "screen"}) });
-     }
-  }, `${sensorType.name}: throw 'NotSupportedError' for an unsupported sensor option`);
-
-  test(() => {
+    assert_true(sensorName in self);
     const invalidFreqs = [
       "invalid",
       NaN,
       Infinity,
       -Infinity,
       {},
       undefined
     ];
     invalidFreqs.map(freq => {
       assert_throws(new TypeError(),
                     () => { new sensorType({frequency: freq}) },
                     `when freq is ${freq}`);
     });
-  }, `${sensorType.name}: throw 'TypeError' if frequency is invalid`);
+  }, `${sensorName}: throw 'TypeError' if frequency is invalid`);
 
-  if (spatialSensors.indexOf(sensorType.name) == -1) {
+  if (spatialSensors.indexOf(sensorName) == -1) {
     // The sensorType does not represent a spatial sensor.
     return;
   }
 
-  promise_test(async t => {
+  sensor_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType({referenceFrame: "screen"});
     const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
     sensor.start();
 
     await sensorWatcher.wait_for("reading");
     //TODO use mock data to verify sensor readings, blocked by issue:
     // https://github.com/w3c/web-platform-tests/issues/9686
     assert_reading_not_null(sensor);
 
     sensor.stop();
-  }, `${sensorType.name}: sensor reading is correct when options.referenceFrame is 'screen'`);
+  }, `${sensorName}: sensor reading is correct when options.referenceFrame is 'screen'`);
 
   test(() => {
+    assert_true(sensorName in self);
     const invalidRefFrames = [
       "invalid",
       null,
       123,
       {},
       "",
-      true,
-      undefined
+      true
     ];
     invalidRefFrames.map(refFrame => {
       assert_throws(new TypeError(),
                     () => { new sensorType({referenceFrame: refFrame}) },
                     `when refFrame is ${refFrame}`);
     });
-  }, `${sensorType.name}: throw 'TypeError' if referenceFrame is not one of enumeration values`);
+  }, `${sensorName}: throw 'TypeError' if referenceFrame is not one of enumeration values`);
 }
 
-function runGenericSensorInsecureContext(sensorType) {
+function runGenericSensorInsecureContext(sensorName) {
   test(() => {
-    assert_false(sensorType in window, `${sensorType} must not be exposed`);
-  }, `${sensorType} is not exposed in an insecure context`);
+    assert_false(sensorName in window, `${sensorName} must not be exposed`);
+  }, `${sensorName} is not exposed in an insecure context`);
 }
 
-function runGenericSensorOnerror(sensorType) {
+function runGenericSensorOnerror(sensorName) {
+  const sensorType = self[sensorName];
+
   promise_test(async t => {
+    assert_true(sensorName in self);
     const sensor = new sensorType();
     const sensorWatcher = new EventWatcher(t, sensor, ["error", "activate"]);
     sensor.start();
 
     const event = await sensorWatcher.wait_for("error");
     assert_false(sensor.activated);
     assert_true(event.error.name == 'NotReadableError' ||
                 event.error.name == 'NotAllowedError');
-  }, `${sensorType.name}: 'onerror' event is fired when sensor is not supported`);
+  }, `${sensorName}: 'onerror' event is fired when sensor is not supported`);
 }
--- a/testing/web-platform/tests/gyroscope/Gyroscope-disabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope-disabled-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>Gyroscope Feature Policy Test: Disabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_disabled(Gyroscope);
+run_fp_tests_disabled('Gyroscope');
 </script>
 </body>
--- a/testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy-attribute-redirect-on-load.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy-attribute-redirect-on-load.https.html
@@ -3,11 +3,11 @@
 <title>Gyroscope Feature Policy Test: Enabled by attribute redirect on load</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute_redirect_on_load(Gyroscope);
+run_fp_tests_enabled_by_attribute_redirect_on_load('Gyroscope');
 </script>
 </body>
--- a/testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy-attribute.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy-attribute.https.html
@@ -3,11 +3,11 @@
 <title>Gyroscope Feature Policy Test: Enabled by attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute(Gyroscope);
+run_fp_tests_enabled_by_attribute('Gyroscope');
 </script>
 </body>
--- a/testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope-enabled-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>Gyroscope Feature Policy Test: Enabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled(Gyroscope);
+run_fp_tests_enabled('Gyroscope');
 </script>
 </body>
--- a/testing/web-platform/tests/gyroscope/Gyroscope-enabled-on-self-origin-by-feature-policy.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope-enabled-on-self-origin-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>Gyroscope Feature Policy Test: Enabled on self origin</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_on_self_origin(Gyroscope);
+run_fp_tests_enabled_on_self_origin('Gyroscope');
 </script>
 </body>
--- a/testing/web-platform/tests/gyroscope/Gyroscope.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope.https.html
@@ -4,11 +4,11 @@
 <link rel="author" title="Intel" href="http://www.intel.com">
 <link rel="help" href="https://www.w3.org/TR/gyroscope/">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/generic-sensor/generic-sensor-tests.js"></script>
 <div id="log"></div>
 <script>
 
-runGenericSensorTests(Gyroscope);
+runGenericSensorTests('Gyroscope');
 
 </script>
--- a/testing/web-platform/tests/gyroscope/Gyroscope_onerror-manual.https.html
+++ b/testing/web-platform/tests/gyroscope/Gyroscope_onerror-manual.https.html
@@ -10,11 +10,11 @@
 <h2>Precondition</h2>
 <ol>
   <li>
     Disable the Gyroscope Sensor or run test on a device without Gyroscope Sensor.
   </li>
 </ol>
 <script>
 
-runGenericSensorOnerror(Gyroscope);
+runGenericSensorOnerror('Gyroscope');
 
 </script>
--- a/testing/web-platform/tests/lint.whitelist
+++ b/testing/web-platform/tests/lint.whitelist
@@ -766,16 +766,17 @@ MISSING-LINK: css/cssom-view/scrollIntoV
 MISSING-LINK: css/cssom-view/scrollTop-display-change.html
 
 # TODO https://github.com/w3c/web-platform-tests/issues/5770
 MISSING-LINK: css/geometry/*.worker.js
 MISSING-LINK: css/filter-effects/*.any.js
 
 # Tests that use WebKit/Blink testing APIs
 LAYOUTTESTS APIS: css/css-regions/interactivity/*
+LAYOUTTESTS APIS: resources/chromium/generic_sensor_mocks.js
 
 # Existing use of WEB-PLATFORM.TEST
 WEB-PLATFORM.TEST: clear-site-data/support/test_utils.sub.js
 WEB-PLATFORM.TEST: content-security-policy/base-uri/report-uri-does-not-respect-base-uri.sub.html
 WEB-PLATFORM.TEST: content-security-policy/generic/generic-0_8.sub.html
 WEB-PLATFORM.TEST: content-security-policy/generic/generic-0_8_1.sub.html
 WEB-PLATFORM.TEST: content-security-policy/nonce-hiding/script-nonces-hidden-meta.tentative.html
 WEB-PLATFORM.TEST: content-security-policy/nonce-hiding/svgscript-nonces-hidden-meta.tentative.html
--- a/testing/web-platform/tests/magnetometer/Magnetometer-disabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer-disabled-by-feature-policy.https.html
@@ -3,12 +3,12 @@
 <title>Magnetometer Feature Policy Test: Disabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_disabled(Magnetometer);
-run_fp_tests_disabled(UncalibratedMagnetometer);
+run_fp_tests_disabled('Magnetometer');
+run_fp_tests_disabled('UncalibratedMagnetometer');
 </script>
 </body>
--- a/testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy-attribute-redirect-on-load.https.html
@@ -3,12 +3,12 @@
 <title>Magnetometer Feature Policy Test: Enabled by attribute redirect on load</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute_redirect_on_load(Magnetometer);
-run_fp_tests_enabled_by_attribute_redirect_on_load(UncalibratedMagnetometer);
+run_fp_tests_enabled_by_attribute_redirect_on_load('Magnetometer');
+run_fp_tests_enabled_by_attribute_redirect_on_load('UncalibratedMagnetometer');
 </script>
 </body>
--- a/testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy-attribute.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy-attribute.https.html
@@ -3,12 +3,12 @@
 <title>Magnetometer Feature Policy Test: Enabled by attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute(Magnetometer);
-run_fp_tests_enabled_by_attribute(UncalibratedMagnetometer);
+run_fp_tests_enabled_by_attribute('Magnetometer');
+run_fp_tests_enabled_by_attribute('UncalibratedMagnetometer');
 </script>
 </body>
--- a/testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer-enabled-by-feature-policy.https.html
@@ -3,12 +3,12 @@
 <title>Magnetometer Feature Policy Test: Enabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled(Magnetometer);
-run_fp_tests_enabled(UncalibratedMagnetometer);
+run_fp_tests_enabled('Magnetometer');
+run_fp_tests_enabled('UncalibratedMagnetometer');
 </script>
 </body>
--- a/testing/web-platform/tests/magnetometer/Magnetometer-enabled-on-self-origin-by-feature-policy.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer-enabled-on-self-origin-by-feature-policy.https.html
@@ -3,12 +3,12 @@
 <title>Magnetometer Feature Policy Test: Enabled on self origin</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_on_self_origin(Magnetometer);
-run_fp_tests_enabled_on_self_origin(UncalibratedMagnetometer);
+run_fp_tests_enabled_on_self_origin('Magnetometer');
+run_fp_tests_enabled_on_self_origin('UncalibratedMagnetometer');
 </script>
 </body>
--- a/testing/web-platform/tests/magnetometer/Magnetometer.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer.https.html
@@ -4,12 +4,12 @@
 <link rel="author" title="Intel" href="http://www.intel.com">
 <link rel="help" href="https://www.w3.org/TR/magnetometer/">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/generic-sensor/generic-sensor-tests.js"></script>
 <div id="log"></div>
 <script>
 
-runGenericSensorTests(Magnetometer);
-runGenericSensorTests(UncalibratedMagnetometer);
+runGenericSensorTests('Magnetometer');
+runGenericSensorTests('UncalibratedMagnetometer');
 
 </script>
--- a/testing/web-platform/tests/magnetometer/Magnetometer_onerror-manual.https.html
+++ b/testing/web-platform/tests/magnetometer/Magnetometer_onerror-manual.https.html
@@ -10,12 +10,12 @@
 <h2>Precondition</h2>
 <ol>
   <li>
     Disable the Magnetometer Sensor or run test on a device without Magnetometer Sensor.
   </li>
 </ol>
 <script>
 
-runGenericSensorOnerror(Magnetometer);
-runGenericSensorOnerror(UncalibratedMagnetometer);
+runGenericSensorOnerror('Magnetometer');
+runGenericSensorOnerror('UncalibratedMagnetometer');
 
 </script>
--- a/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-disabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-disabled-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>AbsoluteOrientationSensor Feature Policy Test: Disabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_disabled(AbsoluteOrientationSensor);
+run_fp_tests_disabled('AbsoluteOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html
+++ b/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html
@@ -3,11 +3,11 @@
 <title>AbsoluteOrientationSensor Feature Policy Test: Enabled by attribute redirect on load</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute_redirect_on_load(AbsoluteOrientationSensor);
+run_fp_tests_enabled_by_attribute_redirect_on_load('AbsoluteOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute.https.html
+++ b/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy-attribute.https.html
@@ -3,11 +3,11 @@
 <title>AbsoluteOrientationSensor Feature Policy Test: Enabled by attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute(AbsoluteOrientationSensor);
+run_fp_tests_enabled_by_attribute('AbsoluteOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>AbsoluteOrientationSensor Feature Policy Test: Enabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled(AbsoluteOrientationSensor);
+run_fp_tests_enabled('AbsoluteOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html
+++ b/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>AbsoluteOrientationSensor Feature Policy Test: Enabled on self origin</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_on_self_origin(AbsoluteOrientationSensor);
+run_fp_tests_enabled_on_self_origin('AbsoluteOrientationSensor');
 </script>
 </body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/orientation-sensor/AbsoluteOrientationSensor.https.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OrientationSensor Test</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://w3c.github.io/orientation-sensor/">
+<link rel="help" href="https://w3c.github.io/sensors/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="/orientation-sensor/orientation-sensor-tests.js"></script>
+<div id="log"></div>
+
+<script>
+runOrienationSensorTests('AbsoluteOrientationSensor');
+runGenericSensorTests('AbsoluteOrientationSensor');
+</script>
deleted file mode 100644
--- a/testing/web-platform/tests/orientation-sensor/OrientationSensor.https.html
+++ /dev/null
@@ -1,102 +0,0 @@
- <!DOCTYPE html>
-<meta charset="utf-8">
-<title>OrientationSensor Test</title>
-<link rel="author" title="Intel" href="http://www.intel.com">
-<link rel="help" href="https://w3c.github.io/orientation-sensor/">
-<link rel="help" href="https://w3c.github.io/sensors/">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/generic-sensor/generic-sensor-tests.js"></script>
-<div id="log"></div>
-
-<script>
-
-//IEEE 754: single precision retricts to 7 decimal digits
-const float_precision = 1e-7;
-
-function create_matrix(quat) {
-  const X = quat[0];
-  const Y = quat[1];
-  const Z = quat[2];
-  const W = quat[3];
-  const mat = new Array(
-    1-2*Y*Y-2*Z*Z, 2*X*Y-2*Z*W, 2*X*Z+2*Y*W, 0,
-    2*X*Y+2*Z*W, 1-2*X*X-2*Z*Z, 2*Y*Z-2*X*W, 0,
-    2*X*Z-2*Y*W, 2*Y*Z+2*W*X, 1-2*X*X-2*Y*Y, 0,
-    0, 0, 0, 1
-  );
-  return mat;
-}
-
-async function checkQuaternion(t, sensorType) {
-  const sensor = new sensorType();
-  const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
-  sensor.start();
-
-  await eventWatcher.wait_for("reading");
-  assert_equals(sensor.quaternion.length, 4);
-  assert_true(sensor.quaternion instanceof Array);
-  sensor.stop();
-};
-
-async function checkPopulateMatrix(t, sensorType) {
-  const sensor = new sensorType();
-  const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
-
-  //Throws with insufficient buffer space.
-  assert_throws({ name: 'TypeError' }, () => sensor.populateMatrix(new Float32Array(15)));
-
-  //Throws if no orientation data available.
-  assert_throws({ name: 'NotReadableError' }, () => sensor.populateMatrix(new Float32Array(16)));
-
-  if (window.SharedArrayBuffer) {
-    // Throws if passed SharedArrayBuffer view.
-    assert_throws({ name: 'TypeError' }, () => sensor.populateMatrix(new Float32Array(new SharedArrayBuffer(16))));
-  }
-
-  sensor.start();
-  await eventWatcher.wait_for("reading");
-  const quat = sensor.quaternion;
-  const mat_expect = create_matrix(quat);
-
-  // Works for all supported types.
-  const mat_32 = new Float32Array(16);
-  sensor.populateMatrix(mat_32);
-  assert_array_approx_equals(mat_32, mat_expect, float_precision);
-
-  const mat_64 = new Float64Array(16);
-  sensor.populateMatrix(mat_64);
-  assert_array_equals(mat_64, mat_expect);
-
-  const mat_dom = new DOMMatrix();
-  sensor.populateMatrix(mat_dom);
-  assert_array_equals(mat_dom.toFloat64Array(), mat_expect);
-
-  // Sets every matrix element.
-  mat_64.fill(123);
-  sensor.populateMatrix(mat_64);
-  assert_array_equals(mat_64, mat_expect);
-
-  sensor.stop();
-}
-
-promise_test(t => {
-  return checkQuaternion(t, AbsoluteOrientationSensor);
-}, "Test AbsoluteOrientationSensor.quaternion return a four-element FrozenArray.");
-
-promise_test(t => {
-  return checkQuaternion(t, RelativeOrientationSensor);
-}, "Test RelativeOrientationSensor.quaternion return a four-element FrozenArray.");
-
-promise_test(t => {
-  return checkPopulateMatrix(t, AbsoluteOrientationSensor);
-}, "Test AbsoluteOrientationSensor.populateMatrix() method works correctly.");
-
-promise_test(t => {
-  return checkPopulateMatrix(t, RelativeOrientationSensor);
-}, "Test RelativeOrientationSensor.populateMatrix() method works correctly.");
-
-runGenericSensorTests(AbsoluteOrientationSensor);
-runGenericSensorTests(RelativeOrientationSensor);
-
-</script>
--- a/testing/web-platform/tests/orientation-sensor/OrientationSensor_onerror-manual.https.html
+++ b/testing/web-platform/tests/orientation-sensor/OrientationSensor_onerror-manual.https.html
@@ -11,12 +11,12 @@
 <h2>Precondition</h2>
 <ol>
   <li>
     Disable the motion sensors which the underlying physical sensors include Accelerometer, Magnetometer, and (when present) Gyroscope or run test on a device without the motion sensors.
   </li>
 </ol>
 <script>
 
-runGenericSensorOnerror(AbsoluteOrientationSensor);
-runGenericSensorOnerror(RelativeOrientationSensor);
+runGenericSensorOnerror('AbsoluteOrientationSensor');
+runGenericSensorOnerror('RelativeOrientationSensor');
 
 </script>
--- a/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-disabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-disabled-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>RelativeOrientationSensor Feature Policy Test: Disabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_disabled(RelativeOrientationSensor);
+run_fp_tests_disabled('RelativeOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html
+++ b/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute-redirect-on-load.https.html
@@ -3,11 +3,11 @@
 <title>RelativeOrientationSensor Feature Policy Test: Enabled by attribute redirect on load</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute_redirect_on_load(RelativeOrientationSensor);
+run_fp_tests_enabled_by_attribute_redirect_on_load('RelativeOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute.https.html
+++ b/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy-attribute.https.html
@@ -3,11 +3,11 @@
 <title>RelativeOrientationSensor Feature Policy Test: Enabled by attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_by_attribute(RelativeOrientationSensor);
+run_fp_tests_enabled_by_attribute('RelativeOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy.https.html
+++ b/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>RelativeOrientationSensor Feature Policy Test: Enabled</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled(RelativeOrientationSensor);
+run_fp_tests_enabled('RelativeOrientationSensor');
 </script>
 </body>
--- a/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html
+++ b/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor-enabled-on-self-origin-by-feature-policy.https.html
@@ -3,11 +3,11 @@
 <title>RelativeOrientationSensor Feature Policy Test: Enabled on self origin</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/feature-policy/resources/featurepolicy.js"></script>
 <script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
 <script>
 "use strict";
 
-run_fp_tests_enabled_on_self_origin(RelativeOrientationSensor);
+run_fp_tests_enabled_on_self_origin('RelativeOrientationSensor');
 </script>
 </body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/orientation-sensor/RelativeOrientationSensor.https.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OrientationSensor Test</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://w3c.github.io/orientation-sensor/">
+<link rel="help" href="https://w3c.github.io/sensors/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="/orientation-sensor/orientation-sensor-tests.js"></script>
+<div id="log"></div>
+
+<script>
+runOrienationSensorTests('RelativeOrientationSensor');
+runGenericSensorTests('RelativeOrientationSensor');
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/orientation-sensor/orientation-sensor-tests.js
@@ -0,0 +1,83 @@
+//IEEE 754: single precision retricts to 7 decimal digits
+const float_precision = 1e-7;
+
+function create_matrix(quat) {
+  const X = quat[0];
+  const Y = quat[1];
+  const Z = quat[2];
+  const W = quat[3];
+  const mat = new Array(
+    1-2*Y*Y-2*Z*Z, 2*X*Y-2*Z*W, 2*X*Z+2*Y*W, 0,
+    2*X*Y+2*Z*W, 1-2*X*X-2*Z*Z, 2*Y*Z-2*X*W, 0,
+    2*X*Z-2*Y*W, 2*Y*Z+2*W*X, 1-2*X*X-2*Y*Y, 0,
+    0, 0, 0, 1
+  );
+  return mat;
+}
+
+async function checkQuaternion(t, sensorType) {
+  const sensor = new sensorType();
+  const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+  sensor.start();
+
+  await eventWatcher.wait_for("reading");
+  assert_equals(sensor.quaternion.length, 4);
+  assert_true(sensor.quaternion instanceof Array);
+  sensor.stop();
+};
+
+async function checkPopulateMatrix(t, sensorType) {
+  const sensor = new sensorType();
+  const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+
+  //Throws with insufficient buffer space.
+  assert_throws({ name: 'TypeError' }, () => sensor.populateMatrix(new Float32Array(15)));
+
+  //Throws if no orientation data available.
+  assert_throws({ name: 'NotReadableError' }, () => sensor.populateMatrix(new Float32Array(16)));
+
+  if (window.SharedArrayBuffer) {
+    // Throws if passed SharedArrayBuffer view.
+    assert_throws({ name: 'TypeError' }, () => sensor.populateMatrix(new Float32Array(new SharedArrayBuffer(16))));
+  }
+
+  sensor.start();
+  await eventWatcher.wait_for("reading");
+  const quat = sensor.quaternion;
+  const mat_expect = create_matrix(quat);
+
+  // Works for all supported types.
+  const mat_32 = new Float32Array(16);
+  sensor.populateMatrix(mat_32);
+  assert_array_approx_equals(mat_32, mat_expect, float_precision);
+
+  const mat_64 = new Float64Array(16);
+  sensor.populateMatrix(mat_64);
+  assert_array_equals(mat_64, mat_expect);
+
+  const mat_dom = new DOMMatrix();
+  sensor.populateMatrix(mat_dom);
+  assert_array_equals(mat_dom.toFloat64Array(), mat_expect);
+
+  // Sets every matrix element.
+  mat_64.fill(123);
+  sensor.populateMatrix(mat_64);
+  assert_array_equals(mat_64, mat_expect);
+
+  sensor.stop();
+}
+
+function runOrienationSensorTests(sensorName) {
+  const sensorType = self[sensorName];
+
+  sensor_test(async t => {
+    assert_true(sensorName in self);
+    return checkQuaternion(t, sensorType);
+  }, `${sensorName}.quaternion return a four-element FrozenArray.`);
+
+  sensor_test(async t => {
+    assert_true(sensorName in self);
+    return checkPopulateMatrix(t, sensorType);
+  }, `${sensorName}.populateMatrix() method works correctly.`);
+}
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js
@@ -0,0 +1,226 @@
+'use strict';
+
+var GenericSensorTest = (() => {
+  // Class that mocks Sensor interface defined in
+  // https://cs.chromium.org/chromium/src/services/device/public/mojom/sensor.mojom
+  class MockSensor {
+    constructor(sensorRequest, handle, offset, size, reportingMode) {
+      this.client_ = null;
+      this.reportingMode_ = reportingMode;
+      this.sensorReadingTimerId_ = null;
+      this.requestedFrequencies_ = [];
+      let rv = handle.mapBuffer(offset, size);
+      assert_equals(rv.result, Mojo.RESULT_OK, "Failed to map shared buffer");
+      this.buffer_ = new Float64Array(rv.buffer);
+      this.buffer_.fill(0);
+      this.binding_ = new mojo.Binding(device.mojom.Sensor, this,
+                                       sensorRequest);
+      this.binding_.setConnectionErrorHandler(() => {
+        this.reset();
+      });
+    }
+
+    getDefaultConfiguration() {
+      return Promise.resolve({frequency: 5});
+    }
+
+    addConfiguration(configuration) {
+      assert_not_equals(configuration, null, "Invalid sensor configuration.");
+
+      this.requestedFrequencies_.push(configuration.frequency);
+      // Sort using descending order.
+      this.requestedFrequencies_.sort(
+          (first, second) => { return second - first });
+
+      this.startReading();
+
+      return Promise.resolve({success: true});
+    }
+
+    removeConfiguration(configuration) {
+      let index = this.requestedFrequencies_.indexOf(configuration.frequency);
+      if (index == -1)
+        return;
+
+      this.requestedFrequencies_.splice(index, 1);
+
+      if (this.isReading) {
+        this.stopReading();
+        if (this.requestedFrequencies_.length !== 0)
+          this.startReading();
+      }
+    }
+
+    suspend() {
+      this.stopReading();
+    }
+
+    resume() {
+      this.startReading();
+    }
+
+    reset() {
+      this.stopReading();
+      this.requestedFrequencies_ = [];
+      this.buffer_.fill(0);
+      this.binding_.close();
+    }
+
+    startReading() {
+      if (this.isReading) {
+        console.warn("Sensor reading is already started.");
+        return;
+      }
+
+      if (this.requestedFrequencies_.length == 0) {
+        console.warn("Sensor reading cannot be started as" +
+                     "there are no configurations added.");
+        return;
+      }
+
+      const maxFrequencyHz = this.requestedFrequencies_[0];
+      const timeoutMs = (1 / maxFrequencyHz) * 1000;
+      this.sensorReadingTimerId_ = window.setInterval(() => {
+        // For all tests sensor reading should have monotonically
+        // increasing timestamp in seconds.
+        this.buffer_[1] = window.performance.now() * 0.001;
+        if (this.reportingMode_ === device.mojom.ReportingMode.ON_CHANGE) {
+          this.client_.sensorReadingChanged();
+        }
+      }, timeoutMs);
+    }
+
+    stopReading() {
+      if (this.isReading) {
+        window.clearInterval(this.sensorReadingTimerId_);
+        this.sensorReadingTimerId_ = null;
+      }
+    }
+
+     get isReading() {
+       this.sensorReadingTimerId_ !== null;
+     }
+  }
+
+  // Class that mocks SensorProvider interface defined in
+  // https://cs.chromium.org/chromium/src/services/device/public/mojom/sensor_provider.mojom
+  class MockSensorProvider {
+    constructor() {
+      this.readingSizeInBytes_ =
+          device.mojom.SensorInitParams.kReadBufferSizeForTests;
+      this.sharedBufferSizeInBytes_ = this.readingSizeInBytes_ *
+              device.mojom.SensorType.LAST;
+      let rv = Mojo.createSharedBuffer(this.sharedBufferSizeInBytes_);
+      assert_equals(rv.result, Mojo.RESULT_OK, "Failed to create buffer");
+      this.sharedBufferHandle_ = rv.handle;
+      this.activeSensor_ = null;
+      this.isContinuous_ = false;
+      this.binding_ = new mojo.Binding(device.mojom.SensorProvider, this);
+
+      this.interceptor_ = new MojoInterfaceInterceptor(
+          device.mojom.SensorProvider.name);
+      this.interceptor_.oninterfacerequest = e => {
+        this.binding_.bind(e.handle);
+        this.binding_.setConnectionErrorHandler(() => {
+          console.error("Mojo connection error");
+          this.reset();
+        });
+      };
+      this.interceptor_.start();
+    }
+
+    async getSensor(type) {
+      const offset = (device.mojom.SensorType.LAST - type) *
+                      this.readingSizeInBytes_;
+      const reportingMode = device.mojom.ReportingMode.ON_CHANGE;
+
+      let sensorPtr = new device.mojom.SensorPtr();
+      if (this.activeSensor_ == null) {
+        let mockSensor = new MockSensor(
+            mojo.makeRequest(sensorPtr), this.sharedBufferHandle_, offset,
+            this.readingSizeInBytes_, reportingMode);
+        this.activeSensor_ = mockSensor;
+        this.activeSensor_.client_ = new device.mojom.SensorClientPtr();
+      }
+
+      let rv = this.sharedBufferHandle_.duplicateBufferHandle();
+
+      assert_equals(rv.result, Mojo.RESULT_OK);
+      let maxAllowedFrequencyHz = 60;
+      if (type == device.mojom.SensorType.AMBIENT_LIGHT ||
+          type == device.mojom.SensorType.MAGNETOMETER) {
+        maxAllowedFrequencyHz = 10;
+      }
+
+      let initParams = new device.mojom.SensorInitParams({
+        sensor: sensorPtr,
+        clientRequest: mojo.makeRequest(this.activeSensor_.client_),
+        memory: rv.handle,
+        bufferOffset: offset,
+        mode: reportingMode,
+        defaultConfiguration: {frequency: 5},
+        minimumFrequency: 1,
+        maximumFrequency: maxAllowedFrequencyHz
+      });
+
+      return {result: device.mojom.SensorCreationResult.SUCCESS,
+              initParams: initParams};
+    }
+
+    async reset() {
+      if (this.activeSensor_ !== null) {
+        this.activeSensor_.reset();
+        this.activeSensor_ = null;
+      }
+      // Wait for an event loop iteration to let
+      // the pending mojo commands pass.
+      function schedule(func) {
+        return new Promise(resolve => {
+          setTimeout(() => {
+            func();
+            resolve();
+          }, 0);
+        });
+      }
+      await schedule(this.binding_.close.bind(this.binding_));
+      await schedule(this.interceptor_.stop.bind(this.interceptor_));
+    }
+  }
+
+  let testInternal = {
+    initialized: false,
+    sensorProvider: null
+  }
+
+  class GenericSensorTestChromium {
+    constructor() {
+      Object.freeze(this); // Make it immutable.
+    }
+
+    initialize() {
+      if (testInternal.initialized)
+        throw new Error('Call reset() before initialize().');
+
+      if (testRunner) { // Grant sensor permissions for Chromium testrunner.
+        ['accelerometer', 'gyroscope',
+         'magnetometer', 'ambient-light-sensor'].forEach((entry) => {
+          testRunner.setPermission(entry, 'granted',
+                                   location.origin, location.origin);
+        });
+      }
+
+      testInternal.sensorProvider = new MockSensorProvider;
+      testInternal.initialized = true;
+    }
+    // Resets state of sensor mocks between test runs.
+    async reset() {
+      if (!testInternal.initialized)
+        throw new Error('Call initialize() before reset().');
+      await testInternal.sensorProvider.reset();
+      testInternal.sensorProvider = null;
+      testInternal.initialized = false;
+    }
+  }
+
+  return GenericSensorTestChromium;
+})();
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/resources/chromium/generic_sensor_mocks.js.headers
@@ -0,0 +1,1 @@
+Content-Type: text/javascript; charset=utf-8
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/resources/chromium/sensor.mojom.js
@@ -0,0 +1,1072 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+(function() {
+  var mojomId = 'services/device/public/mojom/sensor.mojom';
+  if (mojo.internal.isMojomLoaded(mojomId)) {
+    console.warn('The following mojom is loaded multiple times: ' + mojomId);
+    return;
+  }
+  mojo.internal.markMojomLoaded(mojomId);
+  var bindings = mojo;
+  var associatedBindings = mojo;
+  var codec = mojo.internal;
+  var validator = mojo.internal;
+
+  var exports = mojo.internal.exposeNamespace('device.mojom');
+
+
+  var SensorType = {};
+  SensorType.FIRST = 1;
+  SensorType.AMBIENT_LIGHT = SensorType.FIRST;
+  SensorType.PROXIMITY = SensorType.AMBIENT_LIGHT + 1;
+  SensorType.ACCELEROMETER = SensorType.PROXIMITY + 1;
+  SensorType.LINEAR_ACCELERATION = SensorType.ACCELEROMETER + 1;
+  SensorType.GYROSCOPE = SensorType.LINEAR_ACCELERATION + 1;
+  SensorType.MAGNETOMETER = SensorType.GYROSCOPE + 1;
+  SensorType.PRESSURE = SensorType.MAGNETOMETER + 1;
+  SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES = SensorType.PRESSURE + 1;
+  SensorType.ABSOLUTE_ORIENTATION_QUATERNION = SensorType.ABSOLUTE_ORIENTATION_EULER_ANGLES + 1;
+  SensorType.RELATIVE_ORIENTATION_EULER_ANGLES = SensorType.ABSOLUTE_ORIENTATION_QUATERNION + 1;
+  SensorType.RELATIVE_ORIENTATION_QUATERNION = SensorType.RELATIVE_ORIENTATION_EULER_ANGLES + 1;
+  SensorType.LAST = SensorType.RELATIVE_ORIENTATION_QUATERNION;
+
+  SensorType.isKnownEnumValue = function(value) {
+    switch (value) {
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+      return true;
+    }
+    return false;
+  };
+
+  SensorType.validate = function(enumValue) {
+    var isExtensible = false;
+    if (isExtensible || this.isKnownEnumValue(enumValue))
+      return validator.validationError.NONE;
+
+    return validator.validationError.UNKNOWN_ENUM_VALUE;
+  };
+  var ReportingMode = {};
+  ReportingMode.ON_CHANGE = 0;
+  ReportingMode.CONTINUOUS = ReportingMode.ON_CHANGE + 1;
+
+  ReportingMode.isKnownEnumValue = function(value) {
+    switch (value) {
+    case 0:
+    case 1:
+      return true;
+    }
+    return false;
+  };
+
+  ReportingMode.validate = function(enumValue) {
+    var isExtensible = false;
+    if (isExtensible || this.isKnownEnumValue(enumValue))
+      return validator.validationError.NONE;
+
+    return validator.validationError.UNKNOWN_ENUM_VALUE;
+  };
+
+  function SensorConfiguration(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  SensorConfiguration.prototype.initDefaults_ = function() {
+    this.frequency = 0;
+  };
+  SensorConfiguration.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  SensorConfiguration.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    return validator.validationError.NONE;
+  };
+
+  SensorConfiguration.encodedSize = codec.kStructHeaderSize + 8;
+
+  SensorConfiguration.decode = function(decoder) {
+    var packed;
+    var val = new SensorConfiguration();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.frequency = decoder.decodeStruct(codec.Double);
+    return val;
+  };
+
+  SensorConfiguration.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(SensorConfiguration.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStruct(codec.Double, val.frequency);
+  };
+  function Sensor_GetDefaultConfiguration_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_GetDefaultConfiguration_Params.prototype.initDefaults_ = function() {
+  };
+  Sensor_GetDefaultConfiguration_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_GetDefaultConfiguration_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 8}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_GetDefaultConfiguration_Params.encodedSize = codec.kStructHeaderSize + 0;
+
+  Sensor_GetDefaultConfiguration_Params.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_GetDefaultConfiguration_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    return val;
+  };
+
+  Sensor_GetDefaultConfiguration_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_GetDefaultConfiguration_Params.encodedSize);
+    encoder.writeUint32(0);
+  };
+  function Sensor_GetDefaultConfiguration_ResponseParams(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_GetDefaultConfiguration_ResponseParams.prototype.initDefaults_ = function() {
+    this.configuration = null;
+  };
+  Sensor_GetDefaultConfiguration_ResponseParams.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_GetDefaultConfiguration_ResponseParams.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate Sensor_GetDefaultConfiguration_ResponseParams.configuration
+    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SensorConfiguration, false);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_GetDefaultConfiguration_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
+
+  Sensor_GetDefaultConfiguration_ResponseParams.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_GetDefaultConfiguration_ResponseParams();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.configuration = decoder.decodeStructPointer(SensorConfiguration);
+    return val;
+  };
+
+  Sensor_GetDefaultConfiguration_ResponseParams.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_GetDefaultConfiguration_ResponseParams.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStructPointer(SensorConfiguration, val.configuration);
+  };
+  function Sensor_AddConfiguration_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_AddConfiguration_Params.prototype.initDefaults_ = function() {
+    this.configuration = null;
+  };
+  Sensor_AddConfiguration_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_AddConfiguration_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate Sensor_AddConfiguration_Params.configuration
+    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SensorConfiguration, false);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_AddConfiguration_Params.encodedSize = codec.kStructHeaderSize + 8;
+
+  Sensor_AddConfiguration_Params.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_AddConfiguration_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.configuration = decoder.decodeStructPointer(SensorConfiguration);
+    return val;
+  };
+
+  Sensor_AddConfiguration_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_AddConfiguration_Params.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStructPointer(SensorConfiguration, val.configuration);
+  };
+  function Sensor_AddConfiguration_ResponseParams(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_AddConfiguration_ResponseParams.prototype.initDefaults_ = function() {
+    this.success = false;
+  };
+  Sensor_AddConfiguration_ResponseParams.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_AddConfiguration_ResponseParams.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_AddConfiguration_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
+
+  Sensor_AddConfiguration_ResponseParams.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_AddConfiguration_ResponseParams();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    packed = decoder.readUint8();
+    val.success = (packed >> 0) & 1 ? true : false;
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    return val;
+  };
+
+  Sensor_AddConfiguration_ResponseParams.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_AddConfiguration_ResponseParams.encodedSize);
+    encoder.writeUint32(0);
+    packed = 0;
+    packed |= (val.success & 1) << 0
+    encoder.writeUint8(packed);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+  };
+  function Sensor_RemoveConfiguration_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_RemoveConfiguration_Params.prototype.initDefaults_ = function() {
+    this.configuration = null;
+  };
+  Sensor_RemoveConfiguration_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_RemoveConfiguration_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate Sensor_RemoveConfiguration_Params.configuration
+    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SensorConfiguration, false);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_RemoveConfiguration_Params.encodedSize = codec.kStructHeaderSize + 8;
+
+  Sensor_RemoveConfiguration_Params.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_RemoveConfiguration_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.configuration = decoder.decodeStructPointer(SensorConfiguration);
+    return val;
+  };
+
+  Sensor_RemoveConfiguration_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_RemoveConfiguration_Params.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStructPointer(SensorConfiguration, val.configuration);
+  };
+  function Sensor_Suspend_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_Suspend_Params.prototype.initDefaults_ = function() {
+  };
+  Sensor_Suspend_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_Suspend_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 8}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_Suspend_Params.encodedSize = codec.kStructHeaderSize + 0;
+
+  Sensor_Suspend_Params.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_Suspend_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    return val;
+  };
+
+  Sensor_Suspend_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_Suspend_Params.encodedSize);
+    encoder.writeUint32(0);
+  };
+  function Sensor_Resume_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_Resume_Params.prototype.initDefaults_ = function() {
+  };
+  Sensor_Resume_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_Resume_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 8}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_Resume_Params.encodedSize = codec.kStructHeaderSize + 0;
+
+  Sensor_Resume_Params.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_Resume_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    return val;
+  };
+
+  Sensor_Resume_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_Resume_Params.encodedSize);
+    encoder.writeUint32(0);
+  };
+  function Sensor_ConfigureReadingChangeNotifications_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  Sensor_ConfigureReadingChangeNotifications_Params.prototype.initDefaults_ = function() {
+    this.enabled = false;
+  };
+  Sensor_ConfigureReadingChangeNotifications_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  Sensor_ConfigureReadingChangeNotifications_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    return validator.validationError.NONE;
+  };
+
+  Sensor_ConfigureReadingChangeNotifications_Params.encodedSize = codec.kStructHeaderSize + 8;
+
+  Sensor_ConfigureReadingChangeNotifications_Params.decode = function(decoder) {
+    var packed;
+    var val = new Sensor_ConfigureReadingChangeNotifications_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    packed = decoder.readUint8();
+    val.enabled = (packed >> 0) & 1 ? true : false;
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    return val;
+  };
+
+  Sensor_ConfigureReadingChangeNotifications_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(Sensor_ConfigureReadingChangeNotifications_Params.encodedSize);
+    encoder.writeUint32(0);
+    packed = 0;
+    packed |= (val.enabled & 1) << 0
+    encoder.writeUint8(packed);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+  };
+  function SensorClient_RaiseError_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  SensorClient_RaiseError_Params.prototype.initDefaults_ = function() {
+  };
+  SensorClient_RaiseError_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  SensorClient_RaiseError_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 8}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  SensorClient_RaiseError_Params.encodedSize = codec.kStructHeaderSize + 0;
+
+  SensorClient_RaiseError_Params.decode = function(decoder) {
+    var packed;
+    var val = new SensorClient_RaiseError_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    return val;
+  };
+
+  SensorClient_RaiseError_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(SensorClient_RaiseError_Params.encodedSize);
+    encoder.writeUint32(0);
+  };
+  function SensorClient_SensorReadingChanged_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  SensorClient_SensorReadingChanged_Params.prototype.initDefaults_ = function() {
+  };
+  SensorClient_SensorReadingChanged_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  SensorClient_SensorReadingChanged_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 8}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  SensorClient_SensorReadingChanged_Params.encodedSize = codec.kStructHeaderSize + 0;
+
+  SensorClient_SensorReadingChanged_Params.decode = function(decoder) {
+    var packed;
+    var val = new SensorClient_SensorReadingChanged_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    return val;
+  };
+
+  SensorClient_SensorReadingChanged_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(SensorClient_SensorReadingChanged_Params.encodedSize);
+    encoder.writeUint32(0);
+  };
+  var kSensor_GetDefaultConfiguration_Name = 0;
+  var kSensor_AddConfiguration_Name = 1;
+  var kSensor_RemoveConfiguration_Name = 2;
+  var kSensor_Suspend_Name = 3;
+  var kSensor_Resume_Name = 4;
+  var kSensor_ConfigureReadingChangeNotifications_Name = 5;
+
+  function SensorPtr(handleOrPtrInfo) {
+    this.ptr = new bindings.InterfacePtrController(Sensor,
+                                                   handleOrPtrInfo);
+  }
+
+  function SensorAssociatedPtr(associatedInterfacePtrInfo) {
+    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
+        Sensor, associatedInterfacePtrInfo);
+  }
+
+  SensorAssociatedPtr.prototype =
+      Object.create(SensorPtr.prototype);
+  SensorAssociatedPtr.prototype.constructor =
+      SensorAssociatedPtr;
+
+  function SensorProxy(receiver) {
+    this.receiver_ = receiver;
+  }
+  SensorPtr.prototype.getDefaultConfiguration = function() {
+    return SensorProxy.prototype.getDefaultConfiguration
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProxy.prototype.getDefaultConfiguration = function() {
+    var params = new Sensor_GetDefaultConfiguration_Params();
+    return new Promise(function(resolve, reject) {
+      var builder = new codec.MessageV1Builder(
+          kSensor_GetDefaultConfiguration_Name,
+          codec.align(Sensor_GetDefaultConfiguration_Params.encodedSize),
+          codec.kMessageExpectsResponse, 0);
+      builder.encodeStruct(Sensor_GetDefaultConfiguration_Params, params);
+      var message = builder.finish();
+      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
+        var reader = new codec.MessageReader(message);
+        var responseParams =
+            reader.decodeStruct(Sensor_GetDefaultConfiguration_ResponseParams);
+        resolve(responseParams);
+      }).catch(function(result) {
+        reject(Error("Connection error: " + result));
+      });
+    }.bind(this));
+  };
+  SensorPtr.prototype.addConfiguration = function() {
+    return SensorProxy.prototype.addConfiguration
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProxy.prototype.addConfiguration = function(configuration) {
+    var params = new Sensor_AddConfiguration_Params();
+    params.configuration = configuration;
+    return new Promise(function(resolve, reject) {
+      var builder = new codec.MessageV1Builder(
+          kSensor_AddConfiguration_Name,
+          codec.align(Sensor_AddConfiguration_Params.encodedSize),
+          codec.kMessageExpectsResponse, 0);
+      builder.encodeStruct(Sensor_AddConfiguration_Params, params);
+      var message = builder.finish();
+      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
+        var reader = new codec.MessageReader(message);
+        var responseParams =
+            reader.decodeStruct(Sensor_AddConfiguration_ResponseParams);
+        resolve(responseParams);
+      }).catch(function(result) {
+        reject(Error("Connection error: " + result));
+      });
+    }.bind(this));
+  };
+  SensorPtr.prototype.removeConfiguration = function() {
+    return SensorProxy.prototype.removeConfiguration
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProxy.prototype.removeConfiguration = function(configuration) {
+    var params = new Sensor_RemoveConfiguration_Params();
+    params.configuration = configuration;
+    var builder = new codec.MessageV0Builder(
+        kSensor_RemoveConfiguration_Name,
+        codec.align(Sensor_RemoveConfiguration_Params.encodedSize));
+    builder.encodeStruct(Sensor_RemoveConfiguration_Params, params);
+    var message = builder.finish();
+    this.receiver_.accept(message);
+  };
+  SensorPtr.prototype.suspend = function() {
+    return SensorProxy.prototype.suspend
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProxy.prototype.suspend = function() {
+    var params = new Sensor_Suspend_Params();
+    var builder = new codec.MessageV0Builder(
+        kSensor_Suspend_Name,
+        codec.align(Sensor_Suspend_Params.encodedSize));
+    builder.encodeStruct(Sensor_Suspend_Params, params);
+    var message = builder.finish();
+    this.receiver_.accept(message);
+  };
+  SensorPtr.prototype.resume = function() {
+    return SensorProxy.prototype.resume
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProxy.prototype.resume = function() {
+    var params = new Sensor_Resume_Params();
+    var builder = new codec.MessageV0Builder(
+        kSensor_Resume_Name,
+        codec.align(Sensor_Resume_Params.encodedSize));
+    builder.encodeStruct(Sensor_Resume_Params, params);
+    var message = builder.finish();
+    this.receiver_.accept(message);
+  };
+  SensorPtr.prototype.configureReadingChangeNotifications = function() {
+    return SensorProxy.prototype.configureReadingChangeNotifications
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProxy.prototype.configureReadingChangeNotifications = function(enabled) {
+    var params = new Sensor_ConfigureReadingChangeNotifications_Params();
+    params.enabled = enabled;
+    var builder = new codec.MessageV0Builder(
+        kSensor_ConfigureReadingChangeNotifications_Name,
+        codec.align(Sensor_ConfigureReadingChangeNotifications_Params.encodedSize));
+    builder.encodeStruct(Sensor_ConfigureReadingChangeNotifications_Params, params);
+    var message = builder.finish();
+    this.receiver_.accept(message);
+  };
+
+  function SensorStub(delegate) {
+    this.delegate_ = delegate;
+  }
+  SensorStub.prototype.getDefaultConfiguration = function() {
+    return this.delegate_ && this.delegate_.getDefaultConfiguration && this.delegate_.getDefaultConfiguration();
+  }
+  SensorStub.prototype.addConfiguration = function(configuration) {
+    return this.delegate_ && this.delegate_.addConfiguration && this.delegate_.addConfiguration(configuration);
+  }
+  SensorStub.prototype.removeConfiguration = function(configuration) {
+    return this.delegate_ && this.delegate_.removeConfiguration && this.delegate_.removeConfiguration(configuration);
+  }
+  SensorStub.prototype.suspend = function() {
+    return this.delegate_ && this.delegate_.suspend && this.delegate_.suspend();
+  }
+  SensorStub.prototype.resume = function() {
+    return this.delegate_ && this.delegate_.resume && this.delegate_.resume();
+  }
+  SensorStub.prototype.configureReadingChangeNotifications = function(enabled) {
+    return this.delegate_ && this.delegate_.configureReadingChangeNotifications && this.delegate_.configureReadingChangeNotifications(enabled);
+  }
+
+  SensorStub.prototype.accept = function(message) {
+    var reader = new codec.MessageReader(message);
+    switch (reader.messageName) {
+    case kSensor_RemoveConfiguration_Name:
+      var params = reader.decodeStruct(Sensor_RemoveConfiguration_Params);
+      this.removeConfiguration(params.configuration);
+      return true;
+    case kSensor_Suspend_Name:
+      var params = reader.decodeStruct(Sensor_Suspend_Params);
+      this.suspend();
+      return true;
+    case kSensor_Resume_Name:
+      var params = reader.decodeStruct(Sensor_Resume_Params);
+      this.resume();
+      return true;
+    case kSensor_ConfigureReadingChangeNotifications_Name:
+      var params = reader.decodeStruct(Sensor_ConfigureReadingChangeNotifications_Params);
+      this.configureReadingChangeNotifications(params.enabled);
+      return true;
+    default:
+      return false;
+    }
+  };
+
+  SensorStub.prototype.acceptWithResponder =
+      function(message, responder) {
+    var reader = new codec.MessageReader(message);
+    switch (reader.messageName) {
+    case kSensor_GetDefaultConfiguration_Name:
+      var params = reader.decodeStruct(Sensor_GetDefaultConfiguration_Params);
+      this.getDefaultConfiguration().then(function(response) {
+        var responseParams =
+            new Sensor_GetDefaultConfiguration_ResponseParams();
+        responseParams.configuration = response.configuration;
+        var builder = new codec.MessageV1Builder(
+            kSensor_GetDefaultConfiguration_Name,
+            codec.align(Sensor_GetDefaultConfiguration_ResponseParams.encodedSize),
+            codec.kMessageIsResponse, reader.requestID);
+        builder.encodeStruct(Sensor_GetDefaultConfiguration_ResponseParams,
+                             responseParams);
+        var message = builder.finish();
+        responder.accept(message);
+      });
+      return true;
+    case kSensor_AddConfiguration_Name:
+      var params = reader.decodeStruct(Sensor_AddConfiguration_Params);
+      this.addConfiguration(params.configuration).then(function(response) {
+        var responseParams =
+            new Sensor_AddConfiguration_ResponseParams();
+        responseParams.success = response.success;
+        var builder = new codec.MessageV1Builder(
+            kSensor_AddConfiguration_Name,
+            codec.align(Sensor_AddConfiguration_ResponseParams.encodedSize),
+            codec.kMessageIsResponse, reader.requestID);
+        builder.encodeStruct(Sensor_AddConfiguration_ResponseParams,
+                             responseParams);
+        var message = builder.finish();
+        responder.accept(message);
+      });
+      return true;
+    default:
+      return false;
+    }
+  };
+
+  function validateSensorRequest(messageValidator) {
+    var message = messageValidator.message;
+    var paramsClass = null;
+    switch (message.getName()) {
+      case kSensor_GetDefaultConfiguration_Name:
+        if (message.expectsResponse())
+          paramsClass = Sensor_GetDefaultConfiguration_Params;
+      break;
+      case kSensor_AddConfiguration_Name:
+        if (message.expectsResponse())
+          paramsClass = Sensor_AddConfiguration_Params;
+      break;
+      case kSensor_RemoveConfiguration_Name:
+        if (!message.expectsResponse() && !message.isResponse())
+          paramsClass = Sensor_RemoveConfiguration_Params;
+      break;
+      case kSensor_Suspend_Name:
+        if (!message.expectsResponse() && !message.isResponse())
+          paramsClass = Sensor_Suspend_Params;
+      break;
+      case kSensor_Resume_Name:
+        if (!message.expectsResponse() && !message.isResponse())
+          paramsClass = Sensor_Resume_Params;
+      break;
+      case kSensor_ConfigureReadingChangeNotifications_Name:
+        if (!message.expectsResponse() && !message.isResponse())
+          paramsClass = Sensor_ConfigureReadingChangeNotifications_Params;
+      break;
+    }
+    if (paramsClass === null)
+      return validator.validationError.NONE;
+    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
+  }
+
+  function validateSensorResponse(messageValidator) {
+   var message = messageValidator.message;
+   var paramsClass = null;
+   switch (message.getName()) {
+      case kSensor_GetDefaultConfiguration_Name:
+        if (message.isResponse())
+          paramsClass = Sensor_GetDefaultConfiguration_ResponseParams;
+        break;
+      case kSensor_AddConfiguration_Name:
+        if (message.isResponse())
+          paramsClass = Sensor_AddConfiguration_ResponseParams;
+        break;
+    }
+    if (paramsClass === null)
+      return validator.validationError.NONE;
+    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
+  }
+
+  var Sensor = {
+    name: 'device::mojom::Sensor',
+    kVersion: 0,
+    ptrClass: SensorPtr,
+    proxyClass: SensorProxy,
+    stubClass: SensorStub,
+    validateRequest: validateSensorRequest,
+    validateResponse: validateSensorResponse,
+  };
+  SensorStub.prototype.validator = validateSensorRequest;
+  SensorProxy.prototype.validator = validateSensorResponse;
+  var kSensorClient_RaiseError_Name = 0;
+  var kSensorClient_SensorReadingChanged_Name = 1;
+
+  function SensorClientPtr(handleOrPtrInfo) {
+    this.ptr = new bindings.InterfacePtrController(SensorClient,
+                                                   handleOrPtrInfo);
+  }
+
+  function SensorClientAssociatedPtr(associatedInterfacePtrInfo) {
+    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
+        SensorClient, associatedInterfacePtrInfo);
+  }
+
+  SensorClientAssociatedPtr.prototype =
+      Object.create(SensorClientPtr.prototype);
+  SensorClientAssociatedPtr.prototype.constructor =
+      SensorClientAssociatedPtr;
+
+  function SensorClientProxy(receiver) {
+    this.receiver_ = receiver;
+  }
+  SensorClientPtr.prototype.raiseError = function() {
+    return SensorClientProxy.prototype.raiseError
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorClientProxy.prototype.raiseError = function() {
+    var params = new SensorClient_RaiseError_Params();
+    var builder = new codec.MessageV0Builder(
+        kSensorClient_RaiseError_Name,
+        codec.align(SensorClient_RaiseError_Params.encodedSize));
+    builder.encodeStruct(SensorClient_RaiseError_Params, params);
+    var message = builder.finish();
+    this.receiver_.accept(message);
+  };
+  SensorClientPtr.prototype.sensorReadingChanged = function() {
+    return SensorClientProxy.prototype.sensorReadingChanged
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorClientProxy.prototype.sensorReadingChanged = function() {
+    var params = new SensorClient_SensorReadingChanged_Params();
+    var builder = new codec.MessageV0Builder(
+        kSensorClient_SensorReadingChanged_Name,
+        codec.align(SensorClient_SensorReadingChanged_Params.encodedSize));
+    builder.encodeStruct(SensorClient_SensorReadingChanged_Params, params);
+    var message = builder.finish();
+    this.receiver_.accept(message);
+  };
+
+  function SensorClientStub(delegate) {
+    this.delegate_ = delegate;
+  }
+  SensorClientStub.prototype.raiseError = function() {
+    return this.delegate_ && this.delegate_.raiseError && this.delegate_.raiseError();
+  }
+  SensorClientStub.prototype.sensorReadingChanged = function() {
+    return this.delegate_ && this.delegate_.sensorReadingChanged && this.delegate_.sensorReadingChanged();
+  }
+
+  SensorClientStub.prototype.accept = function(message) {
+    var reader = new codec.MessageReader(message);
+    switch (reader.messageName) {
+    case kSensorClient_RaiseError_Name:
+      var params = reader.decodeStruct(SensorClient_RaiseError_Params);
+      this.raiseError();
+      return true;
+    case kSensorClient_SensorReadingChanged_Name:
+      var params = reader.decodeStruct(SensorClient_SensorReadingChanged_Params);
+      this.sensorReadingChanged();
+      return true;
+    default:
+      return false;
+    }
+  };
+
+  SensorClientStub.prototype.acceptWithResponder =
+      function(message, responder) {
+    var reader = new codec.MessageReader(message);
+    switch (reader.messageName) {
+    default:
+      return false;
+    }
+  };
+
+  function validateSensorClientRequest(messageValidator) {
+    var message = messageValidator.message;
+    var paramsClass = null;
+    switch (message.getName()) {
+      case kSensorClient_RaiseError_Name:
+        if (!message.expectsResponse() && !message.isResponse())
+          paramsClass = SensorClient_RaiseError_Params;
+      break;
+      case kSensorClient_SensorReadingChanged_Name:
+        if (!message.expectsResponse() && !message.isResponse())
+          paramsClass = SensorClient_SensorReadingChanged_Params;
+      break;
+    }
+    if (paramsClass === null)
+      return validator.validationError.NONE;
+    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
+  }
+
+  function validateSensorClientResponse(messageValidator) {
+    return validator.validationError.NONE;
+  }
+
+  var SensorClient = {
+    name: 'device::mojom::SensorClient',
+    kVersion: 0,
+    ptrClass: SensorClientPtr,
+    proxyClass: SensorClientProxy,
+    stubClass: SensorClientStub,
+    validateRequest: validateSensorClientRequest,
+    validateResponse: null,
+  };
+  SensorClientStub.prototype.validator = validateSensorClientRequest;
+  SensorClientProxy.prototype.validator = null;
+  exports.SensorType = SensorType;
+  exports.ReportingMode = ReportingMode;
+  exports.SensorConfiguration = SensorConfiguration;
+  exports.Sensor = Sensor;
+  exports.SensorPtr = SensorPtr;
+  exports.SensorAssociatedPtr = SensorAssociatedPtr;
+  exports.SensorClient = SensorClient;
+  exports.SensorClientPtr = SensorClientPtr;
+  exports.SensorClientAssociatedPtr = SensorClientAssociatedPtr;
+})();
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/resources/chromium/sensor_provider.mojom.js
@@ -0,0 +1,429 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+(function() {
+  var mojomId = 'services/device/public/mojom/sensor_provider.mojom';
+  if (mojo.internal.isMojomLoaded(mojomId)) {
+    console.warn('The following mojom is loaded multiple times: ' + mojomId);
+    return;
+  }
+  mojo.internal.markMojomLoaded(mojomId);
+  var bindings = mojo;
+  var associatedBindings = mojo;
+  var codec = mojo.internal;
+  var validator = mojo.internal;
+
+  var exports = mojo.internal.exposeNamespace('device.mojom');
+  var sensor$ =
+      mojo.internal.exposeNamespace('device.mojom');
+  if (mojo.config.autoLoadMojomDeps) {
+    mojo.internal.loadMojomIfNecessary(
+        'services/device/public/mojom/sensor.mojom', 'sensor.mojom.js');
+  }
+
+
+  var SensorCreationResult = {};
+  SensorCreationResult.SUCCESS = 0;
+  SensorCreationResult.ERROR_NOT_AVAILABLE = SensorCreationResult.SUCCESS + 1;
+  SensorCreationResult.ERROR_NOT_ALLOWED = SensorCreationResult.ERROR_NOT_AVAILABLE + 1;
+
+  SensorCreationResult.isKnownEnumValue = function(value) {
+    switch (value) {
+    case 0:
+    case 1:
+    case 2:
+      return true;
+    }
+    return false;
+  };
+
+  SensorCreationResult.validate = function(enumValue) {
+    var isExtensible = false;
+    if (isExtensible || this.isKnownEnumValue(enumValue))
+      return validator.validationError.NONE;
+
+    return validator.validationError.UNKNOWN_ENUM_VALUE;
+  };
+
+  function SensorInitParams(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  SensorInitParams.kReadBufferSizeForTests = 48;
+  SensorInitParams.prototype.initDefaults_ = function() {
+    this.sensor = new sensor$.SensorPtr();
+    this.clientRequest = new bindings.InterfaceRequest();
+    this.memory = null;
+    this.bufferOffset = 0;
+    this.mode = 0;
+    this.defaultConfiguration = null;
+    this.maximumFrequency = 0;
+    this.minimumFrequency = 0;
+  };
+  SensorInitParams.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  SensorInitParams.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 64}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorInitParams.sensor
+    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorInitParams.clientRequest
+    err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 8, false)
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorInitParams.memory
+    err = messageValidator.validateHandle(offset + codec.kStructHeaderSize + 12, false)
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+
+    // validate SensorInitParams.mode
+    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 24, sensor$.ReportingMode);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorInitParams.defaultConfiguration
+    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, sensor$.SensorConfiguration, false);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+
+    return validator.validationError.NONE;
+  };
+
+  SensorInitParams.encodedSize = codec.kStructHeaderSize + 56;
+
+  SensorInitParams.decode = function(decoder) {
+    var packed;
+    var val = new SensorInitParams();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.sensor = decoder.decodeStruct(new codec.Interface(sensor$.SensorPtr));
+    val.clientRequest = decoder.decodeStruct(codec.InterfaceRequest);
+    val.memory = decoder.decodeStruct(codec.Handle);
+    val.bufferOffset = decoder.decodeStruct(codec.Uint64);
+    val.mode = decoder.decodeStruct(codec.Int32);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    val.defaultConfiguration = decoder.decodeStructPointer(sensor$.SensorConfiguration);
+    val.maximumFrequency = decoder.decodeStruct(codec.Double);
+    val.minimumFrequency = decoder.decodeStruct(codec.Double);
+    return val;
+  };
+
+  SensorInitParams.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(SensorInitParams.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStruct(new codec.Interface(sensor$.SensorPtr), val.sensor);
+    encoder.encodeStruct(codec.InterfaceRequest, val.clientRequest);
+    encoder.encodeStruct(codec.Handle, val.memory);
+    encoder.encodeStruct(codec.Uint64, val.bufferOffset);
+    encoder.encodeStruct(codec.Int32, val.mode);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.encodeStructPointer(sensor$.SensorConfiguration, val.defaultConfiguration);
+    encoder.encodeStruct(codec.Double, val.maximumFrequency);
+    encoder.encodeStruct(codec.Double, val.minimumFrequency);
+  };
+  function SensorProvider_GetSensor_Params(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  SensorProvider_GetSensor_Params.prototype.initDefaults_ = function() {
+    this.type = 0;
+  };
+  SensorProvider_GetSensor_Params.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  SensorProvider_GetSensor_Params.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 16}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorProvider_GetSensor_Params.type
+    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, sensor$.SensorType);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  SensorProvider_GetSensor_Params.encodedSize = codec.kStructHeaderSize + 8;
+
+  SensorProvider_GetSensor_Params.decode = function(decoder) {
+    var packed;
+    var val = new SensorProvider_GetSensor_Params();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.type = decoder.decodeStruct(codec.Int32);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    return val;
+  };
+
+  SensorProvider_GetSensor_Params.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(SensorProvider_GetSensor_Params.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStruct(codec.Int32, val.type);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+  };
+  function SensorProvider_GetSensor_ResponseParams(values) {
+    this.initDefaults_();
+    this.initFields_(values);
+  }
+
+
+  SensorProvider_GetSensor_ResponseParams.prototype.initDefaults_ = function() {
+    this.result = 0;
+    this.initParams = null;
+  };
+  SensorProvider_GetSensor_ResponseParams.prototype.initFields_ = function(fields) {
+    for(var field in fields) {
+        if (this.hasOwnProperty(field))
+          this[field] = fields[field];
+    }
+  };
+
+  SensorProvider_GetSensor_ResponseParams.validate = function(messageValidator, offset) {
+    var err;
+    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    var kVersionSizes = [
+      {version: 0, numBytes: 24}
+    ];
+    err = messageValidator.validateStructVersion(offset, kVersionSizes);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorProvider_GetSensor_ResponseParams.result
+    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, SensorCreationResult);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+
+    // validate SensorProvider_GetSensor_ResponseParams.initParams
+    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, SensorInitParams, true);
+    if (err !== validator.validationError.NONE)
+        return err;
+
+    return validator.validationError.NONE;
+  };
+
+  SensorProvider_GetSensor_ResponseParams.encodedSize = codec.kStructHeaderSize + 16;
+
+  SensorProvider_GetSensor_ResponseParams.decode = function(decoder) {
+    var packed;
+    var val = new SensorProvider_GetSensor_ResponseParams();
+    var numberOfBytes = decoder.readUint32();
+    var version = decoder.readUint32();
+    val.result = decoder.decodeStruct(codec.Int32);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    decoder.skip(1);
+    val.initParams = decoder.decodeStructPointer(SensorInitParams);
+    return val;
+  };
+
+  SensorProvider_GetSensor_ResponseParams.encode = function(encoder, val) {
+    var packed;
+    encoder.writeUint32(SensorProvider_GetSensor_ResponseParams.encodedSize);
+    encoder.writeUint32(0);
+    encoder.encodeStruct(codec.Int32, val.result);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.skip(1);
+    encoder.encodeStructPointer(SensorInitParams, val.initParams);
+  };
+  var kSensorProvider_GetSensor_Name = 0;
+
+  function SensorProviderPtr(handleOrPtrInfo) {
+    this.ptr = new bindings.InterfacePtrController(SensorProvider,
+                                                   handleOrPtrInfo);
+  }
+
+  function SensorProviderAssociatedPtr(associatedInterfacePtrInfo) {
+    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
+        SensorProvider, associatedInterfacePtrInfo);
+  }
+
+  SensorProviderAssociatedPtr.prototype =
+      Object.create(SensorProviderPtr.prototype);
+  SensorProviderAssociatedPtr.prototype.constructor =
+      SensorProviderAssociatedPtr;
+
+  function SensorProviderProxy(receiver) {
+    this.receiver_ = receiver;
+  }
+  SensorProviderPtr.prototype.getSensor = function() {
+    return SensorProviderProxy.prototype.getSensor
+        .apply(this.ptr.getProxy(), arguments);
+  };
+
+  SensorProviderProxy.prototype.getSensor = function(type) {
+    var params = new SensorProvider_GetSensor_Params();
+    params.type = type;
+    return new Promise(function(resolve, reject) {
+      var builder = new codec.MessageV1Builder(
+          kSensorProvider_GetSensor_Name,
+          codec.align(SensorProvider_GetSensor_Params.encodedSize),
+          codec.kMessageExpectsResponse, 0);
+      builder.encodeStruct(SensorProvider_GetSensor_Params, params);
+      var message = builder.finish();
+      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
+        var reader = new codec.MessageReader(message);
+        var responseParams =
+            reader.decodeStruct(SensorProvider_GetSensor_ResponseParams);
+        resolve(responseParams);
+      }).catch(function(result) {
+        reject(Error("Connection error: " + result));
+      });
+    }.bind(this));
+  };
+
+  function SensorProviderStub(delegate) {
+    this.delegate_ = delegate;
+  }
+  SensorProviderStub.prototype.getSensor = function(type) {
+    return this.delegate_ && this.delegate_.getSensor && this.delegate_.getSensor(type);
+  }
+
+  SensorProviderStub.prototype.accept = function(message) {
+    var reader = new codec.MessageReader(message);
+    switch (reader.messageName) {
+    default:
+      return false;
+    }
+  };
+
+  SensorProviderStub.prototype.acceptWithResponder =
+      function(message, responder) {
+    var reader = new codec.MessageReader(message);
+    switch (reader.messageName) {
+    case kSensorProvider_GetSensor_Name:
+      var params = reader.decodeStruct(SensorProvider_GetSensor_Params);
+      this.getSensor(params.type).then(function(response) {
+        var responseParams =
+            new SensorProvider_GetSensor_ResponseParams();
+        responseParams.result = response.result;
+        responseParams.initParams = response.initParams;
+        var builder = new codec.MessageV1Builder(
+            kSensorProvider_GetSensor_Name,
+            codec.align(SensorProvider_GetSensor_ResponseParams.encodedSize),
+            codec.kMessageIsResponse, reader.requestID);
+        builder.encodeStruct(SensorProvider_GetSensor_ResponseParams,
+                             responseParams);
+        var message = builder.finish();
+        responder.accept(message);
+      });
+      return true;
+    default:
+      return false;
+    }
+  };
+
+  function validateSensorProviderRequest(messageValidator) {
+    var message = messageValidator.message;
+    var paramsClass = null;
+    switch (message.getName()) {
+      case kSensorProvider_GetSensor_Name:
+        if (message.expectsResponse())
+          paramsClass = SensorProvider_GetSensor_Params;
+      break;
+    }
+    if (paramsClass === null)
+      return validator.validationError.NONE;
+    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
+  }
+
+  function validateSensorProviderResponse(messageValidator) {
+   var message = messageValidator.message;
+   var paramsClass = null;
+   switch (message.getName()) {
+      case kSensorProvider_GetSensor_Name:
+        if (message.isResponse())
+          paramsClass = SensorProvider_GetSensor_ResponseParams;
+        break;
+    }
+    if (paramsClass === null)
+      return validator.validationError.NONE;
+    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
+  }
+
+  var SensorProvider = {
+    name: 'device::mojom::SensorProvider',
+    kVersion: 0,
+    ptrClass: SensorProviderPtr,
+    proxyClass: SensorProviderProxy,
+    stubClass: SensorProviderStub,
+    validateRequest: validateSensorProviderRequest,
+    validateResponse: validateSensorProviderResponse,
+  };
+  SensorProviderStub.prototype.validator = validateSensorProviderRequest;
+  SensorProviderProxy.prototype.validator = validateSensorProviderResponse;
+  exports.SensorCreationResult = SensorCreationResult;
+  exports.SensorInitParams = SensorInitParams;
+  exports.SensorProvider = SensorProvider;
+  exports.SensorProviderPtr = SensorProviderPtr;
+  exports.SensorProviderAssociatedPtr = SensorProviderAssociatedPtr;
+})();
\ No newline at end of file