Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
441
gaia/tests/atoms/gaia_apps.js
Executable file
441
gaia/tests/atoms/gaia_apps.js
Executable file
|
|
@ -0,0 +1,441 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
'use strict';
|
||||
/* globals marionetteScriptFinished, waitFor */
|
||||
|
||||
var GaiaApps = {
|
||||
|
||||
normalizeName: function(name) {
|
||||
return name.replace(/[- ]+/g, '').toLowerCase();
|
||||
},
|
||||
|
||||
getInstalledApps: function() {
|
||||
let req = navigator.mozApps.mgmt.getAll();
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(req.result);
|
||||
};
|
||||
},
|
||||
|
||||
getRunningApps: function(includeSystemApps) {
|
||||
let runningApps = GaiaApps.getApps(includeSystemApps);
|
||||
// Return a simplified version of the runningApps object which can be
|
||||
// JSON-serialized.
|
||||
let apps = {};
|
||||
for (let app in runningApps) {
|
||||
let anApp = {};
|
||||
for (let key in runningApps[app]) {
|
||||
if (['name', 'origin', 'manifest'].indexOf(key) > -1) {
|
||||
anApp[key] = runningApps[app][key];
|
||||
}
|
||||
}
|
||||
apps[runningApps[app].origin] = anApp;
|
||||
}
|
||||
return apps;
|
||||
},
|
||||
|
||||
getApps: function(includeSystemApps) {
|
||||
let service = window.wrappedJSObject.Service;
|
||||
let apps = includeSystemApps ?
|
||||
service.query('getApps') :
|
||||
service.query('snapshot');
|
||||
return apps;
|
||||
},
|
||||
|
||||
getRunningAppOrigin: function(name) {
|
||||
let apps = GaiaApps.getApps(true);
|
||||
|
||||
for (let id in apps) {
|
||||
if (apps[id].name == name) {
|
||||
return apps[id].origin;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
getPermission: function(appName, permissionName) {
|
||||
GaiaApps.locateWithName(appName, function(app) {
|
||||
console.log('Getting permission \'' +
|
||||
permissionName +
|
||||
'\' for ' +
|
||||
appName);
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
var result = mozPerms.get(
|
||||
permissionName, app.manifestURL, app.origin, false
|
||||
);
|
||||
marionetteScriptFinished(result);
|
||||
});
|
||||
},
|
||||
|
||||
setPermission: function(appName, permissionName, value) {
|
||||
GaiaApps.locateWithName(appName, function(app) {
|
||||
console.log('Setting permission \'' + permissionName + '\' for ' +
|
||||
appName + 'to \'' + value + '\'');
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
mozPerms.set(
|
||||
permissionName, value, app.manifestURL, app.origin, false
|
||||
);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
},
|
||||
|
||||
setPermissionByUrl: function(manifestUrl, permissionName, value, entryPoint) {
|
||||
GaiaApps.locateWithManifestURL(manifestUrl, entryPoint, function(app) {
|
||||
console.log('Setting permission \'' + permissionName + '\' for ' +
|
||||
manifestUrl + 'to \'' + value + '\'');
|
||||
var mozPerms = navigator.mozPermissionSettings;
|
||||
mozPerms.set(
|
||||
permissionName, value, app.manifestURL, app.origin, false
|
||||
);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
},
|
||||
|
||||
sendLocateResponse:
|
||||
function(aCallback, app, appName, launchPath, entryPoint) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
if (callback === marionetteScriptFinished) {
|
||||
var result = false;
|
||||
if (typeof(app) === 'object') {
|
||||
result = {
|
||||
name: app.manifest.name,
|
||||
origin: app.origin,
|
||||
entryPoint: entryPoint || null,
|
||||
normalizedName: appName
|
||||
};
|
||||
}
|
||||
callback(result);
|
||||
} else {
|
||||
callback(app, appName, launchPath, entryPoint);
|
||||
}
|
||||
},
|
||||
|
||||
locateWithName: function(name, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
let apps = window.wrappedJSObject.applications ||
|
||||
window.wrappedJSObject.Applications;
|
||||
let installedApps = apps.installedApps;
|
||||
let normalizedSearchName = GaiaApps.normalizeName(name);
|
||||
|
||||
for (let manifestURL in installedApps) {
|
||||
let app = installedApps[manifestURL];
|
||||
let entryPoints = app.manifest.entry_points;
|
||||
if (entryPoints) {
|
||||
for (let ep in entryPoints) {
|
||||
let currentEntryPoint = entryPoints[ep];
|
||||
let appName = currentEntryPoint.name;
|
||||
let launchPath = currentEntryPoint.launch_path;
|
||||
let locales = currentEntryPoint.locales;
|
||||
|
||||
if (normalizedSearchName === GaiaApps.normalizeName(appName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath,
|
||||
ep);
|
||||
} else if (locales) {
|
||||
for (let id in locales) {
|
||||
let localisedAppName = locales[id].name;
|
||||
if (localisedAppName && normalizedSearchName ===
|
||||
GaiaApps.normalizeName(localisedAppName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath,
|
||||
ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let appName = app.manifest.name;
|
||||
let launchPath = app.manifest.launch_path;
|
||||
let locales = app.manifest.locales;
|
||||
|
||||
if (normalizedSearchName === GaiaApps.normalizeName(appName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath);
|
||||
} else if (locales) {
|
||||
for (let id in locales) {
|
||||
let localisedAppName = locales[id].name;
|
||||
if (localisedAppName && normalizedSearchName ===
|
||||
GaiaApps.normalizeName(localisedAppName)) {
|
||||
return GaiaApps.sendLocateResponse(callback,
|
||||
app,
|
||||
appName,
|
||||
launchPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(false);
|
||||
},
|
||||
|
||||
locateWithManifestURL: function(manifestURL, entryPoint, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
var apps = window.wrappedJSObject.applications ||
|
||||
window.wrappedJSObject.Applications;
|
||||
var app = apps.getByManifestURL(manifestURL);
|
||||
var launchPath;
|
||||
|
||||
if (app != null) {
|
||||
GaiaApps._formatApp(app, manifestURL, entryPoint, callback, launchPath);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
},
|
||||
_formatApp: function(app, manifestURL, entryPoint, callback, launchPath) {
|
||||
if (entryPoint) {
|
||||
if (app.manifest.entry_points[entryPoint]) {
|
||||
launchPath = app.manifest.entry_points[entryPoint].launch_path;
|
||||
} else {
|
||||
app = null;
|
||||
}
|
||||
} else {
|
||||
launchPath = app.manifest.launch_path;
|
||||
}
|
||||
GaiaApps.sendLocateResponse(callback, app,
|
||||
manifestURL, launchPath, entryPoint);
|
||||
},
|
||||
|
||||
// Returns the number of running apps.
|
||||
// if includeSystemApps is true then system always-running
|
||||
// apps (eg Homescreen) will be counted
|
||||
numRunningApps: function(includeSystemApps) {
|
||||
return Object.keys(GaiaApps.getApps(includeSystemApps)).length;
|
||||
},
|
||||
|
||||
isRunning: function(origin) {
|
||||
var apps = GaiaApps.getApps(true);
|
||||
for (var id in apps) {
|
||||
if (apps[id].origin === origin) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Kills the specified app.
|
||||
kill: function(aOrigin, aCallback) {
|
||||
var callback = aCallback || marionetteScriptFinished;
|
||||
if (!GaiaApps.isRunning(aOrigin)) {
|
||||
callback(false);
|
||||
}
|
||||
else {
|
||||
window.addEventListener('appterminated', function gt_onAppTerminated() {
|
||||
window.removeEventListener('appterminated', gt_onAppTerminated);
|
||||
waitFor(
|
||||
function() {
|
||||
console.log('app with origin \'' + aOrigin + '\' has terminated');
|
||||
callback(true);
|
||||
},
|
||||
function() {
|
||||
return !GaiaApps.isRunning(aOrigin);
|
||||
}
|
||||
);
|
||||
});
|
||||
console.log('terminating app with origin \'' + aOrigin + '\'');
|
||||
window.wrappedJSObject.Service.request('AppWindowManager:kill', aOrigin);
|
||||
}
|
||||
},
|
||||
|
||||
// Kills all running apps that may be killed by the user, defined as
|
||||
// being accessible by the Cards View/Stack Manager
|
||||
killAll: function() {
|
||||
let originsToClose = [];
|
||||
let that = this;
|
||||
|
||||
let apps = GaiaApps.getApps();
|
||||
for (let id in apps) {
|
||||
let origin = apps[id].origin;
|
||||
originsToClose.push(origin);
|
||||
}
|
||||
|
||||
if (!originsToClose.length) {
|
||||
marionetteScriptFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
originsToClose.slice(0).forEach(function(origin) {
|
||||
GaiaApps.kill(origin, function() {});
|
||||
});
|
||||
|
||||
// Even after the 'appterminated' event has been fired for an app,
|
||||
// it can still exist in the apps list, so wait until 1 or fewer
|
||||
// apps are running (since we don't close the homescreen app).
|
||||
waitFor(
|
||||
function() { marionetteScriptFinished(true); },
|
||||
function() { return that.numRunningApps() <= 1; }
|
||||
);
|
||||
},
|
||||
|
||||
launch: function(app, appName, launchPath, entryPoint) {
|
||||
if (app) {
|
||||
let manifestURL = app.manifestURL;
|
||||
let origin = app.origin;
|
||||
|
||||
let sendResponse = function() {
|
||||
let result = GaiaApps.getDisplayedApp();
|
||||
marionetteScriptFinished(result);
|
||||
};
|
||||
|
||||
let displayedApp = GaiaApps.getDisplayedApp();
|
||||
if ((displayedApp.manifestURL == manifestURL &&
|
||||
displayedApp.entryPoint == entryPoint) ||
|
||||
(!displayedApp.manifestURL && displayedApp.origin == origin)) {
|
||||
console.log(`app with origin: ${displayedApp.origin} and
|
||||
manifestURL: ${displayedApp.manifestURL} and
|
||||
entryPoint: ${displayedApp.entryPoint} is already running`);
|
||||
sendResponse();
|
||||
} else {
|
||||
window.addEventListener('windowopened', function appOpen() {
|
||||
window.removeEventListener('windowopened', appOpen);
|
||||
waitFor(
|
||||
function() {
|
||||
console.log(`app with origin: ${displayedApp.origin} and
|
||||
manifestURL: ${displayedApp.manifestURL} and
|
||||
entryPoint: ${displayedApp.entryPoint} has launched`);
|
||||
sendResponse();
|
||||
},
|
||||
function() {
|
||||
// wait for the displayed app to have expected manifestURL/origin
|
||||
let displayedApp = GaiaApps.getDisplayedApp();
|
||||
if (displayedApp.manifestURL) {
|
||||
return displayedApp.manifestURL == manifestURL &&
|
||||
displayedApp.entryPoint == entryPoint;
|
||||
} else {
|
||||
return displayedApp.origin == origin;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
console.log('launching app with name \'' + appName + '\'');
|
||||
app.launch(entryPoint || null);
|
||||
}
|
||||
} else {
|
||||
marionetteScriptFinished(false);
|
||||
}
|
||||
},
|
||||
|
||||
// Launches app with the specified name (e.g., 'Calculator'); returns the
|
||||
// an object with the app frame if successful, false if the app can't be
|
||||
// found, or times out if the app frame can't be found after launching the
|
||||
// app.
|
||||
launchWithName: function(name) {
|
||||
GaiaApps.locateWithName(name, this.launch.bind(this));
|
||||
},
|
||||
|
||||
// Launches app with the specified manifestURL. returns the
|
||||
// an object with the app frame if successful, false if the app can't be
|
||||
// found, or times out if the app frame can't be found after launching the
|
||||
// app.
|
||||
//
|
||||
// This is prefered over launchWithName because localized builds have
|
||||
// different names
|
||||
launchWithManifestURL: function(manifestURL, entryPoint) {
|
||||
GaiaApps.locateWithManifestURL(manifestURL, entryPoint, this.launch);
|
||||
},
|
||||
|
||||
close: function(app, appName, entryPoint) {
|
||||
if (app) {
|
||||
let origin = GaiaApps.getRunningAppOrigin(appName);
|
||||
GaiaApps.kill(origin);
|
||||
} else {
|
||||
marionetteScriptFinished(false);
|
||||
}
|
||||
},
|
||||
|
||||
// Closes app with the specified name (e.g., 'Calculator'); returns nothing
|
||||
closeWithName: function(name) {
|
||||
GaiaApps.locateWithName(name, this.close);
|
||||
},
|
||||
|
||||
closeWithManifestURL: function(manifestURL, entryPoint) {
|
||||
GaiaApps.locateWithManifestURL(manifestURL, entryPoint, this.close);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the currently displayed app.
|
||||
* This is more like getDisplayedFrame really,
|
||||
* as we return what frame the user is interacting with
|
||||
*/
|
||||
getDisplayedApp: function() {
|
||||
let app = window.wrappedJSObject.Service.query('getTopMostWindow');
|
||||
if (!app || app.isLockscreen) {
|
||||
// fallback to app window.
|
||||
app = window.wrappedJSObject.Service
|
||||
.query('AppWindowManager.getActiveWindow').getTopMostWindow();
|
||||
}
|
||||
|
||||
let currentEntryPoint = null;
|
||||
// When browser is on a website, app.manifest is null
|
||||
if (app.manifest) {
|
||||
let entryPoints = app.manifest.entry_points;
|
||||
if (entryPoints) {
|
||||
for (let ep in entryPoints) {
|
||||
if (entryPoints[ep].launch_path == app.manifest.launch_path) {
|
||||
currentEntryPoint = ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result = {
|
||||
frame: (app.browser) ? app.browser.element : app.frame.firstChild,
|
||||
src: (app.browser) ? app.browser.element.src : app.iframe.src,
|
||||
name: app.name,
|
||||
origin: app.origin,
|
||||
manifestURL: app.manifestURL,
|
||||
entryPoint: currentEntryPoint
|
||||
};
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* Install the app with the specified ManifestURL
|
||||
*/
|
||||
install: function(manifestURL) {
|
||||
let req = navigator.mozApps.install(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished(req.error);
|
||||
};
|
||||
},
|
||||
|
||||
installPackage: function(manifestURL) {
|
||||
let req = navigator.mozApps.installPackage(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished(req.error);
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Uninstall the app with the specified ManifestURL
|
||||
*/
|
||||
uninstall: function(manifestURL) {
|
||||
GaiaApps.locateWithManifestURL(manifestURL, null, function uninstall(app) {
|
||||
if (typeof(app) !== 'object') {
|
||||
// App is already not there, so nothing to do here
|
||||
marionetteScriptFinished(true);
|
||||
return;
|
||||
}
|
||||
|
||||
let req = navigator.mozApps.mgmt.uninstall(app);
|
||||
req.onsuccess = function() {
|
||||
marionetteScriptFinished(true);
|
||||
};
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished(req.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
Loading…
Reference in a new issue