This commit is contained in:
Ryan VanderMeulen 2015-08-28 08:50:04 -04:00
Родитель 413bf97b94 402fae4a15
Коммит 9baa6bf56b
165 изменённых файлов: 4525 добавлений и 494 удалений

Просмотреть файл

@ -3,7 +3,7 @@
- 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/. -->
<html xmlns="http://www.w3.org/1999/xhtml "
<html xmlns="http://www.w3.org/1999/xhtml"
id="shell"
windowtype="navigator:browser"
#ifdef ANDROID
@ -25,7 +25,7 @@
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/shell.js"> </script>
#ifndef MOZ_WIDGET_GONK
#ifndef ANDROID
<!-- various task that has to happen only on desktop -->
<script type="application/javascript;version=1.8"
src="chrome://b2g/content/desktop.js"> </script>

Просмотреть файл

@ -232,6 +232,11 @@ var shell = {
},
bootstrap: function() {
#ifdef MOZ_B2GDROID
Cc["@mozilla.org/b2g/b2gdroid-setup;1"]
.getService(Ci.nsIObserver).observe(window, "shell-startup", null);
#endif
window.performance.mark('gecko-shell-bootstrap');
let startManifestURL =
Cc['@mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap']
@ -698,7 +703,8 @@ var shell = {
},
handleCmdLine: function shell_handleCmdLine() {
#ifndef MOZ_WIDGET_GONK
// This isn't supported on devices.
#ifndef ANDROID
let b2gcmds = Cc["@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds"]
.getService(Ci.nsISupports);
let args = b2gcmds.wrappedJSObject.cmdLine;
@ -1054,6 +1060,7 @@ window.addEventListener('ContentStart', function update_onContentStart() {
Cu.import('resource://gre/modules/WebappsUpdater.jsm');
WebappsUpdater.handleContentStart(shell);
#ifdef MOZ_UPDATER
let promptCc = Cc["@mozilla.org/updates/update-prompt;1"];
if (!promptCc) {
return;
@ -1065,6 +1072,7 @@ window.addEventListener('ContentStart', function update_onContentStart() {
}
updatePrompt.wrappedJSObject.handleContentStart(shell);
#endif
});
(function geolocationStatusTracker() {

Просмотреть файл

@ -16,10 +16,15 @@ contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49f
category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
#endif
# On b2gdroid we want to use the android implementation of the directory service.
#ifndef MOZ_B2GDROID
#ifdef MOZ_B2G
# DirectoryProvider.js
component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js
contract @mozilla.org/b2g/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}
category xpcom-directory-providers b2g-directory-provider @mozilla.org/b2g/directory-provider;1
#endif
#endif
# ActivitiesGlue.js
component {3a54788b-48cc-4ab4-93d6-0d6a8ef74f8e} ActivitiesGlue.js
@ -87,6 +92,7 @@ contract @mozilla.org/fxaccounts/fxaccounts-ui-glue;1 {51875c14-91d7-4b8c-b65d-3
component {710322af-e6ae-4b0c-b2c9-1474a87b077e} HelperAppDialog.js
contract @mozilla.org/helperapplauncherdialog;1 {710322af-e6ae-4b0c-b2c9-1474a87b077e}
#ifndef MOZ_B2GDROID
#ifndef MOZ_WIDGET_GONK
component {c83c02c0-5d43-4e3e-987f-9173b313e880} SimulatorScreen.js
contract @mozilla.org/simulator-screen;1 {c83c02c0-5d43-4e3e-987f-9173b313e880}
@ -100,6 +106,7 @@ component {385993fe-8710-4621-9fb1-00a09d8bec37} CommandLine.js
contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds {385993fe-8710-4621-9fb1-00a09d8bec37}
category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
#endif
#endif
# BootstrapCommandLine.js
component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js

Просмотреть файл

@ -32,7 +32,7 @@ EXTRA_COMPONENTS += [
'WebappsUpdateTimer.js',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
EXTRA_COMPONENTS += [
'CommandLine.js',
'OopCommandLine.js',
@ -41,10 +41,14 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
EXTRA_PP_COMPONENTS += [
'B2GComponents.manifest',
'DirectoryProvider.js',
'RecoveryService.js',
]
if CONFIG['MOZ_B2G'] and not CONFIG['MOZ_B2GDROID']:
EXTRA_PP_COMPONENTS += [
'DirectoryProvider.js',
'RecoveryService.js',
]
if CONFIG['MOZ_UPDATER']:
EXTRA_PP_COMPONENTS += [
'UpdatePrompt.js',

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="51ebaf824cc634665c5efcae95b8301ad1758c5e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b4f6fd4afd03161f53c7d2a663750f94762bd238"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "b69c16798ddd7154207f56d983721a327522f5d1",
"git_revision": "fa15462b29258fdec8329bfc367e590022dbc9e5",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "27d2127a81f03614541bfd148daa3002a9010e57",
"revision": "b575200962cb9cc340aa6b704b8f1cc1ac680176",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="51ebaf824cc634665c5efcae95b8301ad1758c5e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b4f6fd4afd03161f53c7d2a663750f94762bd238"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="05a36844c1046a1eb07d5b1325f85ed741f961ea">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b69c16798ddd7154207f56d983721a327522f5d1"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="fa15462b29258fdec8329bfc367e590022dbc9e5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -2,7 +2,8 @@
# 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/.
GAIA_PATH := gaia/profile
# For b2gdroid, gaia ends up in the assets/gaia folder in the APK.
GAIA_PATH := $(if MOZ_B2GDROID,gaia/assets/gaia,gaia/profile)
GENERATED_DIRS += $(DIST)/bin/$(GAIA_PATH)

Просмотреть файл

@ -4,19 +4,21 @@
# 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/.
Program(CONFIG['MOZ_APP_NAME'])
if not CONFIG['MOZ_B2GDROID']:
# b2gdroid does not build a runner executable, but it does build gaia; see Makefile.in.
Program(CONFIG['MOZ_APP_NAME'])
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'run-b2g.cpp',
]
DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
else:
SOURCES += [
'run-b2g.c',
]
DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = '"gaia/profile"'
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'run-b2g.cpp',
]
DEFINES['B2G_NAME'] = 'L"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = 'L"gaia\\\\profile"'
else:
SOURCES += [
'run-b2g.c',
]
DEFINES['B2G_NAME'] = '"%s-bin%s"' % (PROGRAM, CONFIG['BIN_SUFFIX'])
DEFINES['GAIA_PATH'] = '"gaia/profile"'
FAIL_ON_WARNINGS = True

Просмотреть файл

@ -257,22 +257,6 @@ let wrapper = {
this.injectData("message", { status: "can_link_account", data: { ok: ok } });
},
/**
* onSessionStatus sends the currently signed in user's credentials
* to the jelly.
*/
onSessionStatus: function () {
log("Received: 'session_status'.");
fxAccounts.getSignedInUser().then(
(accountData) => {
updateDisplayedEmail(accountData);
this.injectData("message", { status: "session_status", data: accountData });
},
(err) => this.injectData("message", { status: "error", error: err })
);
},
/**
* onSignOut handler erases the current user's session from the fxaccounts service
*/
@ -296,9 +280,6 @@ let wrapper = {
case "can_link_account":
this.onCanLinkAccount(data);
break;
case "session_status":
this.onSessionStatus(data);
break;
case "sign_out":
this.onSignOut(data);
break;

Просмотреть файл

@ -192,7 +192,8 @@ loop.conversationViews = (function(mozL10n) {
/* Prevent event propagation
* stop the click from reaching parent element */
return false;
e.stopPropagation();
e.preventDefault();
},
/*

Просмотреть файл

@ -192,7 +192,8 @@ loop.conversationViews = (function(mozL10n) {
/* Prevent event propagation
* stop the click from reaching parent element */
return false;
e.stopPropagation();
e.preventDefault();
},
/*

Просмотреть файл

@ -11,6 +11,7 @@ describe("loop.store.ConversationAppStore", function () {
beforeEach(function() {
sandbox = sinon.sandbox.create();
dispatcher = new loop.Dispatcher();
sandbox.stub(dispatcher, "dispatch");
});
afterEach(function() {
@ -70,7 +71,7 @@ describe("loop.store.ConversationAppStore", function () {
});
it("should fetch the window type from the mozLoop API", function() {
dispatcher.dispatch(new sharedActions.GetWindowData(fakeGetWindowData));
store.getWindowData(new sharedActions.GetWindowData(fakeGetWindowData));
expect(store.getStoreState()).eql({
windowType: "incoming"
@ -107,7 +108,7 @@ describe("loop.store.ConversationAppStore", function () {
it("should set showFeedbackForm to true when action is triggered", function() {
var showFeedbackFormStub = sandbox.stub(store, "showFeedbackForm");
dispatcher.dispatch(new sharedActions.ShowFeedbackForm());
store.showFeedbackForm(new sharedActions.ShowFeedbackForm());
sinon.assert.calledOnce(showFeedbackFormStub);
});
@ -116,7 +117,7 @@ describe("loop.store.ConversationAppStore", function () {
var clock = sandbox.useFakeTimers();
// Make sure we round down the value.
clock.tick(1001);
dispatcher.dispatch(new sharedActions.ShowFeedbackForm());
store.showFeedbackForm(new sharedActions.ShowFeedbackForm());
sinon.assert.calledOnce(setLoopPrefStub);
sinon.assert.calledWithExactly(setLoopPrefStub,
@ -125,8 +126,6 @@ describe("loop.store.ConversationAppStore", function () {
it("should dispatch a SetupWindowData action with the data from the mozLoop API",
function() {
sandbox.stub(dispatcher, "dispatch");
store.getWindowData(new sharedActions.GetWindowData(fakeGetWindowData));
sinon.assert.calledOnce(dispatcher.dispatch);

Просмотреть файл

@ -270,7 +270,8 @@ describe("loop.conversationViews", function () {
return TestUtils.renderIntoDocument(
React.createElement(loop.conversationViews.CallFailedView, {
dispatcher: dispatcher,
contact: options.contact
contact: options.contact,
outgoing: true
}));
}
@ -646,7 +647,8 @@ describe("loop.conversationViews", function () {
function() {
conversationStore.setStoreState({
callState: CALL_STATES.TERMINATED,
contact: contact
contact: contact,
outgoing: true
});
view = mountTestComponent();
@ -672,7 +674,8 @@ describe("loop.conversationViews", function () {
it("should render the AcceptCallView for incoming calls when the call state is 'alerting'", function() {
conversationStore.setStoreState({
callState: CALL_STATES.ALERTING,
outgoing: false
outgoing: false,
callerId: "fake@invalid.com"
});
view = mountTestComponent();

Просмотреть файл

@ -138,8 +138,9 @@ describe("loop.conversation", function() {
});
describe("AppControllerView", function() {
var conversationStore, client, ccView, dispatcher;
var conversationStore, activeRoomStore, client, ccView, dispatcher;
var conversationAppStore, roomStore, feedbackPeriodMs = 15770000000;
var ROOM_STATES = loop.store.ROOM_STATES;
function mountTestComponent() {
return TestUtils.renderIntoDocument(
@ -169,8 +170,13 @@ describe("loop.conversation", function() {
}]
}});
activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
mozLoop: {},
sdkDriver: {}
});
roomStore = new loop.store.RoomStore(dispatcher, {
mozLoop: navigator.mozLoop
mozLoop: navigator.mozLoop,
activeRoomStore: activeRoomStore
});
conversationAppStore = new loop.store.ConversationAppStore({
dispatcher: dispatcher,
@ -207,6 +213,7 @@ describe("loop.conversation", function() {
it("should display the RoomView for rooms", function() {
conversationAppStore.setStoreState({windowType: "room"});
activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});
ccView = mountTestComponent();

Просмотреть файл

@ -95,7 +95,7 @@
describe("Unexpected Warnings Check", function() {
it("should long only the warnings we expect", function() {
chai.expect(caughtWarnings.length).to.eql(27);
chai.expect(caughtWarnings.length).to.eql(0);
});
});

Просмотреть файл

@ -588,9 +588,18 @@ describe("loop.panel", function() {
}
describe("Copy button", function() {
var roomEntry, copyButton;
var roomStore, roomEntry, copyButton;
beforeEach(function() {
roomStore = new loop.store.RoomStore(dispatcher, {
mozLoop: navigator.mozLoop
});
roomStore.setStoreState({
pendingCreation: false,
pendingInitialRetrieval: false,
rooms: [],
error: undefined
});
roomEntry = mountRoomEntry({
deleteRoom: sandbox.stub(),
room: new loop.store.Room(roomData)

Просмотреть файл

@ -32,7 +32,7 @@ const {
const STRINGS_URI = "chrome://browser/locale/devtools/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
const MILLIS_TIME_FORMAT_MAX_DURATION = 4000;
// The minimum spacing between 2 time graduation headers in the timeline (ms).
// The minimum spacing between 2 time graduation headers in the timeline (px).
const TIME_GRADUATION_MIN_SPACING = 40;
/**
@ -564,9 +564,13 @@ let TimeScale = {
* Add a new animation to time scale.
* @param {Object} state A PlayerFront.state object.
*/
addAnimation: function({startTime, delay, duration, iterationCount}) {
addAnimation: function(state) {
let {startTime, delay, duration, iterationCount, playbackRate} = state;
this.minStartTime = Math.min(this.minStartTime, startTime);
let length = delay + (duration * (!iterationCount ? 1 : iterationCount));
let length = (delay / playbackRate) +
((duration / playbackRate) *
(!iterationCount ? 1 : iterationCount));
this.maxEndTime = Math.max(this.maxEndTime, startTime + length);
},
@ -709,6 +713,7 @@ AnimationsTimeline.prototype = {
},
destroy: function() {
this.stopAnimatingScrubber();
this.unrender();
this.timeHeaderEl.removeEventListener("mousedown",
@ -772,6 +777,8 @@ AnimationsTimeline.prototype = {
},
moveScrubberTo: function(pageX) {
this.stopAnimatingScrubber();
let offset = pageX - this.scrubberEl.offsetWidth;
if (offset < 0) {
offset = 0;
@ -837,6 +844,39 @@ AnimationsTimeline.prototype = {
// Save the targetNode so it can be destroyed later.
this.targetNodes.push(targetNode);
}
// Use the document's current time to position the scrubber (if the server
// doesn't provide it, hide the scrubber entirely).
// Note that because the currentTime was sent via the protocol, some time
// may have gone by since then, and so the scrubber might be a bit late.
let time = this.animations[0].state.documentCurrentTime;
if (!time) {
this.scrubberEl.style.display = "none";
} else {
this.scrubberEl.style.display = "block";
this.startAnimatingScrubber(time);
}
},
startAnimatingScrubber: function(time) {
let x = TimeScale.startTimeToDistance(time, this.timeHeaderEl.offsetWidth);
this.scrubberEl.style.left = x + "px";
if (time < TimeScale.minStartTime ||
time > TimeScale.maxEndTime) {
return;
}
let now = this.win.performance.now();
this.rafID = this.win.requestAnimationFrame(() => {
this.startAnimatingScrubber(time + this.win.performance.now() - now);
});
},
stopAnimatingScrubber: function() {
if (this.rafID) {
this.win.cancelAnimationFrame(this.rafID);
}
},
onAnimationStateChanged: function() {
@ -871,22 +911,26 @@ AnimationsTimeline.prototype = {
drawTimeBlock: function({state}, el) {
let width = el.offsetWidth;
// Container for all iterations and delay. Positioned at the right start
// time.
let x = TimeScale.startTimeToDistance(state.startTime + (state.delay || 0),
width);
// With the right width (duration*duration).
let count = state.iterationCount || 1;
let w = TimeScale.durationToDistance(state.duration, width);
// Create a container element to hold the delay and iterations.
// It is positioned according to its delay (divided by the playbackrate),
// and its width is according to its duration (divided by the playbackrate).
let start = state.startTime;
let duration = state.duration;
let rate = state.playbackRate;
let count = state.iterationCount;
let delay = state.delay || 0;
let x = TimeScale.startTimeToDistance(start + (delay / rate), width);
let w = TimeScale.durationToDistance(duration / rate, width);
let iterations = createNode({
parent: el,
attributes: {
"class": "iterations" + (state.iterationCount ? "" : " infinite"),
"class": "iterations" + (count ? "" : " infinite"),
// Individual iterations are represented by setting the size of the
// repeating linear-gradient.
"style": `left:${x}px;
width:${w * count}px;
width:${w * (count || 1)}px;
background-size:${Math.max(w, 2)}px 100%;`
}
});
@ -895,20 +939,21 @@ AnimationsTimeline.prototype = {
createNode({
parent: iterations,
attributes: {
"class": "name"
"class": "name",
"title": state.name
},
textContent: state.name
});
// Delay.
if (state.delay) {
let delay = TimeScale.durationToDistance(state.delay, width);
if (delay) {
let w = TimeScale.durationToDistance(delay / rate, width);
createNode({
parent: iterations,
attributes: {
"class": "delay",
"style": `left:-${delay}px;
width:${delay}px;`
"style": `left:-${w}px;
width:${w}px;`
}
});
}

Просмотреть файл

@ -4,6 +4,7 @@ subsuite = devtools
support-files =
doc_body_animation.html
doc_frame_script.js
doc_modify_playbackRate.html
doc_simple_animation.html
head.js
@ -38,8 +39,10 @@ support-files =
[browser_animation_timeline_header.js]
[browser_animation_timeline_scrubber_exists.js]
[browser_animation_timeline_scrubber_movable.js]
[browser_animation_timeline_scrubber_moves.js]
[browser_animation_timeline_shows_delay.js]
[browser_animation_timeline_shows_iterations.js]
[browser_animation_timeline_takes_rate_into_account.js]
[browser_animation_timeline_ui.js]
[browser_animation_toggle_button_resets_on_navigate.js]
[browser_animation_toggle_button_toggles_animations.js]

Просмотреть файл

@ -9,12 +9,11 @@
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
yield waitForAllAnimationTargets(panel);
let timeline = panel.animationsTimelineComponent;
let scrubberEl = timeline.scrubberEl;
ok(scrubberEl, "The scrubber element exists");
ok(scrubberEl.classList.contains("scrubber"), "It has the right classname");
is(parseInt(timeline.win.getComputedStyle(scrubberEl).left, 10), 0,
"It's positioned to the left by default");
});

Просмотреть файл

@ -18,21 +18,19 @@ add_task(function*() {
let timeHeaderEl = timeline.timeHeaderEl;
let scrubberEl = timeline.scrubberEl;
let defaultPos = scrubberEl.getBoundingClientRect().left;
info("Mousedown in the header to move the scrubber");
EventUtils.synthesizeMouse(timeHeaderEl, 50, 1, {type: "mousedown"}, win);
let newPos = scrubberEl.getBoundingClientRect().left;
is(newPos - defaultPos, 50, "The scrubber moved on mousedown");
let newPos = parseInt(scrubberEl.style.left);
is(newPos, 50, "The scrubber moved on mousedown");
info("Continue moving the mouse and verify that the scrubber tracks it");
EventUtils.synthesizeMouse(timeHeaderEl, 100, 1, {type: "mousemove"}, win);
newPos = scrubberEl.getBoundingClientRect().left;
is(newPos - defaultPos, 100, "The scrubber followed the mouse");
newPos = parseInt(scrubberEl.style.left);
is(newPos, 100, "The scrubber followed the mouse");
info("Release the mouse and move again and verify that the scrubber stays");
EventUtils.synthesizeMouse(timeHeaderEl, 100, 1, {type: "mouseup"}, win);
EventUtils.synthesizeMouse(timeHeaderEl, 200, 1, {type: "mousemove"}, win);
newPos = scrubberEl.getBoundingClientRect().left;
is(newPos - defaultPos, 100, "The scrubber stopped following the mouse");
newPos = parseInt(scrubberEl.style.left);
is(newPos, 100, "The scrubber stopped following the mouse");
});

Просмотреть файл

@ -0,0 +1,32 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that the scrubber in the timeline-based UI moves when animations are
// playing.
// The animations in the test page last for a very long time, so the test just
// measures the position of the scrubber once, then waits for some time to pass
// and measures its position again.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspectorNewUI();
yield waitForAllAnimationTargets(panel);
let timeline = panel.animationsTimelineComponent;
let win = timeline.win;
let timeHeaderEl = timeline.timeHeaderEl;
let scrubberEl = timeline.scrubberEl;
let startPos = scrubberEl.getBoundingClientRect().left;
info("Wait for some time to check that the scrubber moves");
yield new Promise(r => setTimeout(r, 2000));
let endPos = scrubberEl.getBoundingClientRect().left;
ok(endPos > startPos, "The scrubber has moved");
});

Просмотреть файл

@ -0,0 +1,39 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Check that if an animation has had its playbackRate changed via the DOM, then
// the timeline UI shows the right delay and duration.
// Indeed, the header in the timeline UI always shows the unaltered time,
// because there might be multiple animations displayed at the same time, some
// of which may have a different rate than others. Those that have had their
// rate changed have a delay = delay/rate and a duration = duration/rate.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_modify_playbackRate.html");
let {panel} = yield openAnimationInspectorNewUI();
yield waitForAllAnimationTargets(panel);
let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;
let timeBlocks = timelineEl.querySelectorAll(".time-block");
is(timeBlocks.length, 2, "2 animations are displayed");
info("The first animation has its rate to 1, let's measure it");
let el = timeBlocks[0];
let duration = el.querySelector(".iterations").getBoundingClientRect().width;
let delay = el.querySelector(".delay").getBoundingClientRect().width;
info("The second animation has its rate set to 2, so should be shorter");
let el2 = timeBlocks[1];
let duration2 = el2.querySelector(".iterations").getBoundingClientRect().width;
let delay2 = el2.querySelector(".delay").getBoundingClientRect().width;
is(duration, 2 * duration2, "The duration width is correct");
is(delay, 2 * delay2, "The delay width is correct");
});

Просмотреть файл

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
div {
width: 50px;
height: 50px;
background: blue;
animation: move 20s 20s linear;
animation-fill-mode: forwards;
}
@keyframes move {
to {
margin-left: 200px;
}
}
</style>
</head>
<body>
<div></div>
<div class="rate"></div>
<script>
var el = document.querySelector(".rate");
var ani = el.getAnimations()[0];
ani.playbackRate = 2;
</script>
</body>
</html>

Просмотреть файл

@ -23,22 +23,22 @@ const {findOptimalTimeInterval} = require("devtools/animationinspector/utils");
// interval, this string will be eval'd and tested to be truthy.
const TEST_DATA = [{
desc: "With 1px being 1ms and no minSpacing, expect the interval to be the " +
"default min spacing",
"interval multiple",
timeScale: 1,
minSpacing: undefined,
expectedInterval: 10
expectedInterval: 25
}, {
desc: "With 1px being 1ms and a custom minSpacing being a multiple of 10 " +
desc: "With 1px being 1ms and a custom minSpacing being a multiple of 25 " +
"expect the interval to be the custom min spacing",
timeScale: 1,
minSpacing: 40,
expectedInterval: 40
minSpacing: 50,
expectedInterval: 50
}, {
desc: "With 1px being 1ms and a custom minSpacing not being multiple of 10 " +
desc: "With 1px being 1ms and a custom minSpacing not being multiple of 25 " +
"expect the interval to be the next multiple of 10",
timeScale: 1,
minSpacing: 13,
expectedInterval: 20
minSpacing: 26,
expectedInterval: 50
}, {
desc: "If 1ms corresponds to a distance that is greater than the min " +
"spacing then, expect the interval to be this distance",
@ -48,17 +48,17 @@ const TEST_DATA = [{
}, {
desc: "If 1ms corresponds to a distance that is greater than the min " +
"spacing then, expect the interval to be this distance, even if it " +
"isn't a multiple of 10",
"isn't a multiple of 25",
timeScale: 33,
minSpacing: undefined,
expectedInterval: 33
}, {
desc: "If 1ms is a very small distance, then expect this distance to be " +
"multiplied by 10, 20, 40, 80, etc... until it goes over the min " +
"multiplied by 25, 50, 100, 200, etc... until it goes over the min " +
"spacing",
timeScale: 0.001,
minSpacing: undefined,
expectedInterval: 10.24
expectedInterval: 12.8
}, {
desc: "If the time scale is such that we need to iterate more than the " +
"maximum allowed number of iterations, then expect an interval lower " +

Просмотреть файл

@ -13,17 +13,20 @@ const TEST_ANIMATIONS = [{
startTime: 500,
delay: 0,
duration: 1000,
iterationCount: 1
iterationCount: 1,
playbackRate: 1
}, {
startTime: 400,
delay: 100,
duration: 10,
iterationCount: 100
iterationCount: 100,
playbackRate: 1
}, {
startTime: 50,
delay: 1000,
duration: 100,
iterationCount: 20
iterationCount: 20,
playbackRate: 1
}];
const EXPECTED_MIN_START = 50;
const EXPECTED_MAX_END = 3050;
@ -124,8 +127,8 @@ function run_test() {
equal(TimeScale.maxEndTime, 0);
do_print("Test adding a few animations");
for (let {startTime, delay, duration, iterationCount} of TEST_ANIMATIONS) {
TimeScale.addAnimation({startTime, delay, duration, iterationCount});
for (let state of TEST_ANIMATIONS) {
TimeScale.addAnimation(state);
}
equal(TimeScale.minStartTime, EXPECTED_MIN_START);
equal(TimeScale.maxEndTime, EXPECTED_MAX_END);
@ -136,8 +139,8 @@ function run_test() {
equal(TimeScale.maxEndTime, 0);
do_print("Test adding the animations again");
for (let {startTime, delay, duration, iterationCount} of TEST_ANIMATIONS) {
TimeScale.addAnimation({startTime, delay, duration, iterationCount});
for (let state of TEST_ANIMATIONS) {
TimeScale.addAnimation(state);
}
equal(TimeScale.minStartTime, EXPECTED_MIN_START);
equal(TimeScale.maxEndTime, EXPECTED_MAX_END);

Просмотреть файл

@ -10,7 +10,7 @@
// interval in the timeline graph.
const OPTIMAL_TIME_INTERVAL_MAX_ITERS = 100;
// Background time graduations should be multiple of this number of millis.
const TIME_INTERVAL_MULTIPLE = 10;
const TIME_INTERVAL_MULTIPLE = 25;
const TIME_INTERVAL_SCALES = 3;
// The default minimum spacing between time graduations in px.
const TIME_GRADUATION_MIN_SPACING = 10;

Просмотреть файл

@ -2,56 +2,40 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the waterfall view renders content after recording.
* Tests that the marker details on GC markers displays allocation
* buttons and snaps to the correct range
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { panel } = yield initPerformance(ALLOCS_URL);
let { $, $$, EVENTS, PerformanceController, OverviewView, DetailsView, WaterfallView, MemoryCallTreeView } = panel.panelWin;
let EPSILON = 0.00001;
// Add the Cu.forceGC option to display allocation types for tests
let triggerTypes = Services.prefs.getCharPref("devtools.performance.ui.show-triggers-for-gc-types");
Services.prefs.setCharPref("devtools.performance.ui.show-triggers-for-gc-types", `${triggerTypes} COMPONENT_UTILS`);
// Disable non GC markers so we don't have nested markers and marker index
// matches DOM index.
PerformanceController.setPref("hidden-markers", Array.reduce($$("menuitem"), (disabled, item) => {
let type = item.getAttribute("marker-type");
if (type && type !== "GarbageCollection") {
disabled.push(type);
}
return disabled;
}, []));
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
yield startRecording(panel);
yield waitUntil(hasGCMarkers(PerformanceController));
let rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield idleWait(1000);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
injectGCMarkers(PerformanceController, WaterfallView);
// Select everything
let rendered = WaterfallView.once(EVENTS.WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 0, endTime: Number.MAX_VALUE });
yield rendered;
let bars = $$(".waterfall-marker-bar");
let markers = PerformanceController.getCurrentRecording().getMarkers();
let gcMarkers = markers.filter(isForceGCMarker);
ok(gcMarkers.length >= 2, "should have atleast 2 GC markers");
ok(bars.length >= 2, "should have atleast 2 GC markers rendered");
info("Received markers:");
for (let marker of gcMarkers) {
info(`${marker.causeName} ${marker.start}:${marker.end}`);
}
let gcMarkers = PerformanceController.getCurrentRecording().getMarkers();
ok(gcMarkers.length === 9, "should have 9 GC markers");
ok(bars.length === 9, "should have 9 GC markers rendered");
/**
* Check when it's the first GC marker
* Check when it's the second marker of the first GC cycle.
*/
info(`Will show allocation trigger button for ${Services.prefs.getCharPref("devtools.performance.ui.show-triggers-for-gc-types")}`);
info(`Clicking GC Marker of type ${gcMarkers[0].causeName} ${gcMarkers[0].start}:${gcMarkers[0].end}`);
EventUtils.sendMouseEvent({ type: "mousedown" }, bars[0]);
let targetMarker = gcMarkers[1];
let targetBar = bars[1];
info(`Clicking GC Marker of type ${targetMarker.causeName} ${targetMarker.start}:${targetMarker.end}`);
EventUtils.sendMouseEvent({ type: "mousedown" }, targetBar);
let showAllocsButton;
// On slower machines this can not be found immediately?
yield waitUntil(() => showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']"));
@ -62,7 +46,7 @@ function* spawnTest() {
yield rendered;
is(OverviewView.getTimeInterval().startTime, 0, "When clicking first GC, should use 0 as start time");
within(OverviewView.getTimeInterval().endTime, gcMarkers[0].start, EPSILON, "Correct end time range");
within(OverviewView.getTimeInterval().endTime, targetMarker.start, EPSILON, "Correct end time range");
let duration = PerformanceController.getCurrentRecording().getDuration();
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
@ -71,12 +55,15 @@ function* spawnTest() {
yield rendered;
/**
* Check when there is a previous GC marker
* Check when there is a previous GC cycle
*/
bars = $$(".waterfall-marker-bar");
info(`Clicking GC Marker of type ${gcMarkers[1].causeName} ${gcMarkers[1].start}:${gcMarkers[1].end}`);
EventUtils.sendMouseEvent({ type: "mousedown" }, bars[1]);
targetMarker = gcMarkers[4];
targetBar = bars[4];
info(`Clicking GC Marker of type ${targetMarker.causeName} ${targetMarker.start}:${targetMarker.end}`);
EventUtils.sendMouseEvent({ type: "mousedown" }, targetBar);
// On slower machines this can not be found immediately?
yield waitUntil(() => showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']"));
ok(showAllocsButton, "GC buttons when allocations are enabled");
@ -85,9 +72,9 @@ function* spawnTest() {
EventUtils.sendMouseEvent({ type: "click" }, showAllocsButton);
yield rendered;
within(OverviewView.getTimeInterval().startTime, gcMarkers[0].end, EPSILON,
"selection start range is previous GC marker's end time");
within(OverviewView.getTimeInterval().endTime, gcMarkers[1].start, EPSILON,
within(OverviewView.getTimeInterval().startTime, gcMarkers[2].end, EPSILON,
"selection start range is last marker from previous GC cycle.");
within(OverviewView.getTimeInterval().endTime, targetMarker.start, EPSILON,
"selection end range is current GC marker's start time");
/**
@ -103,19 +90,21 @@ function* spawnTest() {
Services.prefs.setBoolPref(ALLOCATIONS_PREF, false);
yield startRecording(panel);
yield waitUntil(hasGCMarkers(PerformanceController));
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
yield rendered;
injectGCMarkers(PerformanceController, WaterfallView);
// Select everything
rendered = WaterfallView.once(EVENTS.WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 0, endTime: Number.MAX_VALUE });
yield rendered;
ok(true, "WaterfallView rendered after recording is stopped.");
bars = $$(".waterfall-marker-bar");
markers = PerformanceController.getCurrentRecording().getMarkers();
gcMarkers = markers.filter(isForceGCMarker);
gcMarkers = PerformanceController.getCurrentRecording().getMarkers();
EventUtils.sendMouseEvent({ type: "mousedown" }, bars[0]);
showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']");
@ -126,13 +115,30 @@ function* spawnTest() {
finish();
}
function isForceGCMarker (m) {
return m.name === "GarbageCollection" && m.causeName === "COMPONENT_UTILS" && m.start >= 0;
function injectGCMarkers (controller, waterfall) {
// Push some fake GC markers into the recording
let realMarkers = controller.getCurrentRecording().getMarkers();
// Invalidate marker cache
waterfall._cache.delete(realMarkers);
realMarkers.length = 0;
for (let gcMarker of GC_MARKERS) {
realMarkers.push(gcMarker);
}
}
function hasGCMarkers (controller) {
return function () {
Cu.forceGC();
return controller.getCurrentRecording().getMarkers().filter(isForceGCMarker).length >= 2;
};
}
let GC_MARKERS = [
{ causeName: "TOO_MUCH_MALLOC", cycle: 1 },
{ causeName: "TOO_MUCH_MALLOC", cycle: 1 },
{ causeName: "TOO_MUCH_MALLOC", cycle: 1 },
{ causeName: "ALLOC_TRIGGER", cycle: 2 },
{ causeName: "ALLOC_TRIGGER", cycle: 2 },
{ causeName: "ALLOC_TRIGGER", cycle: 2 },
{ causeName: "SET_NEW_DOCUMENT", cycle: 3 },
{ causeName: "SET_NEW_DOCUMENT", cycle: 3 },
{ causeName: "SET_NEW_DOCUMENT", cycle: 3 },
].map((marker, i) => {
marker.name = "GarbageCollection";
marker.start = 50 + (i * 10);
marker.end = marker.start + 9;
return marker;
});

Просмотреть файл

@ -142,22 +142,26 @@ let WaterfallView = Heritage.extend(DetailsSubview, {
let recording = PerformanceController.getCurrentRecording();
let markers = recording.getMarkers();
let mostRecentGC = null;
let lastGCMarkerFromPreviousCycle = null;
let lastGCMarker = null;
// Iterate over markers looking for the most recent GC marker
// before the one who's start time is `endTime`.
// from the cycle before the marker's whose allocations we're interested in.
for (let marker of markers) {
// We found the marker whose allocations we're tracking; abort
if (marker.start === endTime) {
break;
}
if (marker.name === "GarbageCollection") {
mostRecentGC = marker;
if (lastGCMarker && lastGCMarker.cycle !== marker.cycle) {
lastGCMarkerFromPreviousCycle = lastGCMarker;
}
lastGCMarker = marker;
}
}
if (mostRecentGC) {
startTime = mostRecentGC.end;
if (lastGCMarkerFromPreviousCycle) {
startTime = lastGCMarkerFromPreviousCycle.end;
}
// Adjust times so we don't include the range of these markers themselves.

Просмотреть файл

@ -1,166 +1,166 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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/. */
/* global domUtils */
"use strict";
const {Cc, Ci, Cu} = require("chrome");
const {setTimeout, clearTimeout} =
Cu.import("resource://gre/modules/Timer.jsm", {});
const {parseDeclarations} =
require("devtools/styleinspector/css-parsing-utils");
const promise = require("promise");
loader.lazyServiceGetter(this, "domUtils",
"@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
const HTML_NS = "http://www.w3.org/1999/xhtml";
/**
* Create a child element with a set of attributes.
*
* @param {Element} parent
* The parent node.
* @param {string} tagName
* The tag name.
* @param {object} attributes
* A set of attributes to set on the node.
*/
function createChild(parent, tagName, attributes={}) {
let elt = parent.ownerDocument.createElementNS(HTML_NS, tagName);
for (let attr in attributes) {
if (attributes.hasOwnProperty(attr)) {
if (attr === "textContent") {
elt.textContent = attributes[attr];
} else if (attr === "child") {
elt.appendChild(attributes[attr]);
} else {
elt.setAttribute(attr, attributes[attr]);
}
}
}
parent.appendChild(elt);
return elt;
}
exports.createChild = createChild;
/**
* Append a text node to an element.
*
* @param {Element} parent
* The parent node.
* @param {string} text
* The text content for the text node.
*/
function appendText(parent, text) {
parent.appendChild(parent.ownerDocument.createTextNode(text));
}
exports.appendText = appendText;
/**
* Called when a character is typed in a value editor. This decides
* whether to advance or not, first by checking to see if ";" was
* typed, and then by lexing the input and seeing whether the ";"
* would be a terminator at this point.
*
* @param {number} keyCode
* Key code to be checked.
* @param {string} aValue
* Current text editor value.
* @param {number} insertionPoint
* The index of the insertion point.
* @return {Boolean} True if the focus should advance; false if
* the character should be inserted.
*/
function advanceValidate(keyCode, value, insertionPoint) {
// Only ";" has special handling here.
if (keyCode !== Ci.nsIDOMKeyEvent.DOM_VK_SEMICOLON) {
return false;
}
// Insert the character provisionally and see what happens. If we
// end up with a ";" symbol token, then the semicolon terminates the
// value. Otherwise it's been inserted in some spot where it has a
// valid meaning, like a comment or string.
value = value.slice(0, insertionPoint) + ";" + value.slice(insertionPoint);
let lexer = domUtils.getCSSLexer(value);
while (true) {
let token = lexer.nextToken();
if (token.endOffset > insertionPoint) {
if (token.tokenType === "symbol" && token.text === ";") {
// The ";" is a terminator.
return true;
}
// The ";" is not a terminator in this context.
break;
}
}
return false;
}
exports.advanceValidate = advanceValidate;
/**
* Create a throttling function wrapper to regulate its frequency.
*
* @param {Function} func
* The function to throttle
* @param {number} wait
* The throttling period
* @param {Object} scope
* The scope to use for func
* @return {Function} The throttled function
*/
function throttle(func, wait, scope) {
let timer = null;
return function() {
if (timer) {
clearTimeout(timer);
}
let args = arguments;
timer = setTimeout(function() {
timer = null;
func.apply(scope, args);
}, wait);
};
}
exports.throttle = throttle;
/**
* Event handler that causes a blur on the target if the input has
* multiple CSS properties as the value.
*/
function blurOnMultipleProperties(e) {
setTimeout(() => {
let props = parseDeclarations(e.target.value);
if (props.length > 1) {
e.target.blur();
}
}, 0);
}
exports.blurOnMultipleProperties = blurOnMultipleProperties;
/**
* Log the provided error to the console and return a rejected Promise for
* this error.
*
* @param {Error} error
* The error to log
* @return {Promise} A rejected promise
*/
function promiseWarn(error) {
console.error(error);
return promise.reject(error);
}
exports.promiseWarn = promiseWarn;
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* 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/. */
/* global domUtils */
"use strict";
const {Cc, Ci, Cu} = require("chrome");
const {setTimeout, clearTimeout} =
Cu.import("resource://gre/modules/Timer.jsm", {});
const {parseDeclarations} =
require("devtools/styleinspector/css-parsing-utils");
const promise = require("promise");
loader.lazyServiceGetter(this, "domUtils",
"@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
const HTML_NS = "http://www.w3.org/1999/xhtml";
/**
* Create a child element with a set of attributes.
*
* @param {Element} parent
* The parent node.
* @param {string} tagName
* The tag name.
* @param {object} attributes
* A set of attributes to set on the node.
*/
function createChild(parent, tagName, attributes={}) {
let elt = parent.ownerDocument.createElementNS(HTML_NS, tagName);
for (let attr in attributes) {
if (attributes.hasOwnProperty(attr)) {
if (attr === "textContent") {
elt.textContent = attributes[attr];
} else if (attr === "child") {
elt.appendChild(attributes[attr]);
} else {
elt.setAttribute(attr, attributes[attr]);
}
}
}
parent.appendChild(elt);
return elt;
}
exports.createChild = createChild;
/**
* Append a text node to an element.
*
* @param {Element} parent
* The parent node.
* @param {string} text
* The text content for the text node.
*/
function appendText(parent, text) {
parent.appendChild(parent.ownerDocument.createTextNode(text));
}
exports.appendText = appendText;
/**
* Called when a character is typed in a value editor. This decides
* whether to advance or not, first by checking to see if ";" was
* typed, and then by lexing the input and seeing whether the ";"
* would be a terminator at this point.
*
* @param {number} keyCode
* Key code to be checked.
* @param {string} aValue
* Current text editor value.
* @param {number} insertionPoint
* The index of the insertion point.
* @return {Boolean} True if the focus should advance; false if
* the character should be inserted.
*/
function advanceValidate(keyCode, value, insertionPoint) {
// Only ";" has special handling here.
if (keyCode !== Ci.nsIDOMKeyEvent.DOM_VK_SEMICOLON) {
return false;
}
// Insert the character provisionally and see what happens. If we
// end up with a ";" symbol token, then the semicolon terminates the
// value. Otherwise it's been inserted in some spot where it has a
// valid meaning, like a comment or string.
value = value.slice(0, insertionPoint) + ";" + value.slice(insertionPoint);
let lexer = domUtils.getCSSLexer(value);
while (true) {
let token = lexer.nextToken();
if (token.endOffset > insertionPoint) {
if (token.tokenType === "symbol" && token.text === ";") {
// The ";" is a terminator.
return true;
}
// The ";" is not a terminator in this context.
break;
}
}
return false;
}
exports.advanceValidate = advanceValidate;
/**
* Create a throttling function wrapper to regulate its frequency.
*
* @param {Function} func
* The function to throttle
* @param {number} wait
* The throttling period
* @param {Object} scope
* The scope to use for func
* @return {Function} The throttled function
*/
function throttle(func, wait, scope) {
let timer = null;
return function() {
if (timer) {
clearTimeout(timer);
}
let args = arguments;
timer = setTimeout(function() {
timer = null;
func.apply(scope, args);
}, wait);
};
}
exports.throttle = throttle;
/**
* Event handler that causes a blur on the target if the input has
* multiple CSS properties as the value.
*/
function blurOnMultipleProperties(e) {
setTimeout(() => {
let props = parseDeclarations(e.target.value);
if (props.length > 1) {
e.target.blur();
}
}, 0);
}
exports.blurOnMultipleProperties = blurOnMultipleProperties;
/**
* Log the provided error to the console and return a rejected Promise for
* this error.
*
* @param {Error} error
* The error to log
* @return {Promise} A rejected promise
*/
function promiseWarn(error) {
console.error(error);
return promise.reject(error);
}
exports.promiseWarn = promiseWarn;

Просмотреть файл

@ -253,11 +253,14 @@ body {
top: unset;
}
.animation-timeline .animation .animation-title {
height: 1.5em;
.animation-timeline .animation .name {
height: 100%;
width: 100%;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 150%;
padding: 0 2px;
}
.animation-timeline .animation .delay {
@ -284,13 +287,6 @@ body {
background: var(--theme-highlight-lightorange);
}
.animation-timeline .animation .name {
position: absolute;
z-index: 1;
padding: 2px;
white-space: nowrap;
}
/* Animation target node gutter, contains a preview of the dom node */
.animation-target {

Просмотреть файл

@ -25,8 +25,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
'mobile/sutagent/android/watcher',
'mobile/sutagent/android/ffxcp',
'mobile/sutagent/android/fencp',
'mobile/robocop',
]
if not CONFIG['MOZ_B2GDROID']:
TEST_DIRS += [
'mobile/robocop',
]
for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',

Просмотреть файл

@ -3781,6 +3781,7 @@ MOZ_ANDROID_DOWNLOADS_INTEGRATION=
MOZ_ANDROID_MLS_STUMBLER=
MOZ_ANDROID_SHARE_OVERLAY=
MOZ_INSTALL_TRACKING=
MOZ_SWITCHBOARD=
ACCESSIBILITY=1
MOZ_TIME_MANAGER=
MOZ_SIMPLEPUSH=
@ -4038,12 +4039,17 @@ b2g/dev)
;;
esac
if test -n "$MOZ_B2GDROID"; then
AC_DEFINE(MOZ_B2GDROID)
fi
AC_SUBST(MOZ_BUILD_APP)
AC_SUBST(MOZ_PHOENIX)
AC_SUBST(MOZ_XULRUNNER)
AC_SUBST(MOZ_B2G)
AC_SUBST(MOZ_MULET)
AC_SUBST(MOZ_B2G_VERSION)
AC_SUBST(MOZ_B2GDROID)
AC_DEFINE_UNQUOTED(MOZ_BUILD_APP,$MOZ_BUILD_APP)
@ -4063,14 +4069,15 @@ dnl ========================================================
if test -z "$gonkdir" ; then
# Minimum Android SDK API Level we require.
case "$MOZ_BUILD_APP" in
mobile/android)
mobile/android | mobile/android/b2gdroid)
android_min_api_level=20
case "$target" in
*-android*|*-linuxandroid*)
:
;;
*)
AC_MSG_ERROR([You must specify --target=arm-linux-androideabi (or some other valid android target) when building with --enable-application=mobile/android. See https://wiki.mozilla.org/Mobile/Fennec/Android#Setup_Fennec_mozconfig for more information about the necessary options])
AC_MSG_ERROR([You must specify --target=arm-linux-androideabi (or some other valid android target) when building with --enable-application=mobile/android or --enable-application=mobile/android/b2gdroid.
See https://wiki.mozilla.org/Mobile/Fennec/Android#Setup_Fennec_mozconfig for more information about the necessary options])
;;
esac
;;
@ -4871,6 +4878,13 @@ if test -n "$MOZ_INSTALL_TRACKING"; then
AC_DEFINE(MOZ_INSTALL_TRACKING)
fi
dnl ========================================================
dnl = Include Switchboard A/B framework on Android
dnl ========================================================
if test -n "$MOZ_SWITCHBOARD"; then
AC_DEFINE(MOZ_SWITCHBOARD)
fi
dnl ========================================================
dnl = Enable IPDL's "expensive" unit tests
dnl ========================================================
@ -7492,7 +7506,7 @@ fi
AC_SUBST(MOZ_DISABLE_STARTUPCACHE)
dnl ========================================================
dnl = Enable packaging Gaia with B2G desktop
dnl = Enable packaging Gaia with B2G desktop and b2gdroid
dnl ========================================================
if test x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
if test -n "$GAIADIR" -a ! -d "$GAIADIR" ; then
@ -7508,6 +7522,10 @@ if test x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
AC_MSG_ERROR([FXOS_SIMULATOR=1 requires GAIADIR to be defined])
fi
if test "$MOZ_BUILD_APP" = "mobile/android/b2gdroid" -a -z "$GAIADIR"; then
AC_MSG_ERROR([GAIADIR needs to be set in b2gdroid builds])
fi
if test -n "$FXOS_SIMULATOR" ; then
AC_DEFINE(FXOS_SIMULATOR)
AC_SUBST(FXOS_SIMULATOR)
@ -8572,6 +8590,7 @@ AC_SUBST(MOZ_ANDROID_APPLICATION_CLASS)
AC_SUBST(MOZ_ANDROID_BROWSER_INTENT_CLASS)
AC_SUBST(MOZ_ANDROID_SEARCH_INTENT_CLASS)
AC_SUBST(MOZ_INSTALL_TRACKING)
AC_SUBST(MOZ_SWITCHBOARD)
AC_SUBST(ENABLE_STRIP)
AC_SUBST(PKG_SKIP_STRIP)
AC_SUBST(STRIP_FLAGS)

Просмотреть файл

@ -88,6 +88,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "Langpacks",
XPCOMUtils.defineLazyModuleGetter(this, "ImportExport",
"resource://gre/modules/ImportExport.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
#ifdef MOZ_WIDGET_GONK
XPCOMUtils.defineLazyGetter(this, "libcutils", function() {
Cu.import("resource://gre/modules/systemlibs.js");
@ -781,9 +784,9 @@ this.DOMApplicationRegistry = {
}
}
#ifdef MOZ_B2G
yield this.installSystemApps();
#endif
if (AppConstants.MOZ_B2GDROID || AppConstants.MOZ_B2G) {
yield this.installSystemApps();
}
// At first run, install preloaded apps and set up their permissions.
for (let id in this.webapps) {

Просмотреть файл

@ -1757,4 +1757,13 @@ BrowserElementChild.prototype = {
}
};
var api = new BrowserElementChild();
var api = null;
if ('DoPreloadPostfork' in this && typeof this.DoPreloadPostfork === 'function') {
// If we are preloaded, instantiate BrowserElementChild after a content
// process is forked.
this.DoPreloadPostfork(function() {
api = new BrowserElementChild();
});
} else {
api = new BrowserElementChild();
}

Просмотреть файл

@ -2291,11 +2291,7 @@ ContentChild::RecvAppInit()
// PreloadSlowThings() may set the docshell of the first TabChild
// inactive, and we can only safely restore it to active from
// BrowserElementChild.js.
if ((mIsForApp || mIsForBrowser)
#ifdef MOZ_NUWA_PROCESS
&& !IsNuwaProcess()
#endif
) {
if (mIsForApp || mIsForBrowser) {
PreloadSlowThings();
}

Просмотреть файл

@ -23,6 +23,9 @@
#include "mozilla/plugins/PluginWidgetChild.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#ifdef MOZ_NUWA_PROCESS
#include "ipc/Nuwa.h"
#endif
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/layers/APZCCallbackHelper.h"
#include "mozilla/layers/APZCTreeManager.h"
@ -450,10 +453,67 @@ TabChild::FindTabChild(const TabId& aTabId)
return tabChild.forget();
}
static void
PreloadSlowThingsPostFork(void* aUnused)
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
observerService->NotifyObservers(nullptr, "preload-postfork", nullptr);
}
#ifdef MOZ_NUWA_PROCESS
class MessageChannelAutoBlock MOZ_STACK_CLASS
{
public:
MessageChannelAutoBlock()
{
SetMessageChannelBlocked(true);
}
~MessageChannelAutoBlock()
{
SetMessageChannelBlocked(false);
}
private:
void SetMessageChannelBlocked(bool aBlock)
{
if (!IsNuwaProcess()) {
return;
}
mozilla::dom::ContentChild* content =
mozilla::dom::ContentChild::GetSingleton();
if (aBlock) {
content->GetIPCChannel()->Block();
} else {
content->GetIPCChannel()->Unblock();
}
nsTArray<IToplevelProtocol*> actors;
content->GetOpenedActors(actors);
for (size_t j = 0; j < actors.Length(); j++) {
IToplevelProtocol* actor = actors[j];
if (aBlock) {
actor->GetIPCChannel()->Block();
} else {
actor->GetIPCChannel()->Unblock();
}
}
}
};
#endif
static bool sPreloaded = false;
/*static*/ void
TabChild::PreloadSlowThings()
{
MOZ_ASSERT(!sPreallocatedTab);
if (sPreloaded) {
// If we are alredy initialized in Nuwa, don't redo preloading.
return;
}
sPreloaded = true;
// Pass nullptr to aManager since at this point the TabChild is
// not connected to any manager. Any attempt to use the TabChild
@ -465,6 +525,13 @@ TabChild::PreloadSlowThings()
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
return;
}
#ifdef MOZ_NUWA_PROCESS
// Temporarily block the IPC channels to the chrome process when we are
// preloading.
MessageChannelAutoBlock autoblock;
#endif
// Just load and compile these scripts, but don't run them.
tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
// Load, compile, and run these scripts.
@ -472,6 +539,16 @@ TabChild::PreloadSlowThings()
NS_LITERAL_STRING("chrome://global/content/preload.js"),
true);
#ifdef MOZ_NUWA_PROCESS
if (IsNuwaProcess()) {
NuwaAddFinalConstructor(PreloadSlowThingsPostFork, nullptr);
} else {
PreloadSlowThingsPostFork(nullptr);
}
#else
PreloadSlowThingsPostFork(nullptr);
#endif
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(tab->WebNavigation());
if (nsIPresShell* presShell = docShell->GetPresShell()) {
// Initialize and do an initial reflow of the about:blank

Просмотреть файл

@ -9,6 +9,17 @@
const BrowserElementIsPreloaded = true;
const DoPreloadPostfork = function(aCallback) {
Services.obs.addObserver({
_callback: aCallback,
observe: function() {
this._callback();
Services.obs.removeObserver(this, "preload-postfork");
}
}, "preload-postfork", false);
};
(function (global) {
"use strict";
@ -16,7 +27,6 @@ const BrowserElementIsPreloaded = true;
let Cc = Components.classes;
let Ci = Components.interfaces;
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
@ -30,12 +40,10 @@ const BrowserElementIsPreloaded = true;
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
Cc["@mozilla.org/base/telemetry;1"].getService(Ci["nsITelemetry"]);
Cc["@mozilla.org/categorymanager;1"].getService(Ci["nsICategoryManager"]);
Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci["nsIMessageSender"]);
Cc["@mozilla.org/consoleservice;1"].getService(Ci["nsIConsoleService"]);
Cc["@mozilla.org/cookieService;1"].getService(Ci["nsICookieService"]);
Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci["nsIURIFixup"]);
Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci["nsIDOMRequestService"]);
Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci["nsIPromptService"]);
@ -53,14 +61,12 @@ const BrowserElementIsPreloaded = true;
Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci["nsIScriptSecurityManager"]);
Cc["@mozilla.org/storage/service;1"].getService(Ci["mozIStorageService"]);
@ -70,7 +76,6 @@ const BrowserElementIsPreloaded = true;
Cc["@mozilla.org/uriloader;1"].getService(Ci["nsIURILoader"]);
Cc["@mozilla.org/cspcontext;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
Cc["@mozilla.org/settingsManager;1"].createInstance(Ci["nsISupports"]);
Cc["@mozilla.org/webapps;1"].createInstance(Ci["nsISupports"]);
/* Applications Specific Helper */
try {
@ -104,7 +109,44 @@ const BrowserElementIsPreloaded = true;
Services.io.getProtocolHandler("app");
Services.io.getProtocolHandler("default");
docShell.isActive = false;
docShell.createAboutBlankContentViewer(null);
// Register an observer for topic "preload_postfork" after we fork a content
// process.
DoPreloadPostfork(function () {
// Load AppsServiceChild.jsm after fork since it sends an async message to
// the chrome process in its init() function.
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
// Load UserCustomizations.jsm after fork since it sends an async message to
// the chrome process in its init() function.
try {
if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
Cu.import("resource://gre/modules/UserCustomizations.jsm");
}
} catch(e) {}
// Load nsIAppsService after fork since its implementation loads
// AppsServiceChild.jsm
Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
// Load nsICookieService after fork since it sends an IPC constructor
// message to the chrome process.
Cc["@mozilla.org/cookieService;1"].getService(Ci["nsICookieService"]);
// Load nsIPermissionManager after fork since it sends a message to the
// chrome process to read permissions.
Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
// Create this instance after fork since it loads AppsServiceChild.jsm
Cc["@mozilla.org/webapps;1"].createInstance(Ci["nsISupports"]);
// Load nsIProtocolProxyService after fork since it asynchronously accesses
// the "Proxy Resolution" thread after it's frozen.
Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
// Call docShell.createAboutBlankContentViewer() after fork since it has IPC
// activity in the PCompositor protocol.
docShell.createAboutBlankContentViewer(null);
docShell.isActive = false;
});
})(this);

Просмотреть файл

@ -141,7 +141,12 @@ GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
bool
LockScreenOrientation(const ScreenOrientationInternal& aOrientation)
{
switch (aOrientation) {
// Force the default orientation to be portrait-primary.
ScreenOrientationInternal orientation =
aOrientation == eScreenOrientation_Default ? eScreenOrientation_PortraitPrimary
: aOrientation;
switch (orientation) {
// The Android backend only supports these orientations.
case eScreenOrientation_PortraitPrimary:
case eScreenOrientation_PortraitSecondary:
@ -150,7 +155,7 @@ LockScreenOrientation(const ScreenOrientationInternal& aOrientation)
case eScreenOrientation_LandscapeSecondary:
case eScreenOrientation_LandscapePrimary | eScreenOrientation_LandscapeSecondary:
case eScreenOrientation_Default:
mozilla::widget::GeckoAppShell::LockScreenOrientation(aOrientation);
mozilla::widget::GeckoAppShell::LockScreenOrientation(orientation);
return true;
default:
return false;

Просмотреть файл

@ -175,6 +175,16 @@ class MessageChannel : HasResultCodes
sIsPumpingMessages = aIsPumping;
}
#ifdef MOZ_NUWA_PROCESS
void Block() {
mLink->Block();
}
void Unblock() {
mLink->Unblock();
}
#endif
#ifdef OS_WIN
struct MOZ_STACK_CLASS SyncStackFrame
{

Просмотреть файл

@ -16,6 +16,10 @@
#include "mozilla/dom/PContent.h"
#include "mozilla/dom/PNuwa.h"
#include "mozilla/hal_sandbox/PHal.h"
#if defined(DEBUG) || defined(ENABLE_TESTS)
#include "jsprf.h"
extern "C" char* PrintJSStack();
#endif
#endif
#include "mozilla/Assertions.h"
@ -75,6 +79,7 @@ ProcessLink::ProcessLink(MessageChannel *aChan)
, mExistingListener(nullptr)
#ifdef MOZ_NUWA_PROCESS
, mIsToNuwaProcess(false)
, mIsBlocked(false)
#endif
{
}
@ -175,6 +180,8 @@ ProcessLink::SendMessage(Message *msg)
mChan->mMonitor->AssertCurrentThreadOwns();
#ifdef MOZ_NUWA_PROCESS
// Parent to child: check whether we are sending some unexpected message to
// the Nuwa process.
if (mIsToNuwaProcess && mozilla::dom::ContentParent::IsNuwaReady()) {
switch (msg->type()) {
case mozilla::dom::PNuwa::Msg_Fork__ID:
@ -193,6 +200,19 @@ ProcessLink::SendMessage(Message *msg)
#endif
}
}
// Nuwa to parent: check whether we are currently blocked.
if (IsNuwaProcess() && mIsBlocked) {
#if defined(ENABLE_TESTS) || defined(DEBUG)
char* jsstack = PrintJSStack();
printf_stderr("Fatal error: sending a message to the chrome process"
"with a blocked IPC channel from \n%s",
jsstack ? jsstack : "<no JS stack>");
JS_smprintf_free(jsstack);
MOZ_CRASH();
#endif
}
#endif
mIOLoop->PostTask(

Просмотреть файл

@ -128,6 +128,12 @@ class MessageLink
virtual bool Unsound_IsClosed() const = 0;
virtual uint32_t Unsound_NumQueuedMessages() const = 0;
#ifdef MOZ_NUWA_PROCESS
// To be overridden by ProcessLink.
virtual void Block() {}
virtual void Unblock() {}
#endif
protected:
MessageChannel *mChan;
};
@ -175,12 +181,22 @@ class ProcessLink
virtual bool Unsound_IsClosed() const override;
virtual uint32_t Unsound_NumQueuedMessages() const override;
#ifdef MOZ_NUWA_PROCESS
void Block() override {
mIsBlocked = true;
}
void Unblock() override {
mIsBlocked = false;
}
#endif
protected:
Transport* mTransport;
MessageLoop* mIOLoop; // thread where IO happens
Transport::Listener* mExistingListener; // channel's previous listener
#ifdef MOZ_NUWA_PROCESS
bool mIsToNuwaProcess;
bool mIsBlocked;
#endif
};

Просмотреть файл

@ -235,6 +235,8 @@ public:
void GetOpenedActors(nsTArray<IToplevelProtocol*>& aActors);
virtual MessageChannel* GetIPCChannel() = 0;
// This Unsafe version should only be used when all other threads are
// frozen, since it performs no locking. It also takes a stack-allocated
// array and its size (number of elements) rather than an nsTArray. The Nuwa

Просмотреть файл

@ -14,7 +14,7 @@ if CONFIG['MOZ_PKG_SPECIAL']:
DEFINES['MOZ_PKG_SPECIAL'] = CONFIG['MOZ_PKG_SPECIAL']
JS_PREFERENCE_FILES += [
'mobile.js',
'mobile.js',
]
DIST_FILES += [

Просмотреть файл

@ -0,0 +1,21 @@
# vim: set filetype=python:
# 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/.
if not CONFIG['LIBXUL_SDK']:
include('/toolkit/toolkit.mozbuild')
elif CONFIG['ENABLE_TESTS']:
DIRS += ['/testing/mochitest']
if CONFIG['ENABLE_TESTS']:
DIRS += ['/testing/instrumentation']
if CONFIG['MOZ_EXTENSIONS']:
DIRS += ['/extensions']
DIRS += [
'/%s' % CONFIG['MOZ_BRANDING_DIRECTORY'],
'/mobile/android/b2gdroid',
]

Просмотреть файл

@ -0,0 +1,33 @@
# 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/.
ANDROID_MANIFEST_FILE := src/main/AndroidManifest.xml
JAVAFILES := \
src/main/java/org/mozilla/b2gdroid/Launcher.java \
$(NULL)
# The GeckoView consuming APK depends on the GeckoView JAR files. There are two
# issues: first, the GeckoView JAR files need to be built before they are
# consumed here. This happens for delicate reasons. In the (serial) libs tier,
# base/ is traversed before b2gdroid/app. Since base/libs builds classes.dex,
# the underlying JAR files are built before the libs tier of b2gdroid/app is
# processed. Second, there is a correctness issue: the GeckoView JAR providing
# org.mozilla.gecko.R does not have the correct resource IDs for the consuming
# application, so we skip it. The b2gdroid APK builds a JAR containing
# org.mozilla.gecko.R itself.
jars_dir := $(DEPTH)/mobile/android/base
ANDROID_EXTRA_JARS := $(filter-out %gecko-R.jar,$(wildcard $(jars_dir)/*.jar))
# The GeckoView consuming APK depends on the GeckoView resources. This hacks a
# type of poor man's AAR support.
.aapt.deps: .geckoview_resources.deps
.geckoview_resources.deps: $(DEPTH)/mobile/android/base/geckoview_resources.zip
@$(TOUCH) $@
$(UNZIP) -u -o $< -d $(CURDIR)/geckoview_resources
include $(topsrcdir)/config/rules.mk
libs:: $(ANDROID_APK_NAME).apk

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,30 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
ANDROID_APK_NAME = 'b2gdroid'
ANDROID_APK_PACKAGE = 'org.mozilla.b2gdroid'
ANDROID_RES_DIRS += [
'src/main/res',
'!geckoview_resources',
]
ANDROID_ASSETS_DIRS += [
'src/main/assets',
'!/dist/bin/gaia/assets', # We must have built /b2g/gaia before building app/.
]
# Make aapt generate org/mozilla/gecko/R.java. There's a problem hidden here:
# the GeckoView classes may reference resources provided by other packages.
# That is, the GeckoView JAR files may reference android.support.v7.appcompat.R
# (say) at runtime. That class is in the gecko-R.jar file which is not (and can
# not!) be included as part of GeckoView. To avoid this, we'd need to include
# the transitive set of resource classes. For now, let's assume that b2gdroid
# will not induce accesses to other package's resources at runtime.
ANDROID_EXTRA_PACKAGES += ['org.mozilla.gecko']
JS_PREFERENCE_FILES += [
'b2gdroid.js',
]

Просмотреть файл

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mozilla.b2gdroid"
android:installLocation="auto"
>
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="22"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen"/>
<!-- Contacts API -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Tab Queue -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!-- Android Beam support -->
<uses-permission android:name="android.permission.NFC"/>
<uses-feature android:name="android.hardware.nfc" android:required="false"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-feature android:name="android.hardware.audio.low_latency" android:required="false"/>
<uses-feature android:name="android.hardware.camera.any" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<!-- App requires OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<!-- Needed to disable the default lockscreen -->
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application android:label="@string/b2g"
android:icon="@drawable/b2g"
android:logo="@drawable/b2g"
android:hardwareAccelerated="true"
android:debuggable="true">
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true"/>
<activity android:name="org.mozilla.b2gdroid.Launcher"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:icon="@drawable/b2g"
android:label="@string/b2g">
<!-- Set up as a homescreen replacement -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- Default browser intents -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="about" />
<data android:scheme="javascript" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:mimeType="text/html"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="application/xhtml+xml"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.WEB_SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="" />
<data android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
<!-- We will route the search intent to Gaia -->
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
</application>
</manifest>

Просмотреть файл

@ -0,0 +1 @@
Example asset!

Просмотреть файл

@ -0,0 +1,152 @@
package org.mozilla.b2gdroid;
import java.io.ByteArrayOutputStream;
import java.util.Iterator;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardLock;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import org.mozilla.gecko.BaseGeckoInterface;
import org.mozilla.gecko.ContextGetter;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoBatteryManager;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.IntentHelper;
import org.mozilla.gecko.util.GeckoEventListener;
public class Launcher extends Activity
implements GeckoEventListener, ContextGetter {
private static final String LOGTAG = "B2G";
/** ContextGetter */
public Context getContext() {
return this;
}
public SharedPreferences getSharedPreferences() {
return null;
}
/** Initializes Gecko APIs */
private void initGecko() {
GeckoAppShell.setContextGetter(this);
GeckoBatteryManager.getInstance().start(this);
}
private void hideSplashScreen() {
final View splash = findViewById(R.id.splashscreen);
runOnUiThread(new Runnable() {
@Override public void run() {
splash.setVisibility(View.GONE);
}
});
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.w(LOGTAG, "onCreate");
super.onCreate(savedInstanceState);
IntentHelper.init(this);
// Disable the default lockscreen.
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard();
initGecko();
GeckoAppShell.setGeckoInterface(new BaseGeckoInterface(this));
EventDispatcher.getInstance().registerGeckoThreadListener(this,
"Launcher:Ready");
setContentView(R.layout.launcher);
}
@Override
public void onResume() {
super.onResume();
if (GeckoThread.isRunning()) {
hideSplashScreen();
}
}
@Override
public void onDestroy() {
Log.w(LOGTAG, "onDestroy");
super.onDestroy();
IntentHelper.destroy();
EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
"Launcher:Ready");
}
@Override
protected void onNewIntent (Intent intent) {
final String action = intent.getAction();
Log.w(LOGTAG, "onNewIntent " + action);
if (Intent.ACTION_VIEW.equals(action)) {
Log.w(LOGTAG, "Asking gecko to view " + intent.getDataString());
JSONObject obj = new JSONObject();
try {
obj.put("action", "view");
obj.put("url", intent.getDataString());
} catch(Exception ex) {
Log.wtf(LOGTAG, "Error building Android:Launcher view message", ex);
}
GeckoEvent e = GeckoEvent.createBroadcastEvent("Android:Launcher", obj.toString());
GeckoAppShell.sendEventToGecko(e);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
findViewById(R.id.main_layout).setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
public void handleMessage(String event, JSONObject message) {
Log.w(LOGTAG, "Launcher received " + event);
if ("Launcher:Ready".equals(event)) {
hideSplashScreen();
}
}
}

Двоичные данные
mobile/android/b2gdroid/app/src/main/res/drawable-xhdpi/b2g.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Просмотреть файл

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/main_layout">
<org.mozilla.gecko.GeckoView android:id="@+id/gecko_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<RelativeLayout android:id="@+id/splashscreen"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:id="@+id/splashscreen_icon"
android:minWidth="128dip"
android:minHeight="128dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/b2g"/>
<ProgressBar android:id="@+id/splashscreen_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:paddingBottom="30dip"/>
</RelativeLayout>
</RelativeLayout>

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="b2g">Firefox OS</string>
</resources>

Просмотреть файл

@ -0,0 +1,8 @@
# 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/.
ANDROID_PACKAGE_NAME=org.mozilla.b2gdroid_`echo $USER | sed 's/-/_/g'`
MOZ_APP_DISPLAYNAME="B2GDroid `echo $USER | sed 's/-/_/g'`"
MOZ_UPDATER=1
MOZ_ANDROID_ANR_REPORTER=

Двоичные данные
mobile/android/b2gdroid/branding/unofficial/content/about.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Двоичные данные
mobile/android/b2gdroid/branding/unofficial/content/favicon32.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
mobile/android/b2gdroid/branding/unofficial/content/favicon64.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.9 KiB

Просмотреть файл

@ -0,0 +1,9 @@
# 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/.
chrome.jar:
% content branding %content/branding/
content/branding/about.png (about.png)
content/branding/favicon32.png (favicon32.png)
content/branding/favicon64.png (favicon64.png)

Просмотреть файл

@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
JAR_MANIFESTS += ['jar.mn']

Просмотреть файл

@ -0,0 +1,7 @@
<!-- 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/. -->
<!ENTITY brandShortName "B2GDroid">
<!ENTITY brandFullName "Mozilla B2GDroid">
<!ENTITY vendorShortName "Mozilla">

Просмотреть файл

@ -0,0 +1,6 @@
# 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/.
brandShortName=B2GDroid
brandFullName=Mozilla B2GDroid

Просмотреть файл

@ -0,0 +1,11 @@
#filter substitution
# 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/.
@AB_CD@.jar:
% locale branding @AB_CD@ %locale/branding/
# Nightly branding only exists in en-US
locale/branding/brand.dtd (en-US/brand.dtd)
locale/branding/brand.properties (en-US/brand.properties)

Просмотреть файл

@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
JAR_MANIFESTS += ['jar.mn']

Просмотреть файл

@ -0,0 +1,7 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIRS += ['content', 'locales']

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 21 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Просмотреть файл

@ -0,0 +1,63 @@
# 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/.
include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
installer:
@$(MAKE) -C mobile/android/b2gdroid/installer installer
package:
@$(MAKE) -C mobile/android/b2gdroid/installer
ifeq ($(OS_TARGET),Android)
ifneq ($(MOZ_ANDROID_INSTALL_TARGET),)
ANDROID_SERIAL = $(MOZ_ANDROID_INSTALL_TARGET)
endif
ifneq ($(ANDROID_SERIAL),)
export ANDROID_SERIAL
else
# Determine if there's more than one device connected
android_devices=$(filter device,$(shell $(ADB) devices))
ifeq ($(android_devices),)
install::
@echo 'No devices are connected. Connect a device or start an emulator.'
@exit 1
else
ifneq ($(android_devices),device)
install::
@echo 'Multiple devices are connected. Define ANDROID_SERIAL to specify the install target.'
$(ADB) devices
@exit 1
endif
endif
endif
install::
$(ADB) install -r $(DIST)/$(PKG_PATH)$(PKG_BASENAME).apk
else
@echo 'B2GDroid can't be installed directly.'
@exit 1
endif
deb: package
@$(MAKE) -C mobile/android/b2gdroid/installer deb
upload::
@$(MAKE) -C mobile/android/b2gdroid/installer upload
ifdef ENABLE_TESTS
# Implemented in testing/testsuite-targets.mk
mochitest-browser-chrome:
$(RUN_MOCHITEST) --browser-chrome
$(CHECK_TEST_ERROR)
mochitest:: mochitest-browser-chrome
.PHONY: mochitest-browser-chrome
endif
ifeq ($(OS_TARGET),Linux)
deb: installer
endif

Просмотреть файл

@ -0,0 +1,244 @@
/* 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";
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppsUtils",
"resource://gre/modules/AppsUtils.jsm");
function debug() {
dump("-*- B2GDroidSetup " + Array.slice(arguments) + "\n");
}
function B2GDroidSetup() { }
B2GDroidSetup.prototype = {
classID: Components.ID('{8bc88ef2-3aab-4e94-a40c-e2c80added2c}'),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
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.");
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]);

Просмотреть файл

@ -0,0 +1,4 @@
# Setup.js
component {8bc88ef2-3aab-4e94-a40c-e2c80added2c} Setup.js
contract @mozilla.org/b2g/b2gdroid-setup;1 {8bc88ef2-3aab-4e94-a40c-e2c80added2c}
category profile-after-change B2GDroidSetup @mozilla.org/b2g/b2gdroid-setup;1

Просмотреть файл

@ -0,0 +1,8 @@
# 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/.
EXTRA_COMPONENTS += [
'b2gdroid.manifest',
'Setup.js',
]

Просмотреть файл

@ -0,0 +1,124 @@
# 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/.
MOZ_APP_BASENAME=B2GDroid
MOZ_APP_VENDOR=Mozilla
MOZ_B2GDROID=1
MOZ_B2G=1
MOZ_APP_VERSION=43.0a1
MOZ_APP_UA_NAME=Firefox
MOZ_UA_OS_AGNOSTIC=1
MOZ_B2G_VERSION=2.5.0.0-prerelease
MOZ_B2G_OS_NAME=Boot2Gecko
MOZ_BRANDING_DIRECTORY=mobile/android/b2gdroid/branding/unofficial
MOZ_OFFICIAL_BRANDING_DIRECTORY=mobile/android/b2gdroid/branding/official
# MOZ_APP_DISPLAYNAME is set by branding/configure.sh
# We support Android SDK version 9 and up by default.
# See the --enable-android-min-sdk and --enable-android-max-sdk arguments in configure.in.
MOZ_ANDROID_MIN_SDK_VERSION=9
# There are several entry points into the Firefox application. These are the names of some of the classes that are
# listed in the Android manifest. They are specified in here to avoid hard-coding them in source code files.
MOZ_ANDROID_APPLICATION_CLASS=org.mozilla.gecko.GeckoApplication
MOZ_ANDROID_BROWSER_INTENT_CLASS=org.mozilla.gecko.BrowserApp
MOZ_ANDROID_SEARCH_INTENT_CLASS=org.mozilla.search.SearchActivity
MOZ_SAFE_BROWSING=1
MOZ_NO_SMART_CARDS=1
# Enable getUserMedia
MOZ_MEDIA_NAVIGATOR=1
# Enable NFC permission
MOZ_ANDROID_BEAM=1
if test "$LIBXUL_SDK"; then
MOZ_XULRUNNER=1
else
MOZ_XULRUNNER=
fi
MOZ_CAPTURE=1
MOZ_RAW=1
MOZ_PLACES=
MOZ_SOCIAL=
MOZ_ANDROID_HISTORY=1
MOZ_DISABLE_EXPORT_JS=1
# use custom widget for html:select
MOZ_USE_NATIVE_POPUP_WINDOWS=1
MOZ_APP_ID={f7b06d8d-139c-459a-85fa-46bc6c52e2b7}
MOZ_APP_STATIC_INI=1
# Enable on-demand decompression. This requires a host compile toolchain to
# build szip to use during packaging.
if test "$COMPILE_ENVIRONMENT"; then
MOZ_ENABLE_SZIP=1
fi
# Enable navigator.mozPay
MOZ_PAY=1
# Enable UI for healthreporter
MOZ_SERVICES_HEALTHREPORT=1
# Enable runtime locale switching.
MOZ_LOCALE_SWITCHER=1
# Enable second screen and casting support for external devices.
MOZ_DEVICES=1
# Enable second screen using native Android libraries, provided we're
# not resource constrained.
if test -z "$MOZ_ANDROID_RESOURCE_CONSTRAINED"; then
MOZ_NATIVE_DEVICES=1
fi
# Enable install tracking SDK if we have Google Play support; MOZ_NATIVE_DEVICES
# is a proxy flag for that support.
if test "$RELEASE_BUILD"; then
if test "$MOZ_NATIVE_DEVICES"; then
MOZ_INSTALL_TRACKING=1
fi
fi
# Mark as WebGL conformant
MOZ_WEBGL_CONFORMANT=1
# Enable the share handler.
MOZ_ANDROID_SHARE_OVERLAY=1
# Enable Tab Queue
if test "$NIGHTLY_BUILD"; then
MOZ_ANDROID_TAB_QUEUE=1
fi
# Use the low-memory GC tuning.
export JS_GC_SMALL_CHUNK_SIZE=1
# Enable FxAccount Avatar
if test "$NIGHTLY_BUILD"; then
MOZ_ANDROID_FIREFOX_ACCOUNT_PROFILES=1
fi
# Enable checking that add-ons are signed by the trusted root
MOZ_ADDON_SIGNING=1
if test "$MOZ_OFFICIAL_BRANDING"; then
if test "$MOZ_UPDATE_CHANNEL" = "beta" -o \
"$MOZ_UPDATE_CHANNEL" = "release"; then
MOZ_REQUIRE_SIGNING=1
fi
fi
MOZ_JSDOWNLOADS=1
MOZ_TIME_MANAGER=1

Просмотреть файл

@ -0,0 +1,86 @@
# 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/.
STANDALONE_MAKEFILE := 1
# overwrite mobile-l10n.js with a matchOS=true one for multi-locale builds
ifeq ($(AB_CD),multi)
L10N_PREF_JS_EXPORTS = $(srcdir)/mobile-l10n.js
L10N_PREF_JS_EXPORTS_PATH = $(FINAL_TARGET)/$(PREF_DIR)
L10N_PREF_JS_EXPORTS_FLAGS = $(PREF_PPFLAGS) --silence-missing-directive-warnings
PP_TARGETS += L10N_PREF_JS_EXPORTS
endif
include $(topsrcdir)/config/rules.mk
MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in
MOZ_PKG_MANIFEST_P = $(srcdir)/package-manifest.in
DEFINES += \
-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
-DPREF_DIR=$(PREF_DIR) \
-DJAREXT= \
-DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME) \
-DMOZ_CHILD_PROCESS_NAME_PIE=$(MOZ_CHILD_PROCESS_NAME_PIE) \
-DANDROID_CPU_ARCH=$(ANDROID_CPU_ARCH) \
$(NULL)
ifdef MOZ_DEBUG
DEFINES += -DMOZ_DEBUG=1
endif
ifdef MOZ_PKG_MANIFEST_P
MOZ_PKG_MANIFEST = package-manifest
endif
MOZ_PACKAGER_MINIFY=1
include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
# Note that JS_BINARY can be defined in packager.mk, so this test must come
# after including that file. MOZ_PACKAGER_MINIFY_JS is used in packager.mk, but
# since recipe evaluation is deferred, we can set it here after the inclusion.
ifneq (,$(JS_BINARY))
ifndef MOZ_DEBUG
ifndef NIGHTLY_BUILD
MOZ_PACKAGER_MINIFY_JS=1
endif
endif
endif
ifeq (bundle, $(MOZ_FS_LAYOUT))
BINPATH = $(_BINPATH)
DEFINES += -DAPPNAME=$(_APPNAME)
else
# Every other platform just winds up in dist/bin
BINPATH = bin
endif
DEFINES += -DBINPATH=$(BINPATH)
ifdef ENABLE_MARIONETTE
DEFINES += -DENABLE_MARIONETTE=1
endif
ifdef MOZ_PKG_MANIFEST_P
# When MOZ_CHROME_MULTILOCALE is defined, we write multilocale.json like:
# {"locales": ["en-US", "de", "ar", ...]}
$(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) $(GLOBAL_DEPS) FORCE
$(call py_action,preprocessor,$(DEFINES) $(ACDEFINES) $< -o $@)
ifdef MOZ_CHROME_MULTILOCALE
printf '\n[multilocale]\n' >> $@
printf '@BINPATH@/res/multilocale.json\n' >> $@
for LOCALE in en-US $(MOZ_CHROME_MULTILOCALE) ;\
do \
printf '$(BINPATH)/chrome/'"$$LOCALE"'$(JAREXT)\n' >> $@; \
printf '$(BINPATH)/chrome/'"$$LOCALE"'.manifest\n' >> $@; \
done
COMMA=,
echo '{"locales": [$(foreach l,$(MOZ_CHROME_MULTILOCALE),"$(l)"$(COMMA)) "en-US"]}' \
> $(FINAL_TARGET)/res/multilocale.json
endif
GARBAGE += $(MOZ_PKG_MANIFEST)
endif

Просмотреть файл

@ -0,0 +1,6 @@
/* 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/. */
// Inherit locale from the OS, used for multi-locale builds
pref("intl.locale.matchOS", true);

Просмотреть файл

@ -0,0 +1,6 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.

Просмотреть файл

@ -0,0 +1,717 @@
; 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/.
; Package file for the Fennec build.
;
; File format:
;
; [] designates a toplevel component. Example: [xpcom]
; - in front of a file specifies it to be removed from the destination
; * wildcard support to recursively copy the entire directory
; ; file comment
;
#filter substitution
[@AB_CD@]
@BINPATH@/chrome/@AB_CD@@JAREXT@
@BINPATH@/chrome/@AB_CD@.manifest
@BINPATH@/@PREF_DIR@/mobile-l10n.js
@BINPATH@/searchplugins/*
@BINPATH@/defaults/profile/bookmarks.html
@BINPATH@/defaults/profile/localstore.rdf
@BINPATH@/defaults/profile/mimeTypes.rdf
@BINPATH@/defaults/profile/chrome/*
#ifdef MOZ_UPDATER
@BINPATH@/update.locale
@BINPATH@/updater.ini
#endif
@BINPATH@/dictionaries/*
@BINPATH@/hyphenation/*
[assets destdir="assets/@ANDROID_CPU_ARCH@"]
#ifndef MOZ_STATIC_JS
@BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
#endif
#ifdef MOZ_DMD
@BINPATH@/@DLL_PREFIX@dmd@DLL_SUFFIX@
#endif
#ifndef MOZ_FOLD_LIBS
@BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
#endif
@BINPATH@/@DLL_PREFIX@lgpllibs@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxplugin@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxplugingb@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxplugingb235@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginhc@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@omxpluginkk@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
#ifndef MOZ_FOLD_LIBS
@BINPATH@/@DLL_PREFIX@nssutil3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@smime3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
#endif
@BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
#ifndef CROSS_COMPILE
@BINPATH@/@DLL_PREFIX@freebl3.chk
@BINPATH@/@DLL_PREFIX@softokn3.chk
#endif
#ifndef NSS_DISABLE_DBM
@BINPATH@/@DLL_PREFIX@nssdbm3@DLL_SUFFIX@
#ifndef CROSS_COMPILE
@BINPATH@/@DLL_PREFIX@nssdbm3.chk
#endif
#endif
#ifndef MOZ_FOLD_LIBS
@BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
#endif
[lib destdir="lib/@ANDROID_CPU_ARCH@"]
@BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
# This should be MOZ_CHILD_PROCESS_NAME, but that has a "lib/" prefix.
@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
@BINPATH@/@MOZ_CHILD_PROCESS_NAME_PIE@
[xpcom]
@BINPATH@/dependentlibs.list
@BINPATH@/AndroidManifest.xml
@BINPATH@/resources.arsc
@BINPATH@/package-name.txt
@BINPATH@/classes.dex
@BINPATH@/res/drawable
@BINPATH@/res/drawable-hdpi
@BINPATH@/res/layout
@BINPATH@/distribution/*
[browser]
; [Base Browser Files]
#ifndef XP_UNIX
@BINPATH@/@MOZ_APP_NAME@.exe
#else
@BINPATH@/@MOZ_APP_NAME@-bin
@BINPATH@/@MOZ_APP_NAME@
#endif
@BINPATH@/application.ini
@BINPATH@/platform.ini
@BINPATH@/blocklist.xml
#ifdef XP_UNIX
@BINPATH@/run-mozilla.sh
#endif
; [Components]
@BINPATH@/components/components.manifest
@BINPATH@/components/alerts.xpt
#ifdef ACCESSIBILITY
@BINPATH@/components/accessibility.xpt
#endif
@BINPATH@/components/appshell.xpt
@BINPATH@/components/appstartup.xpt
@BINPATH@/components/autocomplete.xpt
@BINPATH@/components/autoconfig.xpt
@BINPATH@/components/browsercompsbase.xpt
@BINPATH@/components/browser-element.xpt
@BINPATH@/components/browser-feeds.xpt
@BINPATH@/components/caps.xpt
@BINPATH@/components/chardet.xpt
@BINPATH@/components/chrome.xpt
@BINPATH@/components/commandhandler.xpt
@BINPATH@/components/commandlines.xpt
@BINPATH@/components/composer.xpt
@BINPATH@/components/content_events.xpt
@BINPATH@/components/content_geckomediaplugins.xpt
@BINPATH@/components/content_html.xpt
@BINPATH@/components/content_webrtc.xpt
@BINPATH@/components/content_xslt.xpt
@BINPATH@/components/cookie.xpt
@BINPATH@/components/devtools_security.xpt
@BINPATH@/components/directory.xpt
@BINPATH@/components/docshell.xpt
@BINPATH@/components/dom.xpt
@BINPATH@/components/dom_activities.xpt
@BINPATH@/components/dom_apps.xpt
@BINPATH@/components/dom_base.xpt
@BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt
@BINPATH@/components/dom_events.xpt
@BINPATH@/components/dom_geolocation.xpt
@BINPATH@/components/dom_media.xpt
@BINPATH@/components/dom_messages.xpt
@BINPATH@/components/dom_network.xpt
@BINPATH@/components/dom_notification.xpt
@BINPATH@/components/dom_html.xpt
@BINPATH@/components/dom_offline.xpt
@BINPATH@/components/dom_json.xpt
@BINPATH@/components/dom_payment.xpt
@BINPATH@/components/dom_power.xpt
@BINPATH@/components/dom_quota.xpt
@BINPATH@/components/dom_range.xpt
@BINPATH@/components/dom_security.xpt
@BINPATH@/components/dom_settings.xpt
@BINPATH@/components/dom_permissionsettings.xpt
@BINPATH@/components/dom_sidebar.xpt
@BINPATH@/components/dom_mobilemessage.xpt
@BINPATH@/components/dom_storage.xpt
@BINPATH@/components/dom_stylesheets.xpt
@BINPATH@/components/dom_system.xpt
@BINPATH@/components/dom_threads.xpt
@BINPATH@/components/dom_traversal.xpt
@BINPATH@/components/dom_tv.xpt
@BINPATH@/components/dom_views.xpt
#ifdef MOZ_WEBSPEECH
@BINPATH@/components/dom_webspeechrecognition.xpt
#endif
@BINPATH@/components/dom_xbl.xpt
@BINPATH@/components/dom_xpath.xpt
@BINPATH@/components/dom_xul.xpt
#ifdef MOZ_GAMEPAD
@BINPATH@/components/dom_gamepad.xpt
#endif
@BINPATH@/components/dom_presentation.xpt
@BINPATH@/components/downloads.xpt
@BINPATH@/components/editor.xpt
@BINPATH@/components/embed_base.xpt
@BINPATH@/components/extensions.xpt
@BINPATH@/components/exthandler.xpt
@BINPATH@/components/exthelper.xpt
@BINPATH@/components/fastfind.xpt
@BINPATH@/components/feeds.xpt
@BINPATH@/components/find.xpt
@BINPATH@/components/fuel.xpt
@BINPATH@/components/gfx.xpt
@BINPATH@/components/html5.xpt
@BINPATH@/components/htmlparser.xpt
@BINPATH@/components/imglib2.xpt
@BINPATH@/components/inspector.xpt
@BINPATH@/components/intl.xpt
@BINPATH@/components/jar.xpt
@BINPATH@/components/jsdebugger.xpt
@BINPATH@/components/jsdownloads.xpt
@BINPATH@/components/jsinspector.xpt
@BINPATH@/components/layout_base.xpt
#ifdef NS_PRINTING
@BINPATH@/components/layout_printing.xpt
#endif
@BINPATH@/components/layout_xul_tree.xpt
@BINPATH@/components/layout_xul.xpt
@BINPATH@/components/locale.xpt
@BINPATH@/components/lwbrk.xpt
@BINPATH@/components/migration.xpt
@BINPATH@/components/mimetype.xpt
@BINPATH@/components/mozfind.xpt
@BINPATH@/components/necko_about.xpt
@BINPATH@/components/necko_cache.xpt
@BINPATH@/components/necko_cache2.xpt
@BINPATH@/components/necko_cookie.xpt
@BINPATH@/components/necko_dns.xpt
@BINPATH@/components/necko_file.xpt
@BINPATH@/components/necko_ftp.xpt
@BINPATH@/components/necko_http.xpt
@BINPATH@/components/necko_mdns.xpt
@BINPATH@/components/necko_res.xpt
@BINPATH@/components/necko_socket.xpt
@BINPATH@/components/necko_strconv.xpt
@BINPATH@/components/necko_viewsource.xpt
@BINPATH@/components/necko_websocket.xpt
@BINPATH@/components/necko_wifi.xpt
@BINPATH@/components/necko_wyciwyg.xpt
@BINPATH@/components/necko.xpt
@BINPATH@/components/loginmgr.xpt
@BINPATH@/components/parentalcontrols.xpt
#ifdef MOZ_WEBRTC
@BINPATH@/components/peerconnection.xpt
#endif
@BINPATH@/components/plugin.xpt
@BINPATH@/components/pref.xpt
@BINPATH@/components/prefetch.xpt
#ifdef MOZ_ENABLE_PROFILER_SPS
@BINPATH@/components/profiler.xpt
#endif
@BINPATH@/components/proxyObject.xpt
@BINPATH@/components/rdf.xpt
@BINPATH@/components/satchel.xpt
@BINPATH@/components/saxparser.xpt
@BINPATH@/components/sessionstore.xpt
@BINPATH@/components/services-crypto-component.xpt
@BINPATH@/components/captivedetect.xpt
@BINPATH@/components/shellservice.xpt
@BINPATH@/components/shistory.xpt
@BINPATH@/components/spellchecker.xpt
@BINPATH@/components/storage.xpt
@BINPATH@/components/telemetry.xpt
@BINPATH@/components/toolkit_asyncshutdown.xpt
@BINPATH@/components/toolkit_filewatcher.xpt
@BINPATH@/components/toolkit_finalizationwitness.xpt
@BINPATH@/components/toolkit_formautofill.xpt
@BINPATH@/components/toolkit_osfile.xpt
#ifdef NIGHTLY_BUILD
@BINPATH@/components/toolkit_perfmonitoring.xpt
#endif
@BINPATH@/components/toolkit_xulstore.xpt
@BINPATH@/components/toolkitprofile.xpt
#ifdef MOZ_ENABLE_XREMOTE
@BINPATH@/components/toolkitremote.xpt
#endif
@BINPATH@/components/txtsvc.xpt
@BINPATH@/components/txmgr.xpt
@BINPATH@/components/uconv.xpt
@BINPATH@/components/unicharutil.xpt
@BINPATH@/components/update.xpt
@BINPATH@/components/uriloader.xpt
@BINPATH@/components/urlformatter.xpt
@BINPATH@/components/webBrowser_core.xpt
@BINPATH@/components/webbrowserpersist.xpt
@BINPATH@/components/webshell_idls.xpt
@BINPATH@/components/widget.xpt
@BINPATH@/components/widget_android.xpt
@BINPATH@/components/windowds.xpt
@BINPATH@/components/windowwatcher.xpt
@BINPATH@/components/xpcom_base.xpt
@BINPATH@/components/xpcom_system.xpt
@BINPATH@/components/xpcom_components.xpt
@BINPATH@/components/xpcom_ds.xpt
@BINPATH@/components/xpcom_io.xpt
@BINPATH@/components/xpcom_threads.xpt
@BINPATH@/components/xpcom_xpti.xpt
@BINPATH@/components/xpconnect.xpt
@BINPATH@/components/xulapp.xpt
@BINPATH@/components/xul.xpt
@BINPATH@/components/xultmpl.xpt
@BINPATH@/components/zipwriter.xpt
; JavaScript components
@BINPATH@/components/RequestSync.manifest
@BINPATH@/components/RequestSyncManager.js
@BINPATH@/components/RequestSyncScheduler.js
@BINPATH@/components/ChromeNotifications.js
@BINPATH@/components/ChromeNotifications.manifest
@BINPATH@/components/ConsoleAPI.manifest
@BINPATH@/components/ConsoleAPIStorage.js
@BINPATH@/components/ContactManager.js
@BINPATH@/components/ContactManager.manifest
@BINPATH@/components/PhoneNumberService.js
@BINPATH@/components/PhoneNumberService.manifest
@BINPATH@/components/NotificationStorage.js
@BINPATH@/components/NotificationStorage.manifest
@BINPATH@/components/SettingsManager.js
@BINPATH@/components/SettingsManager.manifest
@BINPATH@/components/BrowserElementParent.manifest
@BINPATH@/components/BrowserElementParent.js
@BINPATH@/components/FeedProcessor.manifest
@BINPATH@/components/FeedProcessor.js
@BINPATH@/components/BrowserFeeds.manifest
@BINPATH@/components/FeedConverter.js
@BINPATH@/components/FeedWriter.js
@BINPATH@/components/PermissionSettings.js
@BINPATH@/components/PermissionSettings.manifest
@BINPATH@/components/PermissionPromptService.js
@BINPATH@/components/PermissionPromptService.manifest
@BINPATH@/components/fuelApplication.manifest
@BINPATH@/components/fuelApplication.js
@BINPATH@/components/WebContentConverter.js
@BINPATH@/components/BrowserComponents.manifest
@BINPATH@/components/nsBrowserContentHandler.js
@BINPATH@/components/nsBrowserGlue.js
@BINPATH@/components/nsDNSServiceDiscovery.manifest
@BINPATH@/components/nsDNSServiceDiscovery.js
@BINPATH@/components/nsSetDefaultBrowser.manifest
@BINPATH@/components/nsSetDefaultBrowser.js
@BINPATH@/components/toolkitsearch.manifest
@BINPATH@/components/nsSearchService.js
@BINPATH@/components/nsSearchSuggestions.js
@BINPATH@/components/passwordmgr.manifest
@BINPATH@/components/nsLoginInfo.js
@BINPATH@/components/nsLoginManager.js
@BINPATH@/components/nsLoginManagerPrompter.js
@BINPATH@/components/storage-mozStorage.js
@BINPATH@/components/crypto-SDR.js
@BINPATH@/components/jsconsole-clhandler.manifest
@BINPATH@/components/jsconsole-clhandler.js
@BINPATH@/components/nsHelperAppDlg.manifest
@BINPATH@/components/nsHelperAppDlg.js
@BINPATH@/components/NetworkGeolocationProvider.manifest
@BINPATH@/components/NetworkGeolocationProvider.js
@BINPATH@/components/nsSidebar.manifest
@BINPATH@/components/nsSidebar.js
@BINPATH@/components/extensions.manifest
@BINPATH@/components/addonManager.js
@BINPATH@/components/amContentHandler.js
@BINPATH@/components/amInstallTrigger.js
@BINPATH@/components/amWebInstallListener.js
@BINPATH@/components/nsBlocklistService.js
#ifndef RELEASE_BUILD
@BINPATH@/components/TabSource.js
#endif
@BINPATH@/components/webvtt.xpt
@BINPATH@/components/WebVTT.manifest
@BINPATH@/components/WebVTTParserWrapper.js
#ifdef MOZ_UPDATER
@BINPATH@/components/nsUpdateService.manifest
@BINPATH@/components/nsUpdateService.js
@BINPATH@/components/nsUpdateServiceStub.js
#endif
@BINPATH@/components/nsUpdateTimerManager.manifest
@BINPATH@/components/nsUpdateTimerManager.js
@BINPATH@/components/pluginGlue.manifest
@BINPATH@/components/ProcessSingleton.manifest
@BINPATH@/components/MainProcessSingleton.js
@BINPATH@/components/ContentProcessSingleton.js
@BINPATH@/components/nsSessionStore.manifest
@BINPATH@/components/nsSessionStartup.js
@BINPATH@/components/nsSessionStore.js
@BINPATH@/components/nsURLFormatter.manifest
@BINPATH@/components/nsURLFormatter.js
@BINPATH@/components/@DLL_PREFIX@browsercomps@DLL_SUFFIX@
@BINPATH@/components/txEXSLTRegExFunctions.manifest
@BINPATH@/components/txEXSLTRegExFunctions.js
@BINPATH@/components/nsDefaultCLH.manifest
@BINPATH@/components/nsDefaultCLH.js
@BINPATH@/components/nsContentPrefService.manifest
@BINPATH@/components/nsContentPrefService.js
@BINPATH@/components/nsContentDispatchChooser.manifest
@BINPATH@/components/nsContentDispatchChooser.js
@BINPATH@/components/nsHandlerService.manifest
@BINPATH@/components/nsHandlerService.js
@BINPATH@/components/nsWebHandlerApp.manifest
@BINPATH@/components/nsWebHandlerApp.js
@BINPATH@/components/satchel.manifest
@BINPATH@/components/nsFormAutoComplete.js
@BINPATH@/components/nsFormHistory.js
@BINPATH@/components/FormHistoryStartup.js
@BINPATH@/components/nsInputListAutoComplete.js
@BINPATH@/components/formautofill.manifest
@BINPATH@/components/FormAutofillContentService.js
@BINPATH@/components/FormAutofillStartup.js
@BINPATH@/components/CSSUnprefixingService.js
@BINPATH@/components/CSSUnprefixingService.manifest
@BINPATH@/components/contentAreaDropListener.manifest
@BINPATH@/components/contentAreaDropListener.js
@BINPATH@/components/messageWakeupService.js
@BINPATH@/components/messageWakeupService.manifest
#ifdef MOZ_ENABLE_DBUS
@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
#endif
@BINPATH@/components/nsINIProcessor.manifest
@BINPATH@/components/nsINIProcessor.js
@BINPATH@/components/nsPrompter.manifest
@BINPATH@/components/nsPrompter.js
@BINPATH@/components/servicesComponents.manifest
@BINPATH@/components/cryptoComponents.manifest
@BINPATH@/components/TelemetryStartup.js
@BINPATH@/components/TelemetryStartup.manifest
@BINPATH@/components/XULStore.js
@BINPATH@/components/XULStore.manifest
@BINPATH@/components/Webapps.js
@BINPATH@/components/Webapps.manifest
@BINPATH@/components/AppsService.js
@BINPATH@/components/AppsService.manifest
@BINPATH@/components/htmlMenuBuilder.js
@BINPATH@/components/htmlMenuBuilder.manifest
@BINPATH@/components/Activities.manifest
@BINPATH@/components/ActivitiesGlue.js
@BINPATH@/components/ActivityProxy.js
@BINPATH@/components/ActivityRequestHandler.js
@BINPATH@/components/ActivityWrapper.js
@BINPATH@/components/ActivityMessageConfigurator.js
@BINPATH@/components/TCPSocket.js
@BINPATH@/components/TCPSocketParentIntermediary.js
@BINPATH@/components/TCPServerSocket.js
@BINPATH@/components/TCPSocket.manifest
#ifdef MOZ_WEBRTC
@BINPATH@/components/PeerConnection.js
@BINPATH@/components/PeerConnection.manifest
#endif
#ifdef MOZ_SERVICES_HEALTHREPORT
@BINPATH@/components/HealthReportComponents.manifest
@BINPATH@/components/HealthReportService.js
#endif
@BINPATH@/components/CaptivePortalDetectComponents.manifest
@BINPATH@/components/captivedetect.js
#ifdef MOZ_WEBSPEECH
@BINPATH@/components/dom_webspeechsynth.xpt
#endif
#ifdef MOZ_DEBUG
@BINPATH@/components/TestInterfaceJS.js
@BINPATH@/components/TestInterfaceJS.manifest
@BINPATH@/components/TestInterfaceJSMaplike.js
#endif
@BINPATH@/components/nsAsyncShutdown.manifest
@BINPATH@/components/nsAsyncShutdown.js
@BINPATH@/components/Downloads.manifest
@BINPATH@/components/DownloadLegacy.js
@BINPATH@/components/PresentationDeviceInfoManager.manifest
@BINPATH@/components/PresentationDeviceInfoManager.js
@BINPATH@/components/BuiltinProviders.manifest
@BINPATH@/components/TCPPresentationServer.js
@BINPATH@/components/PACGenerator.js
@BINPATH@/components/PACGenerator.manifest
; Modules
@BINPATH@/modules/*
#ifdef MOZ_SAFE_BROWSING
; Safe Browsing
@BINPATH@/components/nsURLClassifier.manifest
@BINPATH@/components/nsUrlClassifierHashCompleter.js
@BINPATH@/components/nsUrlClassifierListManager.js
@BINPATH@/components/nsUrlClassifierLib.js
@BINPATH@/components/PrivateBrowsingTrackingProtectionWhitelist.js
@BINPATH@/components/url-classifier.xpt
#endif
; GNOME hooks
#ifdef MOZ_ENABLE_GNOME_COMPONENT
@BINPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
#endif
; [Browser Chrome Files]
@BINPATH@/chrome/browser@JAREXT@
@BINPATH@/chrome/browser.manifest
#ifdef NIGHTLY_BUILD
@BINPATH@/chrome/shumway.manifest
@BINPATH@/chrome/shumway/*
#endif
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
@BINPATH@/chrome/toolkit@JAREXT@
@BINPATH@/chrome/toolkit.manifest
#ifdef XP_UNIX
@BINPATH@/chrome/icons/default/default16.png
@BINPATH@/chrome/icons/default/default32.png
@BINPATH@/chrome/icons/default/default48.png
#endif
; shell icons
#ifdef XP_UNIX
@BINPATH@/icons/*.xpm
@BINPATH@/icons/*.png
#endif
; [Default Preferences]
; All the pref files must be part of base to prevent migration bugs
@BINPATH@/@PREF_DIR@/mobile.js
@BINPATH@/@PREF_DIR@/mobile-branding.js
@BINPATH@/@PREF_DIR@/channel-prefs.js
@BINPATH@/ua-update.json
@BINPATH@/greprefs.js
@BINPATH@/defaults/autoconfig/prefcalls.js
@BINPATH@/defaults/profile/prefs.js
; [Layout Engine Resources]
; Style Sheets, Graphics and other Resources used by the layout engine.
@BINPATH@/res/EditorOverride.css
@BINPATH@/res/contenteditable.css
@BINPATH@/res/designmode.css
@BINPATH@/res/TopLevelImageDocument.css
@BINPATH@/res/TopLevelVideoDocument.css
@BINPATH@/res/table-add-column-after-active.gif
@BINPATH@/res/table-add-column-after-hover.gif
@BINPATH@/res/table-add-column-after.gif
@BINPATH@/res/table-add-column-before-active.gif
@BINPATH@/res/table-add-column-before-hover.gif
@BINPATH@/res/table-add-column-before.gif
@BINPATH@/res/table-add-row-after-active.gif
@BINPATH@/res/table-add-row-after-hover.gif
@BINPATH@/res/table-add-row-after.gif
@BINPATH@/res/table-add-row-before-active.gif
@BINPATH@/res/table-add-row-before-hover.gif
@BINPATH@/res/table-add-row-before.gif
@BINPATH@/res/table-remove-column-active.gif
@BINPATH@/res/table-remove-column-hover.gif
@BINPATH@/res/table-remove-column.gif
@BINPATH@/res/table-remove-row-active.gif
@BINPATH@/res/table-remove-row-hover.gif
@BINPATH@/res/table-remove-row.gif
@BINPATH@/res/grabber.gif
@BINPATH@/res/dtd/*
@BINPATH@/res/html/*
@BINPATH@/res/language.properties
@BINPATH@/res/entityTables/*
#ifdef NIGHTLY_BUILD
@BINPATH@/res/text_caret.png
@BINPATH@/res/text_caret@1.5x.png
@BINPATH@/res/text_caret@2.25x.png
@BINPATH@/res/text_caret@2x.png
@BINPATH@/res/text_caret_tilt_left.png
@BINPATH@/res/text_caret_tilt_left@1.5x.png
@BINPATH@/res/text_caret_tilt_left@2.25x.png
@BINPATH@/res/text_caret_tilt_left@2x.png
@BINPATH@/res/text_caret_tilt_right.png
@BINPATH@/res/text_caret_tilt_right@1.5x.png
@BINPATH@/res/text_caret_tilt_right@2.25x.png
@BINPATH@/res/text_caret_tilt_right@2x.png
#endif
#ifndef MOZ_ANDROID_EXCLUDE_FONTS
@BINPATH@/res/fonts/*
#endif
; svg
@BINPATH@/res/svg.css
@BINPATH@/components/dom_svg.xpt
@BINPATH@/components/dom_smil.xpt
; [Personal Security Manager]
;
@BINPATH@/components/pipboot.xpt
@BINPATH@/components/pipnss.xpt
; For process sandboxing
#if defined(MOZ_SANDBOX)
@BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
#endif
; for Solaris SPARC
#ifdef SOLARIS
bin/libfreebl_32fpu_3.chk
bin/libfreebl_32fpu_3.so
bin/libfreebl_32int_3.chk
bin/libfreebl_32int_3.so
bin/libfreebl_32int64_3.chk
bin/libfreebl_32int64_3.so
#endif
; [Updater]
;
#ifdef MOZ_UPDATER
@BINPATH@/updater@BIN_SUFFIX@
#endif
; [Crash Reporter]
;
#ifdef MOZ_CRASHREPORTER
@BINPATH@/components/CrashService.manifest
@BINPATH@/components/CrashService.js
@BINPATH@/crashreporter@BIN_SUFFIX@
@BINPATH@/crashreporter.crt
@BINPATH@/crashreporter.ini
#ifdef XP_UNIX
@BINPATH@/Throbber-small.gif
#endif
@BINPATH@/crashreporter-override.ini
#endif
[mobile]
@BINPATH@/chrome/icons/
@BINPATH@/chrome/chrome@JAREXT@
@BINPATH@/chrome/chrome.manifest
@BINPATH@/components/AboutRedirector.js
@BINPATH@/components/AddonUpdateService.js
@BINPATH@/components/BlocklistPrompt.js
@BINPATH@/components/BrowserCLH.js
@BINPATH@/components/ColorPicker.js
@BINPATH@/components/ContentDispatchChooser.js
@BINPATH@/components/ContentPermissionPrompt.js
@BINPATH@/components/DirectoryProvider.js
@BINPATH@/components/FilePicker.js
@BINPATH@/components/HelperAppDialog.js
@BINPATH@/components/LoginManagerPrompter.js
@BINPATH@/components/MobileComponents.manifest
@BINPATH@/components/MobileComponents.xpt
@BINPATH@/components/NSSDialogService.js
@BINPATH@/components/PromptService.js
@BINPATH@/components/SessionStore.js
@BINPATH@/components/Sidebar.js
@BINPATH@/components/SiteSpecificUserAgent.js
@BINPATH@/components/Snippets.js
@BINPATH@/components/Payment.js
@BINPATH@/components/PaymentFlowInfo.js
@BINPATH@/components/PaymentProvider.js
@BINPATH@/components/Payment.manifest
@BINPATH@/components/PaymentsUI.js
@BINPATH@/components/PaymentProviderStrategy.js
#ifdef MOZ_SAFE_BROWSING
@BINPATH@/components/SafeBrowsing.jsm
#endif
@BINPATH@/components/XPIDialogService.js
@BINPATH@/components/browsercomps.xpt
#ifdef ENABLE_MARIONETTE
@BINPATH@/chrome/marionette@JAREXT@
@BINPATH@/chrome/marionette.manifest
@BINPATH@/components/MarionetteComponents.manifest
@BINPATH@/components/marionettecomponent.js
#endif
@BINPATH@/components/DataStore.manifest
@BINPATH@/components/DataStoreImpl.js
@BINPATH@/components/dom_datastore.xpt
# b2g and b2gdroid components
@BINPATH@/components/b2gdroid.manifest
@BINPATH@/components/Setup.js
@BINPATH@/components/dom_alarm.xpt
@BINPATH@/components/AlarmsManager.js
@BINPATH@/components/AlarmsManager.manifest
@BINPATH@/components/InterAppComm.manifest
@BINPATH@/components/InterAppCommService.js
@BINPATH@/components/InterAppConnection.js
@BINPATH@/components/InterAppMessagePort.js
@BINPATH@/components/nsDOMIdentity.js
@BINPATH@/components/nsIDService.js
@BINPATH@/components/Identity.manifest
@BINPATH@/components/SystemMessageInternal.js
@BINPATH@/components/SystemMessageManager.js
@BINPATH@/components/SystemMessageCache.js
@BINPATH@/components/SystemMessageManager.manifest
@BINPATH@/components/B2GComponents.manifest
@BINPATH@/components/AlertsService.js
@BINPATH@/components/ContentPermissionPrompt.js
@BINPATH@/components/ActivitiesGlue.js
@BINPATH@/components/InterAppCommUIGlue.js
@BINPATH@/components/SystemMessageGlue.js
@BINPATH@/components/ProcessGlobal.js
@BINPATH@/components/OMAContentHandler.js
@BINPATH@/components/PaymentGlue.js
@BINPATH@/components/TelProtocolHandler.js
@BINPATH@/components/SmsProtocolHandler.js
@BINPATH@/components/MailtoProtocolHandler.js
@BINPATH@/components/RecoveryService.js
@BINPATH@/components/B2GAboutRedirector.js
@BINPATH@/components/FilePicker.js
@BINPATH@/components/WebappsUpdateTimer.js
@BINPATH@/components/FxAccountsUIGlue.js
@BINPATH@/components/HelperAppDialog.js
@BINPATH@/components/MobileIdentityUIGlue.js
@BINPATH@/components/B2GAppMigrator.js
@BINPATH@/components/B2GPresentationDevicePrompt.js
@BINPATH@/components/BootstrapCommandLine.js
#ifdef MOZ_UPDATER
@BINPATH@/components/UpdatePrompt.js
#endif
@BINPATH@/components/DownloadsAPI.js
@BINPATH@/components/DownloadsAPI.manifest
; InputMethod API
@BINPATH@/components/MozKeyboard.js
@BINPATH@/components/InputMethod.manifest
@BINPATH@/@PREF_DIR@/b2gdroid.js

Просмотреть файл

@ -0,0 +1,4 @@
update.locale
README.txt
defaults/preferences/healthreport-prefs.js
components/dom_webspeech.xpt

Просмотреть файл

@ -0,0 +1,29 @@
# 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/.
CONFIGURE_SUBST_FILES += ['installer/Makefile']
# These are used to localize the GeckoView Android and Gecko resources, but not
# yet to localize the b2gdroid Android resources.
DIRS += [
'../../locales',
'../locales',
]
DIRS += [
'components',
'../components',
'../modules',
'../javaaddons',
'../base',
'../fonts',
'../geckoview_library',
'/b2g/components',
'/b2g/chrome',
'/b2g/gaia',
# We must build the libs target of app after building the libs target of
# /b2g/gaia, since the gaia directory is packed into the APK as an assets/
# directory. This relies on the serial nature of the libs tier recursion.
'app',
]

Просмотреть файл

@ -324,6 +324,13 @@ public class AppConstants {
false;
//#endif
public static final boolean MOZ_SWITCHBOARD =
//#ifdef MOZ_SWITCHBOARD
true;
//#else
false;
//#endif
public static final boolean MOZ_ANDROID_NATIVE_ACCOUNT_UI =
//#ifdef MOZ_ANDROID_NATIVE_ACCOUNT_UI
true;

Просмотреть файл

@ -140,6 +140,8 @@ import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.ViewFlipper;
import com.keepsafe.switchboard.AsyncConfigLoader;
import com.keepsafe.switchboard.SwitchBoard;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ObjectAnimator;
import org.json.JSONException;
@ -740,6 +742,21 @@ public class BrowserApp extends GeckoApp
final Context appContext = getApplicationContext();
if (AppConstants.MOZ_SWITCHBOARD) {
// Initializes the default URLs the first time.
Log.d(LOGTAG, "init Server Urls");
SwitchBoard.initDefaultServerUrls("https://mozilla-switchboard.herokuapp.com/SwitchboardURLs.php", "https://mozilla-switchboard.herokuapp.com/SwitchboardDriver.php", true);
// Looks at the server if there are changes in the server URL that should be used in the future
Log.d(LOGTAG, "update server urls from remote");
new AsyncConfigLoader(this, AsyncConfigLoader.UPDATE_SERVER).execute();
// Loads the actual config. This can be done on app start or on app onResume() depending
// how often you want to update the config.
Log.d(LOGTAG, "update app config");
new AsyncConfigLoader(this, AsyncConfigLoader.CONFIG_SERVER).execute();
}
mBrowserChrome = (ViewGroup) findViewById(R.id.browser_chrome);
mActionBarFlipper = (ViewFlipper) findViewById(R.id.browser_actionbar);
mActionBar = (ActionModeCompatView) findViewById(R.id.actionbar);
@ -3167,7 +3184,6 @@ public class BrowserApp extends GeckoApp
ClearOnShutdownPref.PREF,
new HashSet<String>()).isEmpty();
aMenu.findItem(R.id.quit).setVisible(visible);
aMenu.findItem(R.id.logins).setVisible(visible);
if (tab == null || tab.getURL() == null) {
bookmark.setEnabled(false);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше