mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-30 18:56:40 +00:00
271 lines
8.4 KiB
JavaScript
271 lines
8.4 KiB
JavaScript
/* 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";
|
|
|
|
var Cc = Components.classes;
|
|
var Ci = Components.interfaces;
|
|
var Cu = Components.utils;
|
|
|
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
Cu.import("resource://gre/modules/Services.jsm");
|
|
Cu.import("resource://gre/modules/MessagesBridge.jsm");
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
|
"resource://gre/modules/FileUtils.jsm");
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "AppsUtils",
|
|
"resource://gre/modules/AppsUtils.jsm");
|
|
|
|
XPCOMUtils.defineLazyServiceGetter(this, "settings",
|
|
"@mozilla.org/settingsService;1",
|
|
"nsISettingsService");
|
|
|
|
function debug() {
|
|
dump("-*- B2GDroidSetup " + Array.slice(arguments) + "\n");
|
|
}
|
|
|
|
function B2GDroidSetup() {
|
|
this.wrappedJSObject = this;
|
|
this.isFirstRun = true;
|
|
}
|
|
|
|
B2GDroidSetup.prototype = {
|
|
classID: Components.ID('{8bc88ef2-3aab-4e94-a40c-e2c80added2c}'),
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
|
Ci.nsISupportsWeakReference]),
|
|
|
|
// Returns a promise that resolves once we have set the wallpaper.image
|
|
// setting in sync with Android's wallpaper.
|
|
setWallpaper: function() {
|
|
if (!this.isFirstRun) {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
debug("Getting wallpaper");
|
|
|
|
Cu.import("resource://gre/modules/Messaging.jsm");
|
|
return Messaging.sendRequestForResult({ type: "Android:GetWallpaper" })
|
|
.then(aData => {
|
|
settings.createLock().set("wallpaper.image", aData.wallpaper, null);
|
|
return Promise.resolve();
|
|
});
|
|
},
|
|
|
|
getApk: function() {
|
|
let registry = Cc["@mozilla.org/chrome/chrome-registry;1"]
|
|
.getService(Ci.nsIChromeRegistry);
|
|
let url = registry.convertChromeURL(
|
|
Services.io.newURI("chrome://b2g/content/shell.html", null, null)).spec;
|
|
// url is something like jar:jar:file:///data/app/org.mozilla.fennec_fabrice-1.apk!/assets/omni.ja!/chrome/chrome/content/shell.html
|
|
// and we just need the apk file path.
|
|
let path = url.substring(url.indexOf("///") + 2, url.indexOf(".apk") + 4);
|
|
debug("apk path: " + path);
|
|
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
|
file.initWithPath(path);
|
|
return file;
|
|
},
|
|
|
|
installWebapps: function(aDir) {
|
|
debug("Extracting webapps");
|
|
let apk = this.getApk();
|
|
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
|
|
.createInstance(Ci.nsIZipReader);
|
|
zipReader.open(apk);
|
|
|
|
// Get the target file for a zip entry, normalizing it to remove the
|
|
// assets/gaia part.
|
|
function getTargetFile(aDir, entry) {
|
|
let target = aDir.clone();
|
|
let part = 0;
|
|
entry.split("/").forEach(aPart => {
|
|
if (part > 1) {
|
|
target.append(aPart);
|
|
}
|
|
part++;
|
|
});
|
|
return target;
|
|
}
|
|
|
|
try {
|
|
// create directories first
|
|
let entries = zipReader.findEntries("assets/gaia/webapps/*");
|
|
while (entries.hasMore()) {
|
|
let entryName = entries.getNext();
|
|
let entry = zipReader.getEntry(entryName);
|
|
let target = getTargetFile(aDir, entryName);
|
|
if (!target.exists() && entry.isDirectory) {
|
|
try {
|
|
debug("Creating " + entryName);
|
|
target.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
|
|
}
|
|
catch (e) {
|
|
debug("extractFiles: failed to create directory " + target.path + " : " + e);
|
|
}
|
|
}
|
|
}
|
|
|
|
entries = zipReader.findEntries("assets/gaia/webapps/*");
|
|
while (entries.hasMore()) {
|
|
let entryName = entries.getNext();
|
|
let target = getTargetFile(aDir, entryName);
|
|
if (target.exists())
|
|
continue;
|
|
|
|
debug("Extracting " + entryName + " to " + target.path);
|
|
zipReader.extract(entryName, target);
|
|
try {
|
|
target.permissions |= FileUtils.PERMS_FILE;
|
|
}
|
|
catch (e) {
|
|
debug("Failed to set permissions " + aPermissions.toString(8) + " on " + target.path);
|
|
}
|
|
}
|
|
}
|
|
finally {
|
|
zipReader.close();
|
|
}
|
|
|
|
debug("Webapps extracted");
|
|
},
|
|
|
|
installSettings: function(aDir) {
|
|
debug("Installing default settings");
|
|
let apk = this.getApk();
|
|
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
|
|
.createInstance(Ci.nsIZipReader);
|
|
zipReader.open(apk);
|
|
|
|
try {
|
|
let dest = aDir.clone();
|
|
dest.append("settings.json")
|
|
zipReader.extract("assets/gaia/settings.json", dest);
|
|
debug("Default settings installed to " + dest.path);
|
|
}
|
|
catch(e) {
|
|
dump("Error extracting settings.json : " + e);
|
|
}
|
|
finally {
|
|
zipReader.close();
|
|
}
|
|
},
|
|
|
|
shellStartup: function(aWindow) {
|
|
Services.androidBridge.browserApp = {
|
|
selectedTab: function() {
|
|
debug("browserApp::selectedTab");
|
|
return null;
|
|
},
|
|
|
|
getBrowserTab: function(aTabId) {
|
|
debug("browserApp::getBrowserTab " + aTabId);
|
|
return null;
|
|
},
|
|
|
|
getPreferences: function(aRequestId, aPrefNames, aCount) {
|
|
debug("browserApp::getPreferences " + uneval(aPrefNames));
|
|
let prefs = [];
|
|
|
|
for (let prefName of aPrefNames) {
|
|
let pref = {
|
|
name: prefName,
|
|
type: "",
|
|
value: null
|
|
};
|
|
|
|
try {
|
|
switch (Services.prefs.getPrefType(prefName)) {
|
|
case Ci.nsIPrefBranch.PREF_BOOL:
|
|
pref.type = "bool";
|
|
pref.value = Services.prefs.getBoolPref(prefName);
|
|
break;
|
|
case Ci.nsIPrefBranch.PREF_INT:
|
|
pref.type = "int";
|
|
pref.value = Services.prefs.getIntPref(prefName);
|
|
break;
|
|
case Ci.nsIPrefBranch.PREF_STRING:
|
|
default:
|
|
pref.type = "string";
|
|
try {
|
|
// Try in case it's a localized string (will throw an exception if not)
|
|
pref.value = Services.prefs.getComplexValue(prefName, Ci.nsIPrefLocalizedString).data;
|
|
} catch (e) {
|
|
pref.value = Services.prefs.getCharPref(prefName);
|
|
}
|
|
break;
|
|
}
|
|
} catch (e) {
|
|
debug("Error reading pref [" + prefName + "]: " + e);
|
|
// preference does not exist; do not send it
|
|
continue;
|
|
}
|
|
|
|
prefs.push(pref);
|
|
}
|
|
|
|
Messaging.sendRequest({
|
|
type: "Preferences:Data",
|
|
requestId: aRequestId, // opaque request identifier, can be any string/int/whatever
|
|
preferences: prefs
|
|
});
|
|
},
|
|
|
|
observePreferences: function(requestId, prefNames, count) {
|
|
debug("browserApp::observePreferences " + prefNames);
|
|
},
|
|
|
|
removePreferenceObservers: function(aRequestId) {
|
|
debug("browserApp::removePreferenceObservers");
|
|
},
|
|
|
|
getUITelemetryObserver: function() {
|
|
debug("browserApp:getUITelemetryObserver");
|
|
return null;
|
|
}
|
|
};
|
|
|
|
Cu.import("resource://gre/modules/Messaging.jsm");
|
|
Messaging.sendRequest({ type: "Launcher:Ready" });
|
|
Messaging.sendRequest({ type: "Gecko:Ready" });
|
|
debug("Sent Gecko:Ready");
|
|
aWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
.getInterface(Ci.nsIDOMWindowUtils).isFirstPaint = true;
|
|
Services.androidBridge.contentDocumentChanged();
|
|
},
|
|
|
|
observe: function (aSubject, aTopic, aData) {
|
|
debug("observer notification: " + aTopic);
|
|
if (aTopic === "shell-startup") {
|
|
this.shellStartup(aSubject);
|
|
return;
|
|
}
|
|
|
|
if (aTopic !== "profile-after-change") {
|
|
return;
|
|
}
|
|
|
|
// At first run of after updates, unpack gaia.
|
|
let branch = Services.prefs.getBranch("b2gdroid");
|
|
if (!AppsUtils.isFirstRun(branch)) {
|
|
debug("No need to unpack gaia again.");
|
|
this.isFirstRun = false;
|
|
return;
|
|
}
|
|
|
|
let profile = Services.dirsvc.get("DefRt", Ci.nsIFile);
|
|
debug("profile directory is " + profile.path);
|
|
|
|
let webapps = profile.clone();
|
|
webapps.append("webapps");
|
|
webapps.append("webapps.json");
|
|
this.installWebapps(profile);
|
|
|
|
let settings = profile.clone();
|
|
settings.append("settings.json");
|
|
this.installSettings(profile);
|
|
}
|
|
};
|
|
|
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GDroidSetup]);
|