diff --git a/apps/system/js/ftu_ping.js b/apps/system/js/ftu_ping.js index 1e17c82abaec..f9698d2bf763 100644 --- a/apps/system/js/ftu_ping.js +++ b/apps/system/js/ftu_ping.js @@ -102,41 +102,55 @@ initSettings: function fp_initSettings() { var self = this; - return new Promise(function(resolve, reject) { - self.reset(); - - self._pingData.screenHeight = window.screen.height; - self._pingData.screenWidth = window.screen.width; - self._pingData.devicePixelRatio = window.devicePixelRatio; - - self.getAsyncStorageItems([FTU_PING_ID, FTU_PING_ACTIVATION, - FTU_PING_ENABLED, - FTU_PING_NETWORK_FAIL_COUNT], - function(items) { - self._pingData.pingID = items[FTU_PING_ID]; - self._pingData.activationTime = items[FTU_PING_ACTIVATION]; - self._pingEnabled = items[FTU_PING_ENABLED]; - - if (!self._pingData.pingID) { + function getDeviceID() { + // The TelemetryRequest API rejects when device ID can't be found, which + // means we can't easily chain it to other promises, so we wrap it here + return new Promise(function(resolve, reject) { + var promise = TelemetryRequest.getDeviceID(FTU_PING_ID); + promise.then(function(deviceID) { + self.debug('Found deviceID: ' + deviceID); + self._pingData.pingID = deviceID; + resolve(); + }).catch(function(error) { + self.debug('Generating deviceID: ' + error); self._pingData.pingID = uuid(); window.asyncStorage.setItem(FTU_PING_ID, self._pingData.pingID); - } + resolve(); + }); + }); + } - if (!self._pingData.activationTime) { - self._pingData.activationTime = Date.now(); - window.asyncStorage.setItem(FTU_PING_ACTIVATION, - self._pingData.activationTime); - } + function getAsyncItems() { + return new Promise(function(resolve, reject) { + self.getAsyncStorageItems([FTU_PING_ACTIVATION, + FTU_PING_ENABLED, + FTU_PING_NETWORK_FAIL_COUNT], + function(items) { - if (self._pingEnabled === null) { - self._pingEnabled = true; - } + self._pingData.activationTime = items[FTU_PING_ACTIVATION]; + self._pingEnabled = items[FTU_PING_ENABLED]; - if (typeof(items[FTU_PING_NETWORK_FAIL_COUNT]) === 'number') { - self._networkFailCount = items[FTU_PING_NETWORK_FAIL_COUNT]; - } + if (!self._pingData.activationTime) { + self._pingData.activationTime = Date.now(); + window.asyncStorage.setItem(FTU_PING_ACTIVATION, + self._pingData.activationTime); + } + + if (self._pingEnabled === null) { + self._pingEnabled = true; + } + + if (typeof(items[FTU_PING_NETWORK_FAIL_COUNT]) === 'number') { + self._networkFailCount = items[FTU_PING_NETWORK_FAIL_COUNT]; + } + resolve(); + }); + }); + } + function getSettings() { + return new Promise(function(resolve, reject) { var allSettings = [FTU_PING_URL, FTU_PING_TRY_INTERVAL, FTU_PING_TIMEOUT, FTU_PING_MAX_NETWORK_FAILS]. concat(OBSERVE_SETTINGS); @@ -167,7 +181,15 @@ resolve(); }); }); - }); + } + + self.reset(); + + self._pingData.screenHeight = window.screen.height; + self._pingData.screenWidth = window.screen.width; + self._pingData.devicePixelRatio = window.devicePixelRatio; + + return Promise.all([getDeviceID(), getAsyncItems(), getSettings()]); }, initPreinstalledApps: function fp_initPreinstalledApps(callback) { @@ -230,8 +252,11 @@ }, ensurePing: function fp_ensurePing() { - var initPromises = [this.initSettings(), this.initPreinstalledApps()]; - Promise.all(initPromises).then(this.startPing.bind(this)); + var self = this; + LazyLoader.load('shared/js/telemetry.js').then(function() { + return Promise.all([self.initSettings(), self.initPreinstalledApps()]) + .then(self.startPing.bind(self)); + }); }, onSettingChanged: function fp_onSettingChanged(evt) { @@ -346,32 +371,28 @@ var pingData = this.assemblePingData(); this._pingData.pingTime = Date.now(); - LazyLoader.load(['shared/js/telemetry.js']).then(() => { - var request = new TelemetryRequest({ - reason: TELEMETRY_REASON, - deviceID: pingData.pingID, - ver: TELEMETRY_VERSION, - url: this._pingURL, - appUpdateChannel: this._infoData['app.update.channel'], - appVersion: this._infoData['deviceinfo.platform_version'], - appBuildID: this._infoData['deviceinfo.platform_build_id'] - }, pingData); - - var self = this; - request.send({ - timeout: this._pingTimeout, - onload: function() { - self.pingSuccess(this.responseText); - }, - ontimeout: function() { - self.pingError('Timed out'); - }, - onerror: function() { - self.pingError(this.statusText); - } - }); - }).catch((err) => { - console.error(err); + var request = new TelemetryRequest({ + reason: TELEMETRY_REASON, + deviceID: pingData.pingID, + ver: TELEMETRY_VERSION, + url: this._pingURL, + appUpdateChannel: this._infoData['app.update.channel'], + appVersion: this._infoData['deviceinfo.platform_version'], + appBuildID: this._infoData['deviceinfo.platform_build_id'] + }, pingData); + + var self = this; + request.send({ + timeout: this._pingTimeout, + onload: function() { + self.pingSuccess(this.responseText); + }, + ontimeout: function() { + self.pingError('Timed out'); + }, + onerror: function() { + self.pingError(this.statusText); + } }); }, diff --git a/apps/system/test/unit/ftu_ping_test.js b/apps/system/test/unit/ftu_ping_test.js index 4a79d6d98013..7359f15c5965 100644 --- a/apps/system/test/unit/ftu_ping_test.js +++ b/apps/system/test/unit/ftu_ping_test.js @@ -2,14 +2,15 @@ /* global MockNavigatorSettings, MockasyncStorage, MockXMLHttpRequest, MockNavigatorMozMobileConnections, MockNavigatorMozIccManager, - MockMobileOperator, MockSIMSlotManager, MockSIMSlot, MockAppsMgmt, - MocksHelper */ + MockNavigatorMozTelephony, MockMobileOperator, MockSIMSlotManager, + MockSIMSlot, MockAppsMgmt, MocksHelper */ require('/shared/test/unit/mocks/mock_navigator_moz_settings.js'); require('/apps/system/test/unit/mock_asyncStorage.js'); require('/apps/system/test/unit/mock_xmlhttprequest.js'); require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js'); require('/shared/test/unit/mocks/mock_navigator_moz_icc_manager.js'); +require('/shared/test/unit/mocks/mock_navigator_moz_telephony.js'); require('/shared/test/unit/mocks/mock_mobile_operator.js'); requireApp('system/test/unit/mock_apps_mgmt.js'); requireApp('system/test/unit/mock_lazy_loader.js'); @@ -54,7 +55,7 @@ suite('FtuPing', function() { var realMobileConnections, realIccManager; var realMobileOperator, realSIMSlotManager; var realNavigatorLanguage; - var realMozApps; + var realMozApps, realMozTelephony; var FtuPing; suiteSetup(function() { @@ -67,6 +68,7 @@ suite('FtuPing', function() { realSIMSlotManager = window.SIMSlotManager; realMozApps = navigator.mozApps; realNavigatorLanguage = navigator.language; + realMozTelephony = navigator.mozTelephony; navigator.mozSettings = MockNavigatorSettings; window.asyncStorage = MockasyncStorage; @@ -76,6 +78,7 @@ suite('FtuPing', function() { window.MobileOperator = MockMobileOperator; window.SIMSlotManager = MockSIMSlotManager; navigator.mozApps = { mgmt: MockAppsMgmt }; + navigator.mozTelephony = MockNavigatorMozTelephony; switchReadOnlyProperty(navigator,'language', realNavigatorLanguage); }); @@ -88,6 +91,7 @@ suite('FtuPing', function() { window.MobileOperator = realMobileOperator; window.SIMSlotManager = realSIMSlotManager; navigator.mozApps = realMozApps; + navigator.mozTelephony = realMozTelephony; switchReadOnlyProperty(navigator,'language', realNavigatorLanguage); }); @@ -544,4 +548,53 @@ suite('FtuPing', function() { assert.equal(FtuPing.assemblePingData().locale, newLocale); }); }); + + suite('deviceID', function() { + setup(function() { + MockNavigatorSettings.mSettings['ftu.pingURL'] = 'test_url'; + MockasyncStorage.mItems['ftu.pingEnabled'] = true; + + this.sinon.stub(window, 'uuid', function() { + return 'uuid'; + }); + + this.sinon.stub(navigator.mozTelephony, 'dial', function() { + return Promise.resolve({ + result: Promise.resolve({ + success: true, + serviceCode: 'scImei', + statusMessage: 'fakeImei' + }) + }); + }); + }); + + test('is IMEI for dogfooder', function(done) { + var mockSettings = MockNavigatorSettings.mSettings; + mockSettings['debug.performance_data.dogfooding'] = '1'; + + FtuPing.initSettings().then(function() { + var pingData = FtuPing.assemblePingData(); + assert.equal(pingData.pingID, 'fakeImei'); + done(); + }); + }); + + test('is generated when not set', function(done) { + FtuPing.initSettings().then(function() { + var pingData = FtuPing.assemblePingData(); + assert.equal(pingData.pingID, 'uuid'); + done(); + }); + }); + + test('restores gracefully from asyncStorage', function(done) { + MockasyncStorage.mItems['ftu.pingID'] = 'ping_id'; + FtuPing.initSettings().then(function() { + var pingData = FtuPing.assemblePingData(); + assert.equal(pingData.pingID, 'ping_id'); + done(); + }); + }); + }); });