diff --git a/apps/homescreen/everything.me/js/Core.js b/apps/homescreen/everything.me/js/Core.js index 9e81fef156a8..bbca3ab691fc 100644 --- a/apps/homescreen/everything.me/js/Core.js +++ b/apps/homescreen/everything.me/js/Core.js @@ -6,7 +6,7 @@ window.Evme = new function Evme_Core() { this.shouldSearchOnInputBlur = false; - this.init = function init(callback) { + this.init = function init(config, callback) { var data = Evme.__config, apiHost = Evme.Utils.getUrlParam('apiHost') || data.apiHost; @@ -38,6 +38,7 @@ window.Evme = new function Evme_Core() { }); Evme.DoATAPI.init({ + 'deviceId': config.deviceId, 'apiKey': data.apiKey, 'appVersion': data.appVersion, 'authCookieName': data.authCookieName, diff --git a/apps/homescreen/everything.me/js/api/DoATAPI.js b/apps/homescreen/everything.me/js/api/DoATAPI.js index e89c2bd23214..9d9db850a15a 100644 --- a/apps/homescreen/everything.me/js/api/DoATAPI.js +++ b/apps/homescreen/everything.me/js/api/DoATAPI.js @@ -94,12 +94,7 @@ Evme.DoATAPI = new function Evme_DoATAPI() { authCookieName = options.authCookieName; manualCampaignStats = options.manualCampaignStats; - // temporarily generate a device id, so that requests going out before we - // took it from the cache won't fail - deviceId = generateDeviceId(); - getDeviceId(function deviceIdGot(value) { - deviceId = value; - }); + deviceId = options.deviceId; Evme.Storage.get(STORAGE_KEY_CREDS, function storageGot(value) { manualCredentials = value; @@ -921,28 +916,10 @@ Evme.DoATAPI = new function Evme_DoATAPI() { return retParams.join(','); } - function getDeviceId(callback) { - Evme.Storage.get('deviceId', function storageGot(deviceId) { - if (!deviceId) { - deviceId = generateDeviceId(); - Evme.Storage.set('deviceId', deviceId); - } - - callback(deviceId); - }); - } - this.getDeviceId = function getDeviceId() { return deviceId; }; - function generateDeviceId() { - var queryString = {}; - (location.search || '').replace(/(?:[?&]|^)([^=]+)=([^&]*)/g, - function regexmatch(ig, k, v) {queryString[k] = v;}); - return queryString['did'] || 'fxos-' + Evme.Utils.uuid(); - } - function cbRequest(methodNamespace, method, params, retryNumber, completeURL) { Evme.EventHandler.trigger(NAME, 'request', { diff --git a/apps/homescreen/everything.me/js/everything.me.js b/apps/homescreen/everything.me/js/everything.me.js index e73e9f38d2a5..306004343a02 100644 --- a/apps/homescreen/everything.me/js/everything.me.js +++ b/apps/homescreen/everything.me/js/everything.me.js @@ -327,8 +327,15 @@ var EverythingME = { }, initEvme: function EverythingME_initEvme() { - Evme.init(EverythingME.onEvmeLoaded); - EvmeFacade = Evme; + var config = this.datastore.getConfig(); + config.then(function resolve(emeConfig) { + EverythingME.log('EVME config from storage', JSON.stringify(emeConfig)); + + Evme.init({'deviceId': emeConfig.deviceId}, EverythingME.onEvmeLoaded); + EvmeFacade = Evme; + }, function reject(reason) { + EverythingME.warn('EVME config missing', reason); + }); }, onEvmeLoaded: function onEvmeLoaded() { @@ -499,8 +506,8 @@ var EverythingME = { }); } catch (ex) { deleteOld(); - console.warn('[EVME migration] [' + oldKey + ']: error: ' + oldValue + - ' (' + ex.message + ')'); + EverythingME.warn('[EVME migration] [' + oldKey + ']: error: ' + + oldValue + ' (' + ex.message + ')'); onComplete(false); return false; } @@ -551,6 +558,11 @@ var EverythingME = { if (this.debug) { console.log.apply(window, arguments); } + }, + warn: function log() { + if (this.debug) { + console.warn.apply(window, arguments); + } } }; @@ -562,3 +574,66 @@ var EvmeFacade = { return false; } }; + + +(function() { + 'use strict'; + + // datastore to use + var DS_NAME = 'eme_store'; + + // id of config object + var DS_CONFIG_ID = 1; + + // see duplicate in search/eme.js + function generateDeviceId() { + var url = window.URL.createObjectURL(new Blob()); + var id = url.replace('blob:', ''); + + window.URL.revokeObjectURL(url); + + return 'fxos-' + id; + } + + function emeDataStore() { + } + emeDataStore.prototype = { + // Get or create config shared with search/eme instance via DataStore API. + getConfig: function getConfig() { + var promise = new Promise(function done(resolve, reject) { + navigator.getDataStores(DS_NAME).then(function(stores) { + if (stores.length === 1) { + var db = stores[0]; + + db.get(DS_CONFIG_ID).then(function success(emeConfig) { + // use existing config + if (emeConfig) { + resolve(emeConfig); + } else { + // store new config + emeConfig = { + 'deviceId': generateDeviceId() + }; + + db.add(emeConfig, DS_CONFIG_ID).then(function success(id) { + resolve(emeConfig); + }, function error(e) { + reject('config creation failed'); + }); + } + }, function error(e) { + reject(e.message); + }); + + } else { + reject('invalid datastore setup'); + } + }); + }); + + return promise; + } + }; + + EverythingME.datastore = new emeDataStore(); +})(); diff --git a/apps/homescreen/manifest.webapp b/apps/homescreen/manifest.webapp index 342035d5007a..52f66728bf4e 100644 --- a/apps/homescreen/manifest.webapp +++ b/apps/homescreen/manifest.webapp @@ -56,5 +56,11 @@ }, "messages": [ { "alarm": "/index.html" } - ] + ], + "datastores-owned": { + "eme_store": { + "access": "readwrite", + "description": "Stores Everything.me data" + } + } } diff --git a/apps/search/js/eme/api.js b/apps/search/js/eme/api.js index 0e8420715c1e..b6284523b577 100644 --- a/apps/search/js/eme/api.js +++ b/apps/search/js/eme/api.js @@ -6,9 +6,13 @@ var API_URL = 'https://api.everything.me/partners/1.0/{resource}/'; var API_KEY = '79011a035b40ef3d7baeabc8f85b862f'; + var deviceId = null; + var self = this; this.init = function init(config) { + deviceId = config.deviceId; + addApiMethod('Apps', 'search'); addApiMethod('Search', 'suggestions'); addApiMethod('Search', 'bgimage'); @@ -31,14 +35,18 @@ */ function apiRequest(resource, options) { var url = API_URL.replace('{resource}', resource); - var params = 'apiKey=' + API_KEY + '&'; + var payload = ''; - if (options) { - for (var k in options) { - var v = options[k]; - if (v !== null && v !== undefined) { - params += k + '=' + encodeURIComponent(options[k]) + '&'; - } + options = options ? options : {}; + + // always send apiKey and deviceId + options.apiKey = API_KEY; + options.deviceId = deviceId; + + for (var k in options) { + var v = options[k]; + if (v !== null && v !== undefined) { + payload += k + '=' + encodeURIComponent(options[k]) + '&'; } } @@ -70,7 +78,7 @@ }; httpRequest.withCredentials = true; - httpRequest.send(params); + httpRequest.send(payload); }); return promise; diff --git a/apps/search/js/eme/eme.js b/apps/search/js/eme/eme.js index 123d0f439088..d4a1a9a8f36c 100644 --- a/apps/search/js/eme/eme.js +++ b/apps/search/js/eme/eme.js @@ -1,14 +1,60 @@ (function() { 'use strict'; + var DS_NAME = 'eme_store'; + var DS_CONFIG_ID = 1; + + // see duplicate in homescreen/everything.me.js + function generateDeviceId() { + var url = window.URL.createObjectURL(new Blob()); + var id = url.replace('blob:', ''); + + window.URL.revokeObjectURL(url); + + return 'fxos-' + id; + } + window.eme = { api: null, + /** + * Get or create config and init search/eme instance. + * Config is shared with the homescreen/eme instance via DataStore API. + */ init: function init() { - // TODO: - // get deviceId from homescreen app + var config = new Promise(function done(resolve, reject) { + navigator.getDataStores(DS_NAME).then(function(stores) { + if (stores.length === 1) { + var db = stores[0]; + db.get(DS_CONFIG_ID).then(function get(emeConfig) { + if (emeConfig) { + // use existing config + resolve(emeConfig); + } else { + // store new config + emeConfig = { + 'deviceId': generateDeviceId() + }; + db.add(emeConfig, DS_CONFIG_ID).then(function success(id) { + resolve(emeConfig); + }, function error(e) { + reject('config creation failed'); + }); + } + }, function error(e) { + reject(e.message); + }); + } else { + reject('invalid datastore setup'); + } + }); + }); - eme.api.init(); + config.then(function resolve(emeConfig) { + eme.api.init(emeConfig); + }, function reject(reason) { + // no eme.api + }); this.init = function noop() { // avoid multiple init calls diff --git a/apps/search/manifest.webapp b/apps/search/manifest.webapp index 2e323ea6b9ab..aa6789c722bf 100644 --- a/apps/search/manifest.webapp +++ b/apps/search/manifest.webapp @@ -32,5 +32,11 @@ "manifestURLs": ["app://system.gaiamobile.org/manifest.webapp"] } } + }, + "datastores-access": { + "eme_store": { + "readonly": false, + "description": "Stores Everything.me data" + } } }