mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 10:45:42 +00:00
Merge autoland to mozilla-central r=merge a=merge
This commit is contained in:
commit
0bc344f9d6
@ -103,6 +103,9 @@
|
||||
#ifdef MOZ_GTK3
|
||||
@BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
@BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
#ifdef MOZ_WAYLAND
|
||||
@BINPATH@/@DLL_PREFIX@mozwayland@DLL_SUFFIX@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
; We don't have a complete view of which dlls to expect when doing an artifact
|
||||
|
@ -16,7 +16,6 @@ allprojects {
|
||||
topobjdir = gradle.mozconfig.topobjdir
|
||||
|
||||
compileSdkVersion = tryInt(mozconfig.substs.ANDROID_COMPILE_SDK_VERSION)
|
||||
buildToolsVersion = tryInt(mozconfig.substs.ANDROID_BUILD_TOOLS_VERSION)
|
||||
targetSdkVersion = tryInt(mozconfig.substs.ANDROID_TARGET_SDK)
|
||||
minSdkVersion = tryInt(mozconfig.substs.MOZ_ANDROID_MIN_SDK_VERSION)
|
||||
manifestPlaceholders = [
|
||||
@ -52,7 +51,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||
// Provided in tree.
|
||||
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.7.3'
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#include "StringOperations.h"
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
@ -50,7 +51,7 @@ void ensurePath(std::string Path) {
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
AutoLockFile::AutoLockFile(const std::string &Filename) {
|
||||
std::string Hash = Hash(filename);
|
||||
std::string Hash = hash(Filename);
|
||||
std::string MutexName = std::string("Local\\searchfox-") + Hash;
|
||||
std::wstring WideMutexName;
|
||||
WideMutexName.assign(MutexName.begin(), MutexName.end());
|
||||
@ -85,7 +86,7 @@ bool AutoLockFile::truncateFile(size_t Length) {
|
||||
}
|
||||
|
||||
std::string getAbsolutePath(const std::string &Filename) {
|
||||
char full[_MAX_PATH];
|
||||
char Full[_MAX_PATH];
|
||||
if (!_fullpath(Full, Filename.c_str(), _MAX_PATH)) {
|
||||
return std::string("");
|
||||
}
|
||||
|
@ -70,28 +70,18 @@ redistributed publicly.)
|
||||
|
||||
Archiving the Gradle executable is straight-forward, but archiving a
|
||||
local Maven repository is not. Therefore a special Task Cluster
|
||||
Docker image and job exist for producing the required archives. The
|
||||
Docker image definition is rooted in
|
||||
``taskcluster/docker/android-build``. The Task Cluster job
|
||||
definition is in
|
||||
``testing/taskcluster/tasks/builds/android_api_16_gradle_dependencies.yml``.
|
||||
The job runs in a container based on the custom Docker image and
|
||||
spawns a Sonatype Nexus proxying Maven repository process in the
|
||||
background. The job builds Firefox for Android using Gradle and the
|
||||
in-tree Gradle configuration rooted at ``build.gradle``. The spawned
|
||||
proxying Maven repository downloads external dependencies and collects
|
||||
them. After the Gradle build completes, the job archives the Gradle
|
||||
version used to build, and the downloaded Maven repository, and
|
||||
exposes them as Task Cluster artifacts.
|
||||
|
||||
Here is `an example try job fetching these dependencies
|
||||
<https://treeherder.mozilla.org/#/jobs?repo=try&revision=75bc98935147&selectedJob=17793653>`_.
|
||||
The resulting task produced a `Gradle archive
|
||||
<https://queue.taskcluster.net/v1/task/CeYMgAP3Q-KF8h37nMhJjg/runs/0/artifacts/public%2Fbuild%2Fgradle.tar.xz>`_
|
||||
and a `Maven repository archive
|
||||
<https://queue.taskcluster.net/v1/task/CeYMgAP3Q-KF8h37nMhJjg/runs/0/artifacts/public%2Fbuild%2Fjcentral.tar.xz>`_.
|
||||
These archives were then uploaded (manually) to Mozilla automation
|
||||
using tooltool for consumption in Gradle builds.
|
||||
Docker image and toolchain job exist for producing the required
|
||||
archives. The Docker image definition is rooted in
|
||||
``taskcluster/docker/android-build``. The Task Cluster toolchain job
|
||||
is named `android-gradle-dependencies`. The job runs in a container
|
||||
based on the custom Docker image and spawns a Sonatype Nexus proxying
|
||||
Maven repository process in the background. The job builds Firefox
|
||||
for Android using Gradle and the in-tree Gradle configuration rooted
|
||||
at ``build.gradle``. The spawned proxying Maven repository downloads
|
||||
external dependencies and collects them. After the Gradle build
|
||||
completes, the job archives the Gradle version used to build, and the
|
||||
downloaded Maven repository, and exposes them as Task Cluster
|
||||
artifacts.
|
||||
|
||||
To update the version of Gradle in the archive produced, update
|
||||
``gradle/wrapper/gradle-wrapper.properties``. Be sure to also update
|
||||
@ -100,12 +90,18 @@ the SHA256 checksum to prevent poisoning the build machines!
|
||||
To update the versions of Gradle dependencies used, update
|
||||
``dependencies`` sections in the in-tree Gradle configuration rooted
|
||||
at ``build.gradle``. Once you are confident your changes build
|
||||
locally, push a fresh try build with an invocation like::
|
||||
locally, push a fresh build to try. The `android-gradle-dependencies`
|
||||
toolchain should run automatically, fetching your new dependencies and
|
||||
wiring them into the appropriate try build jobs.
|
||||
|
||||
$ hg push-to-try -m "try: -b o -p android-api-16-gradle-dependencies"
|
||||
To update the version of Sonatype Nexus, update `NEXUS_VERSION` in the
|
||||
`android-build` Docker image.
|
||||
|
||||
Then `upload your archives to tooltool
|
||||
<https://wiki.mozilla.org/ReleaseEngineering/Applications/Tooltool#How_To_Upload_To_Tooltool>`_,
|
||||
update the in-tree manifests in
|
||||
``mobile/android/config/tooltool-manifests``, and push a fresh try
|
||||
build.
|
||||
To modify the Sonatype Nexus configuration, typically to proxy a new
|
||||
remote Maven repository, modify
|
||||
`taskcluster/scripts/misc/android-gradle-dependencies/nexus.xml`.
|
||||
|
||||
There is also a toolchain job that fetches the Android SDK and related
|
||||
packages. To update the versions of packaged fetched, modify
|
||||
`python/mozboot/mozboot/android-packages.txt` and update the various
|
||||
in-tree versions accordingly.
|
||||
|
@ -11,6 +11,7 @@ cairo_version=1.10.2
|
||||
pango_version=1.30.1
|
||||
atk_version=2.2.0
|
||||
gtk__version=3.4.4
|
||||
pulseaudio_version=2.0
|
||||
|
||||
fontconfig_url=http://www.freedesktop.org/software/fontconfig/release/fontconfig-${fontconfig_version}.tar.gz
|
||||
libffi_url=ftp://sourceware.org/pub/libffi/libffi-${libffi_version}.tar.gz
|
||||
@ -21,12 +22,16 @@ cairo_url=http://cairographics.org/releases/cairo-${cairo_version}.tar.gz
|
||||
pango_url=http://ftp.gnome.org/pub/GNOME/sources/pango/${pango_version%.*}/pango-${pango_version}.tar.xz
|
||||
atk_url=http://ftp.gnome.org/pub/GNOME/sources/atk/${atk_version%.*}/atk-${atk_version}.tar.xz
|
||||
gtk__url=http://ftp.gnome.org/pub/gnome/sources/gtk+/${gtk__version%.*}/gtk+-${gtk__version}.tar.xz
|
||||
pulseaudio_url=https://freedesktop.org/software/pulseaudio/releases/pulseaudio-${pulseaudio_version}.tar.xz
|
||||
|
||||
root_dir=$(mktemp -d)
|
||||
cd $root_dir
|
||||
|
||||
make_flags=-j$(nproc)
|
||||
|
||||
# Install a few packages for pulseaudio.
|
||||
yum install -y libtool-ltdl-devel libtool-ltdl-devel.i686 json-c-devel json-c-devel.i686 libsndfile-devel libsndfile-devel.i686
|
||||
|
||||
build() {
|
||||
name=$1
|
||||
shift
|
||||
@ -72,6 +77,7 @@ build pango
|
||||
build atk
|
||||
make_flags="$make_flags GLIB_COMPILE_SCHEMAS=glib-compile-schemas"
|
||||
build gtk+
|
||||
build pulseaudio --disable-nls
|
||||
|
||||
done
|
||||
|
||||
|
@ -278,6 +278,12 @@
|
||||
margin-inline-end: 15px;
|
||||
}
|
||||
|
||||
/* For non expandable root nodes, we don't have .tree-indent elements, so we declare
|
||||
the margin on the start of the node */
|
||||
.tree-node[data-expandable="false"][aria-level="0"] {
|
||||
padding-inline-start: 15px
|
||||
}
|
||||
|
||||
.tree .tree-node[data-expandable="true"] {
|
||||
cursor: default;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -280,11 +280,7 @@ skip-if = true # Bug 1404382
|
||||
[browser_webconsole_highlighter_console_helper.js]
|
||||
[browser_webconsole_history_arrow_keys.js]
|
||||
[browser_webconsole_hpkp_invalid-headers.js]
|
||||
skip-if = true # Bug 1405340
|
||||
# old console skip-if = (os == 'win' && bits == 64) # Bug 1390001
|
||||
[browser_webconsole_hsts_invalid-headers.js]
|
||||
skip-if = true # Bug 1405341
|
||||
# old console skip-if = e10s # Bug 1042253 - webconsole e10s tests
|
||||
[browser_webconsole_iframe_wrong_hud.js]
|
||||
skip-if = true # Bug 1404378
|
||||
[browser_webconsole_ineffective_iframe_sandbox_warning.js]
|
||||
|
@ -1,74 +1,68 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that errors about invalid HPKP security headers are logged to the web
|
||||
// console.
|
||||
// Tests that errors about invalid HPKP security headers are logged to the web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console HPKP invalid " +
|
||||
"header test";
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console HPKP invalid header test";
|
||||
const SJS_URL = "https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test_hpkp-invalid-headers.sjs";
|
||||
const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Web/HTTP/" +
|
||||
"Public_Key_Pinning" + DOCS_GA_PARAMS;
|
||||
const NON_BUILTIN_ROOT_PREF = "security.cert_pinning.process_headers_from_" +
|
||||
"non_builtin_roots";
|
||||
"new-console-output/test/mochitest/test_hpkp-invalid-headers.sjs";
|
||||
const LEARN_MORE_URI =
|
||||
"https://developer.mozilla.org/docs/Web/HTTP/Public_Key_Pinning" + DOCS_GA_PARAMS;
|
||||
const NON_BUILTIN_ROOT_PREF =
|
||||
"security.cert_pinning.process_headers_from_non_builtin_roots";
|
||||
|
||||
add_task(function* () {
|
||||
add_task(async function () {
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(NON_BUILTIN_ROOT_PREF);
|
||||
});
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?badSyntax",
|
||||
name: "Could not parse header error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that could not be " +
|
||||
"parsed successfully."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?noMaxAge",
|
||||
name: "No max-age error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that did not include " +
|
||||
"a \u2018max-age\u2019 directive."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?invalidIncludeSubDomains",
|
||||
name: "Invalid includeSubDomains error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that included an " +
|
||||
"invalid \u2018includeSubDomains\u2019 directive."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?invalidMaxAge",
|
||||
name: "Invalid max-age error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that included an " +
|
||||
"invalid \u2018max-age\u2019 directive."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?multipleIncludeSubDomains",
|
||||
name: "Multiple includeSubDomains error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that included " +
|
||||
"multiple \u2018includeSubDomains\u2019 directives."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?multipleMaxAge",
|
||||
name: "Multiple max-age error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that included " +
|
||||
"multiple \u2018max-age\u2019 directives."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?multipleReportURIs",
|
||||
name: "Multiple report-uri error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that included " +
|
||||
@ -79,7 +73,7 @@ add_task(function* () {
|
||||
// true to have the PKP implementation return more specific errors.
|
||||
Services.prefs.setBoolPref(NON_BUILTIN_ROOT_PREF, true);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?pinsetDoesNotMatch",
|
||||
name: "Non-matching pinset error displayed successfully",
|
||||
text: "Public-Key-Pins: The site specified a header that did not include " +
|
||||
@ -88,7 +82,7 @@ add_task(function* () {
|
||||
|
||||
Services.prefs.setBoolPref(NON_BUILTIN_ROOT_PREF, false);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckForWarningMessage({
|
||||
url: SJS_URL + "?pinsetDoesNotMatch",
|
||||
name: "Non-built-in root error displayed successfully",
|
||||
text: "Public-Key-Pins: The certificate used by the site was not issued " +
|
||||
@ -97,30 +91,17 @@ add_task(function* () {
|
||||
}, hud);
|
||||
});
|
||||
|
||||
function* checkForMessage(curTest, hud) {
|
||||
hud.jsterm.clearOutput();
|
||||
async function navigateAndCheckForWarningMessage({name, text, url}, hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, curTest.url);
|
||||
const onMessage = waitForMessage(hud, text, ".message.warning");
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
|
||||
const {node} = await onMessage;
|
||||
ok(node, name);
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: curTest.name,
|
||||
text: curTest.text,
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING,
|
||||
objects: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
yield testClickOpenNewTab(hud, results);
|
||||
}
|
||||
|
||||
function testClickOpenNewTab(hud, results) {
|
||||
let warningNode = results[0].clickableElements[0];
|
||||
ok(warningNode, "link element");
|
||||
ok(warningNode.classList.contains("learn-more-link"), "link class name");
|
||||
return simulateMessageLinkClick(warningNode, LEARN_MORE_URI);
|
||||
let learnMoreNode = node.querySelector(".learn-more-link");
|
||||
ok(learnMoreNode, `There is a "Learn more" link`);
|
||||
const navigatedLink = await simulateLinkClick(learnMoreNode);
|
||||
is(navigatedLink, LEARN_MORE_URI,
|
||||
"Click on the learn more link navigates the user to the expected url");
|
||||
}
|
||||
|
@ -1,61 +1,55 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that errors about invalid HSTS security headers are logged
|
||||
// to the web console.
|
||||
// Tests that errors about invalid HSTS security headers are logged to the web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console HSTS invalid " +
|
||||
"header test";
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console HSTS invalid header test";
|
||||
const SJS_URL = "https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test_hsts-invalid-headers.sjs";
|
||||
"/new-console-output/test/mochitest/test_hsts-invalid-headers.sjs";
|
||||
const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Web/HTTP/Headers/" +
|
||||
"Strict-Transport-Security" + DOCS_GA_PARAMS;
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
add_task(async function () {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckWarningMessage({
|
||||
url: SJS_URL + "?badSyntax",
|
||||
name: "Could not parse header error displayed successfully",
|
||||
text: "Strict-Transport-Security: The site specified a header that could " +
|
||||
"not be parsed successfully."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckWarningMessage({
|
||||
url: SJS_URL + "?noMaxAge",
|
||||
name: "No max-age error displayed successfully",
|
||||
text: "Strict-Transport-Security: The site specified a header that did " +
|
||||
"not include a \u2018max-age\u2019 directive."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckWarningMessage({
|
||||
url: SJS_URL + "?invalidIncludeSubDomains",
|
||||
name: "Invalid includeSubDomains error displayed successfully",
|
||||
text: "Strict-Transport-Security: The site specified a header that " +
|
||||
"included an invalid \u2018includeSubDomains\u2019 directive."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckWarningMessage({
|
||||
url: SJS_URL + "?invalidMaxAge",
|
||||
name: "Invalid max-age error displayed successfully",
|
||||
text: "Strict-Transport-Security: The site specified a header that " +
|
||||
"included an invalid \u2018max-age\u2019 directive."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckWarningMessage({
|
||||
url: SJS_URL + "?multipleIncludeSubDomains",
|
||||
name: "Multiple includeSubDomains error displayed successfully",
|
||||
text: "Strict-Transport-Security: The site specified a header that " +
|
||||
"included multiple \u2018includeSubDomains\u2019 directives."
|
||||
}, hud);
|
||||
|
||||
yield* checkForMessage({
|
||||
await navigateAndCheckWarningMessage({
|
||||
url: SJS_URL + "?multipleMaxAge",
|
||||
name: "Multiple max-age error displayed successfully",
|
||||
text: "Strict-Transport-Security: The site specified a header that " +
|
||||
@ -63,30 +57,17 @@ add_task(function* () {
|
||||
}, hud);
|
||||
});
|
||||
|
||||
function* checkForMessage(curTest, hud) {
|
||||
hud.jsterm.clearOutput();
|
||||
async function navigateAndCheckWarningMessage({url, name, text}, hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, curTest.url);
|
||||
const onMessage = waitForMessage(hud, text, ".message.warning");
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
|
||||
const {node} = await onMessage;
|
||||
ok(node, name);
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: curTest.name,
|
||||
text: curTest.text,
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING,
|
||||
objects: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
yield testClickOpenNewTab(hud, results);
|
||||
}
|
||||
|
||||
function testClickOpenNewTab(hud, results) {
|
||||
let warningNode = results[0].clickableElements[0];
|
||||
ok(warningNode, "link element");
|
||||
ok(warningNode.classList.contains("learn-more-link"), "link class name");
|
||||
return simulateMessageLinkClick(warningNode, LEARN_MORE_URI);
|
||||
let learnMoreNode = node.querySelector(".learn-more-link");
|
||||
ok(learnMoreNode, `There is a "Learn more" link`);
|
||||
const navigatedLink = await simulateLinkClick(learnMoreNode);
|
||||
is(navigatedLink, LEARN_MORE_URI,
|
||||
"Click on the learn more link navigates the user to the expected url");
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
org.gradle.parallel=true
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xmx2560M
|
||||
android.enableAapt2=false
|
||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -3,5 +3,5 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip
|
||||
distributionSha256Sum=ed7e9c8bb41bd10d4c9339c95b2f8b122f5bf13188bd90504a26e0f00b123b0d
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
||||
distributionSha256Sum=5c07b3bac2209fbc98fb1fdf6fd831f72429cdf8c503807404eae03d8c8099e5
|
||||
|
@ -5,13 +5,14 @@ apply plugin: 'checkstyle'
|
||||
apply plugin: 'com.getkeepsafe.dexcount'
|
||||
apply plugin: 'findbugs'
|
||||
|
||||
apply from: "${topsrcdir}/mobile/android/gradle/product_flavors.gradle"
|
||||
|
||||
dexcount {
|
||||
format = "tree"
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.compileSdkVersion
|
||||
buildToolsVersion project.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
targetSdkVersion project.ext.targetSdkVersion
|
||||
@ -84,35 +85,13 @@ android {
|
||||
// want to develop significant new user interface pieces in-tree that don't ship (even in the
|
||||
// Nightly channel) while under development. A new "skin" flavour allows us to develop such
|
||||
// pieces in Gradle without changing the mainline configuration.
|
||||
flavorDimensions "audience", "skin"
|
||||
|
||||
project.configureProductFlavors.delegate = it
|
||||
project.configureProductFlavors()
|
||||
|
||||
flavorDimensions "audience", "geckoBinaries", "minApi", "skin"
|
||||
|
||||
productFlavors {
|
||||
// For API 21+ - with pre-dexing, this will be faster for local development.
|
||||
local {
|
||||
dimension "audience"
|
||||
|
||||
// For pre-dexing, setting `minSdkVersion 21` allows the Android gradle plugin to
|
||||
// pre-DEX each module and produce an APK that can be tested on
|
||||
// Android Lollipop without time consuming DEX merging processes.
|
||||
minSdkVersion 21
|
||||
dexOptions {
|
||||
preDexLibraries true
|
||||
}
|
||||
}
|
||||
// For API < 21 - does not support pre-dexing because local development
|
||||
// is slow in that case.
|
||||
localOld {
|
||||
dimension "audience"
|
||||
}
|
||||
|
||||
// Automation builds. We use "official" rather than "automation" to drive these builds down
|
||||
// the list of configurations that Android Studio offers, thereby making it _not_ the
|
||||
// default. This avoids a common issue with "omni.ja" not being packed into the default APK
|
||||
// built and deployed by Android Studio.
|
||||
official {
|
||||
dimension "audience"
|
||||
}
|
||||
|
||||
// Since Firefox 57, the mobile user interface has followed the Photon design.
|
||||
// Before Firefox 57, the user interface followed the Australis design.
|
||||
photon {
|
||||
@ -162,13 +141,10 @@ android {
|
||||
exclude 'org/mozilla/gecko/gcm/**/*.java'
|
||||
exclude 'org/mozilla/gecko/push/**/*.java'
|
||||
}
|
||||
|
||||
srcDir "${project.buildDir}/generated/source/preprocessed_code" // See syncPreprocessedCode.
|
||||
}
|
||||
|
||||
res {
|
||||
srcDir "${topsrcdir}/${mozconfig.substs.MOZ_BRANDING_DIRECTORY}/res"
|
||||
srcDir "${project.buildDir}/generated/source/preprocessed_resources" // See syncPreprocessedResources.
|
||||
srcDir "${topsrcdir}/mobile/android/services/src/main/res"
|
||||
if (mozconfig.substs.MOZ_CRASHREPORTER) {
|
||||
srcDir "${topsrcdir}/mobile/android/base/crashreporter/res"
|
||||
@ -182,18 +158,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
// Every configuration needs the stub manifest at
|
||||
// src/main/AndroidManifest.xml and the generated manifest. We can't
|
||||
// use the main sourceSet without losing the stub, so we cover all the
|
||||
// configurations by enumerating the buildTypes here.
|
||||
debug {
|
||||
manifest.srcFile "${project.buildDir}/generated/source/preprocessed_manifest/AndroidManifest.xml"
|
||||
}
|
||||
|
||||
release {
|
||||
manifest.srcFile "${project.buildDir}/generated/source/preprocessed_manifest/AndroidManifest.xml"
|
||||
}
|
||||
|
||||
test {
|
||||
java {
|
||||
// Bug 1229149 tracks pushing this into a :services Gradle project.
|
||||
@ -227,6 +191,9 @@ android {
|
||||
}
|
||||
|
||||
testOptions {
|
||||
// For Robolectric: see https://github.com/robolectric/robolectric/issues/3333#issuecomment-324300418.
|
||||
unitTests.includeAndroidResources true
|
||||
|
||||
unitTests.all {
|
||||
// We'd like to use (Runtime.runtime.availableProcessors()/2), but
|
||||
// we have tests that start test servers and the bound ports
|
||||
@ -237,72 +204,50 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:appcompat-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:cardview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:recyclerview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:design:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:customtabs:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:appcompat-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:cardview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:recyclerview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:design:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:customtabs:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:palette-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
|
||||
if (mozconfig.substs.MOZ_NATIVE_DEVICES) {
|
||||
compile "com.android.support:mediarouter-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-base:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-cast:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.android.support:mediarouter-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-base:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-cast:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
}
|
||||
|
||||
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
|
||||
compile "com.google.android.gms:play-services-analytics:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-analytics:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
}
|
||||
|
||||
if (mozconfig.substs.MOZ_ANDROID_GCM) {
|
||||
compile "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-base:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-gcm:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-measurement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-base:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-gcm:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-measurement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
}
|
||||
|
||||
// Include LeakCanary in most gradle based builds. LeakCanary adds about 5k methods, so we disable
|
||||
// it for the (non-proguarded, non-predex) localOld builds to allow space for other libraries.
|
||||
// Gradle based tests include the no-op version. Mach based builds only include the no-op version
|
||||
// of this library.
|
||||
// It doesn't seem like there is a non-trivial way to be conditional on 'localOld', so instead we explicitly
|
||||
// define a version of leakcanary for every flavor:
|
||||
localCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
|
||||
localOldCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
officialCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
officialCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
// Include LeakCanary in most gradle based builds. Gradle based tests
|
||||
// include the no-op version. Mach based builds only include the no-op
|
||||
// version of this library.
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
|
||||
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
|
||||
// With a simple "compile", Gradle will always build these libraries in their default configuration
|
||||
// (i.e. release), so we need to explicitly forward our own build configuration here (bug 1385695).
|
||||
//
|
||||
// Official builds compile a hacked up app:Official..Debug, but need the
|
||||
// release versions of the dependencies, in order to not have debugging
|
||||
// information. It's not yet possible to specify just officialDebug, so we
|
||||
// hack around it here.
|
||||
if (mozconfig.substs.MOZILLA_OFFICIAL) {
|
||||
debugCompile project(path: ':geckoview', configuration: "release")
|
||||
} else {
|
||||
debugCompile project(path: ':geckoview', configuration: "debug")
|
||||
}
|
||||
releaseCompile project(path: ':geckoview', configuration: "release")
|
||||
implementation project(path: ':geckoview')
|
||||
implementation project(path: ':thirdparty')
|
||||
|
||||
if (mozconfig.substs.MOZILLA_OFFICIAL) {
|
||||
debugCompile project(path: ':thirdparty', configuration: "release")
|
||||
} else {
|
||||
debugCompile project(path: ':thirdparty', configuration: "debug")
|
||||
}
|
||||
releaseCompile project(path: ':thirdparty', configuration: "release")
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.robolectric:robolectric:3.1.2'
|
||||
testCompile 'org.simpleframework:simple-http:6.0.1'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.robolectric:robolectric:3.5.1'
|
||||
testImplementation 'org.simpleframework:simple-http:6.0.1'
|
||||
testImplementation 'org.mockito:mockito-core:1.10.19'
|
||||
|
||||
// Including the Robotium JAR directly can cause issues with dexing.
|
||||
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4'
|
||||
androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.5.4'
|
||||
}
|
||||
|
||||
// TODO: (bug 1261486): This impl is not robust -
|
||||
@ -317,11 +262,6 @@ task checkstyle(type: Checkstyle) {
|
||||
classpath = files()
|
||||
}
|
||||
|
||||
task syncPreprocessedCode(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
|
||||
into("${project.buildDir}/generated/source/preprocessed_code")
|
||||
from("${topobjdir}/mobile/android/base/generated/preprocessed")
|
||||
}
|
||||
|
||||
// The localization system uses the moz.build preprocessor to interpolate a .dtd
|
||||
// file of XML entity definitions into an XML file of elements referencing those
|
||||
// entities. (Each locale produces its own .dtd file, backstopped by the en-US
|
||||
@ -337,49 +277,80 @@ class ExpandXMLEntitiesFilter extends FilterReader {
|
||||
}
|
||||
}
|
||||
|
||||
task syncPreprocessedResources(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
|
||||
into("${project.buildDir}/generated/source/preprocessed_resources")
|
||||
from("${topobjdir}/mobile/android/base/res")
|
||||
filesMatching('**/strings.xml') {
|
||||
filter(ExpandXMLEntitiesFilter)
|
||||
}
|
||||
}
|
||||
|
||||
// It's not easy -- see the backout in Bug 1242213 -- to change the <manifest>
|
||||
// package for Fennec. Gradle has grown a mechanism to achieve what we want for
|
||||
// Fennec, however, with applicationId. To use the same manifest as moz.build,
|
||||
// we replace the package with org.mozilla.gecko (the eventual package) here.
|
||||
task rewriteManifestPackage(type: Copy, dependsOn: rootProject.generateCodeAndResources) {
|
||||
into("${project.buildDir}/generated/source/preprocessed_manifest")
|
||||
from("${topobjdir}/mobile/android/base/AndroidManifest.xml")
|
||||
filter { it.replaceFirst(/package=".*?"/, 'package="org.mozilla.gecko"') }
|
||||
}
|
||||
|
||||
apply from: "${topsrcdir}/mobile/android/gradle/with_gecko_binaries.gradle"
|
||||
|
||||
android.applicationVariants.all { variant ->
|
||||
def syncPreprocessedJava = task("syncPreprocessedJavaFor${variant.name.capitalize()}", type: Sync) {
|
||||
into("${project.buildDir}/moz.build/src/${variant.name}/java")
|
||||
from("${topobjdir}/mobile/android/base/generated/preprocessed")
|
||||
exclude('**/*.mkdir.done')
|
||||
}
|
||||
// This is an Android-Gradle plugin 3+-ism. Culted from reading the source,
|
||||
// searching for "registerJavaGeneratingTask", and finding
|
||||
// https://github.com/GoogleCloudPlatform/endpoints-framework-gradle-plugin/commit/2f2b91476fb1c6647791e2c6fe531a47615a1e85.
|
||||
// The added directory doesn't appear in the paths listed by the
|
||||
// `sourceSets` task, for reasons unknown.
|
||||
variant.registerJavaGeneratingTask(syncPreprocessedJava, syncPreprocessedJava.destinationDir)
|
||||
|
||||
def syncPreprocessedRes = task("syncPreprocessedResFor${variant.name.capitalize()}", type: Sync) {
|
||||
into("${project.buildDir}/moz.build/src/${variant.name}/res")
|
||||
from("${topobjdir}/mobile/android/base/res")
|
||||
filesMatching('**/strings.xml') {
|
||||
filter(ExpandXMLEntitiesFilter)
|
||||
}
|
||||
exclude('**/*.mkdir.done')
|
||||
}
|
||||
// This is an Android-Gradle plugin 3+-ism. Determined by reading the
|
||||
// source. The added directory doesn't appear in the paths listed by the
|
||||
// `sourceSets` task, for reasons unknown.
|
||||
variant.registerGeneratedResFolders(project.files(syncPreprocessedRes.destinationDir).builtBy(syncPreprocessedRes))
|
||||
|
||||
// It's not easy -- see the backout in Bug 1242213 -- to change the
|
||||
// <manifest> package for Fennec. Gradle has grown a mechanism to achieve
|
||||
// what we want for Fennec, however, with applicationId. To use the same
|
||||
// manifest as moz.build, we replace the package with org.mozilla.gecko (the
|
||||
// eventual package) here.
|
||||
def rewriteManifestPackage = task("rewriteManifestPackageFor${variant.name.capitalize()}", type: Copy, dependsOn: rootProject.generateCodeAndResources) {
|
||||
into("${project.buildDir}/moz.build/src/${variant.name}")
|
||||
from("${topobjdir}/mobile/android/base/AndroidManifest.xml")
|
||||
filter { it.replaceFirst(/package=".*?"/, 'package="org.mozilla.gecko"') }
|
||||
exclude('**/*.mkdir.done')
|
||||
}
|
||||
|
||||
// Every configuration needs the stub manifest at
|
||||
// src/main/AndroidManifest.xml and the generated manifest. We can't use
|
||||
// the main sourceSet without losing the stub, so we cover all the
|
||||
// configurations here.
|
||||
android.sourceSets."${variant.name}".manifest.srcFile "${rewriteManifestPackage.destinationDir}/AndroidManifest.xml"
|
||||
variant.preBuild.dependsOn rewriteManifestPackage
|
||||
variant.preBuild.dependsOn syncPreprocessedCode
|
||||
variant.preBuild.dependsOn syncPreprocessedResources
|
||||
|
||||
// Official automation builds don't include Gecko binaries, since those binaries are not
|
||||
// produced until after build time (at package time). official Therefore, automation builds
|
||||
// include the Gecko binaries into the APK at package time. The "withGeckoBinaries" variant of
|
||||
// the :geckoview project also does this. (It does what it says on the tin!) For notes on this
|
||||
// approach, see mobile/android/gradle/with_gecko_binaries.gradle.
|
||||
|
||||
// Like 'local' or 'localOld'.
|
||||
def audienceDimension = variant.productFlavors[0].name
|
||||
// Local (read, not 'official') builds want to reflect developer changes to
|
||||
// AndroidManifest.xml.in, strings.xml, and preprocessed Java code. To do
|
||||
// this, the Gradle build calls out to the moz.build system, which can be
|
||||
// re-entrant. Official builds are driven by the moz.build system and
|
||||
// should never be re-entrant in this way.
|
||||
if (!((variant.productFlavors*.name).contains('official'))) {
|
||||
syncPreprocessedJava.dependsOn rootProject.generateCodeAndResources
|
||||
syncPreprocessedRes.dependsOn rootProject.generateCodeAndResources
|
||||
rewriteManifestPackage.dependsOn rootProject.generateCodeAndResources
|
||||
}
|
||||
|
||||
// :app uses :geckoview:release and handles it's own Gecko binary inclusion,
|
||||
// even though this would be most naturally done in the :geckoview project.
|
||||
if (!audienceDimension.equals('official')) {
|
||||
// When driven from moz.build via |mach build|, Gradle does not require or
|
||||
// use Gecko binaries. It's only |mach package| that packs the Gecko
|
||||
// binaries into the resulting APK. The "withoutGeckoBinaries" variants
|
||||
// handle this. When driven from Android Studio or Gradle, the
|
||||
// "withGeckoBinaries" variants handle packing the Gecko binaries into the
|
||||
// resulting APK (for on-device deployment). They also update the Omnijars
|
||||
// as necessary, smoothing out the edit-compile-test development cycle.
|
||||
// They do what they say on the tin!
|
||||
if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
|
||||
configureVariantWithGeckoBinaries(variant)
|
||||
}
|
||||
}
|
||||
|
||||
android.applicationVariants.all { variant ->
|
||||
configureVariantWithJNIWrappers(variant, "Fennec")
|
||||
configureApplicationVariantWithJNIWrappers(variant, "Fennec")
|
||||
}
|
||||
|
||||
if (gradle.startParameter.taskNames.any { it.endsWith('UnitTest') }) {
|
||||
@ -416,7 +387,7 @@ android.applicationVariants.all { variant ->
|
||||
|
||||
reports {
|
||||
html.enabled = true // HTML reports for humans.
|
||||
html.destination = "$project.buildDir/reports/findbugs/findbugs-${variant.name}-output.html"
|
||||
html.destination = file("$project.buildDir/reports/findbugs/findbugs-${variant.name}-output.html")
|
||||
xml.enabled = false
|
||||
}
|
||||
}
|
||||
@ -440,7 +411,7 @@ android.applicationVariants.all { variant ->
|
||||
|
||||
reports {
|
||||
xml.enabled = true // XML reports for machines.
|
||||
xml.destination = "$project.buildDir/reports/findbugs/findbugs-${variant.name}-output.xml"
|
||||
xml.destination = file("$project.buildDir/reports/findbugs/findbugs-${variant.name}-output.xml")
|
||||
html.enabled = false
|
||||
}
|
||||
}
|
||||
@ -466,8 +437,7 @@ android.applicationVariants.all { variant ->
|
||||
|
||||
variant.outputs.each { output ->
|
||||
output.processManifest.doLast {
|
||||
[output.processManifest.manifestOutputFile,
|
||||
output.processManifest.instantRunManifestOutputFile,
|
||||
[file("${manifestOutputDirectory}/AndroidManifest.xml"),
|
||||
].each({ File manifestOutFile ->
|
||||
if (manifestOutFile.exists()) {
|
||||
def contents = manifestOutFile.getText('UTF-8')
|
||||
|
@ -38,7 +38,6 @@
|
||||
<issue id="ResourceAsColor" severity="warning" />
|
||||
<issue id="ResourceType" severity="warning" />
|
||||
<issue id="ValidFragment" severity="warning" />
|
||||
<issue id="WrongConstant" severity="warning" />
|
||||
|
||||
<!-- New Android-Gradle lint integration regressed this check. -->
|
||||
<issue id="MissingRegistered" severity="warning" />
|
||||
@ -51,7 +50,6 @@
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/dlc/DownloadContentTelemetry.java"/>
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/preferences/LocaleListPreference.java"/>
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java"/>
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/db/PerProfileDatabaseProvider.java"/>
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/PrintHelper.java"/>
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/animation/PropertyAnimator.java"/>
|
||||
<ignore path="**/mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java"/>
|
||||
|
@ -5,5 +5,5 @@
|
||||
android:viewportHeight="12.0">
|
||||
<path
|
||||
android:fillColor="@color/activity_stream_icon"
|
||||
android:pathData="M4.97.151l-2.819,6.5A.25.25,0,0,0,2.381,7H4.029a.25.25,0,0,1,.225.359L2,12,9.4,5.437A.25.25,0,0,0,9.234,5H6.791a.25.25,0,0,1-.19-.412L10.15.412A.25.25,0,0,0,9.959,0H5.2A.25.25,0,0,0,4.97.151Z"/>
|
||||
android:pathData="M4.97,0.151l-2.819,6.5A0.25,0.25,0,0,0,2.381,7H4.029a0.25,0.25,0,0,1,0.225,0.359L2,12,9.4,5.437A0.25,0.25,0,0,0,9.234,5H6.791a0.25,0.25,0,0,1,-0.19,-0.412L10.15,0.412A0.25,0.25,0,0,0,9.959,0H5.2A0.25,0.25,0,0,0,4.97,0.151Z"/>
|
||||
</vector>
|
||||
|
@ -40,7 +40,7 @@
|
||||
android:id="@+id/custom_tabs_action_bar_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
tools:text="Mozilla.org"/>
|
||||
@ -49,7 +49,6 @@
|
||||
android:id="@+id/custom_tabs_action_bar_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="10sp"
|
||||
|
@ -15,15 +15,6 @@
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="GeckoDialogBase" parent="@android:style/Theme.Holo.Light.Dialog">
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<style name="GeckoTitleDialogBase" parent="@android:style/Theme.Holo.Light.Dialog" />
|
||||
|
||||
<!--
|
||||
Activity based themes for API 11+. This theme completely replaces
|
||||
GeckoAppBase from res/values/themes.xml on API 11+ devices.
|
||||
|
@ -1,15 +0,0 @@
|
||||
<!-- 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/. -->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
|
||||
<item name="android:windowBackground">@color/toolbar_grey</item>
|
||||
<item name="android:colorBackground">@color/toolbar_grey</item>
|
||||
</style>
|
||||
|
||||
<style name="SettingsTheme" parent="@android:style/Theme.Holo.Light"/>
|
||||
|
||||
</resources>
|
@ -1,19 +0,0 @@
|
||||
<!-- 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/. -->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="TextAppearance.EmptyView.Title" parent="@android:style/TextAppearance.Small">
|
||||
<item name="android:textColor">@color/text_and_tabs_tray_grey</item>
|
||||
<item name="android:textSize">20sp</item>
|
||||
<item name="android:fontFamily">sans-serif-light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.EmptyView.Message" parent="@android:style/TextAppearance.Small">
|
||||
<item name="android:textColor">@color/placeholder_grey</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:lineSpacingExtra">4sp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -3,7 +3,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/. -->
|
||||
|
||||
<resources>
|
||||
<resources
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!--
|
||||
Base application theme. This could be overridden by GeckoBaseTheme
|
||||
@ -15,13 +16,6 @@
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="GeckoDialogBase" parent="@android:style/Theme.Dialog">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
</style>
|
||||
|
||||
<style name="GeckoTitleDialogBase" parent="@android:style/Theme.Dialog" />
|
||||
|
||||
<style name="Gecko.Preferences">
|
||||
<item name="windowActionBar">true</item>
|
||||
<item name="windowNoTitle">false</item>
|
||||
@ -73,10 +67,6 @@
|
||||
<item name="actionBarTheme">@style/GeckoActionBar</item>
|
||||
</style>
|
||||
|
||||
<style name="Gecko.Dialog" parent="GeckoDialogBase"/>
|
||||
|
||||
<style name="Gecko.TitleDialog" parent="GeckoTitleDialogBase"/>
|
||||
|
||||
<!--
|
||||
Activity based themes, dependent on API level. This theme is replaced
|
||||
by GeckoAppBase from res/values-vXX/themes.xml on newer devices.
|
||||
@ -126,7 +116,8 @@
|
||||
</style>
|
||||
|
||||
<!-- Bookmark full-page dialog theme -->
|
||||
<style name="Bookmark" parent="Theme.AppCompat.Light.DialogWhenLarge"/>
|
||||
<style name="Bookmark" parent="Theme.AppCompat.Light.DialogWhenLarge"
|
||||
tools:ignore="UnusedResources" />
|
||||
<style name="Bookmark.Gecko" parent="Gecko">
|
||||
<item name="toolbarStyle">@style/BookmarkToolbarStyle</item>
|
||||
<item name="colorAccent">@color/fennec_ui_accent</item>
|
||||
|
@ -4,7 +4,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/. -->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!--
|
||||
Only overriden styles for Honeycomb/Ice cream sandwich are specified here.
|
||||
@ -26,9 +27,6 @@
|
||||
|
||||
<style name="Widget.BaseTextView" parent="android:style/Widget.Holo.Light.TextView" />
|
||||
|
||||
<style name="Widget.ProgressBar.Horizontal" parent="android:style/Widget.Holo.ProgressBar.Horizontal" />
|
||||
|
||||
|
||||
<!--
|
||||
Application styles. All customizations that are not specific
|
||||
to a particular API level can go here.
|
||||
@ -47,18 +45,6 @@
|
||||
<!-- ActionBar -->
|
||||
<style name="ActionBar" parent="android:style/Widget.Holo.ActionBar" />
|
||||
|
||||
<!-- TabsLayout ActionBar -->
|
||||
<style name="ActionBar.TabsLayout">
|
||||
<item name="android:visibility">gone</item>
|
||||
</style>
|
||||
|
||||
<!-- DropDown List View -->
|
||||
<style name="DropDownListView" parent="@android:style/Widget.Holo.ListView.DropDown">
|
||||
<item name="android:listSelector">@drawable/action_bar_button</item>
|
||||
<item name="android:divider">@color/toolbar_divider_grey</item>
|
||||
<item name="android:dividerHeight">@dimen/page_row_divider_height</item>
|
||||
</style>
|
||||
|
||||
<!-- Spinner DropDown Item -->
|
||||
<style name="Widget.DropDownItem.Spinner" parent="@android:style/Widget.Holo.Light.DropDownItem.Spinner">
|
||||
<item name="android:textColor">#FF000000</item>
|
||||
@ -108,7 +94,8 @@
|
||||
|
||||
<style name="TabInput.TabWidget" parent="android:style/Widget.Holo.Light.TabWidget" />
|
||||
|
||||
<style name="TabInput.Tab" parent="android:style/Widget.Holo.Light.Tab">
|
||||
<style name="TabInput.Tab" parent="android:style/Widget.Holo.Light.Tab"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:minHeight">@dimen/menu_item_row_height</item>
|
||||
<item name="android:textAllCaps">true</item>
|
||||
</style>
|
||||
|
@ -14,14 +14,6 @@
|
||||
<item name="android:fontFamily">sans-serif-light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.FirstrunTextLight">
|
||||
<item name="android:fontFamily">sans-serif-light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.FirstrunTextRegular">
|
||||
<item name="android:fontFamily">sans-serif</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.UrlBar.Title" parent="TextAppearance.Small">
|
||||
<item name="android:textSize">16sp</item>
|
||||
</style>
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
<style name="Widget.BaseTextView" parent="android:style/Widget.TextView"/>
|
||||
|
||||
<style name="Widget.ProgressBar.Horizontal" parent="android:style/Widget.ProgressBar.Horizontal"/>
|
||||
|
||||
<!--
|
||||
Application styles. All customizations that are not specific
|
||||
to a particular API level can go here.
|
||||
@ -65,10 +63,6 @@
|
||||
<item name="android:listSelector">@drawable/action_bar_button</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Home.HomeList">
|
||||
<item name="android:scrollbarStyle">outsideOverlay</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.ListItem">
|
||||
<item name="android:minHeight">?android:attr/listPreferredItemHeight</item>
|
||||
<item name="android:textAppearance">?android:attr/textAppearanceLargeInverse</item>
|
||||
@ -216,12 +210,6 @@
|
||||
<item name="android:scaleType">centerCrop</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.TopSitesGridItemPin">
|
||||
<item name="android:minWidth">30dip</item>
|
||||
<item name="android:minHeight">30dip</item>
|
||||
<item name="android:padding">0dip</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.TopSitesGridItemTitle">
|
||||
<item name="android:textColor">@color/top_sites_grid_item_title</item>
|
||||
<item name="android:textSize">12sp</item>
|
||||
@ -295,7 +283,8 @@
|
||||
<!--
|
||||
We are overriding the snackbar message style to guarantee a consistent style across Android versions (bug 1217416).
|
||||
-->
|
||||
<style name="TextAppearance.Design.Snackbar.Message" parent="android:TextAppearance" tools:override="true">
|
||||
<style name="TextAppearance.Design.Snackbar.Message" parent="android:TextAppearance" tools:override="true"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:textSize">@dimen/design_snackbar_text_size</item>
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
</style>
|
||||
@ -370,7 +359,8 @@
|
||||
<item name="android:textColor">?android:attr/textColorTertiary</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Micro.Inverse">
|
||||
<style name="TextAppearance.Micro.Inverse"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:textColor">?android:attr/textColorTertiaryInverse</item>
|
||||
<item name="android:textColorHint">?android:attr/textColorHintInverse</item>
|
||||
<item name="android:textColorHighlight">@color/text_color_highlight_inverse</item>
|
||||
@ -400,7 +390,8 @@
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.Widget.Home" />
|
||||
<style name="TextAppearance.Widget.Home"
|
||||
tools:ignore="UnusedResources" />
|
||||
|
||||
<style name="TextAppearance.Widget.Home.Header" parent="TextAppearance.Small">
|
||||
<item name="android:textColor">@color/disabled_grey</item>
|
||||
@ -436,7 +427,8 @@
|
||||
<item name="android:fontFamily">sans-serif-light</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.DoorHanger.Small">
|
||||
<style name="TextAppearance.DoorHanger.Small"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
@ -527,30 +519,21 @@
|
||||
<item name="android:layout_marginRight">6dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.RemoteTabsItemView" parent="Widget.TwoLinePageRow"/>
|
||||
|
||||
<style name="Widget.RemoteTabsClientView" parent="Widget.TwoLinePageRow">
|
||||
<item name="android:background">@color/about_page_header_grey</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.RemoteTabsListView" parent="Widget.HomeListView">
|
||||
<item name="android:childDivider">@color/toolbar_divider_grey</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.HistoryListView" parent="Widget.HomeListView">
|
||||
<item name="android:childDivider">@color/toolbar_divider_grey</item>
|
||||
<item name="android:drawSelectorOnTop">true</item>
|
||||
</style>
|
||||
|
||||
<!-- TabsLayout Row -->
|
||||
<style name="TabLayoutItemTextAppearance">
|
||||
<style name="TabLayoutItemTextAppearance"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:textColor">#FFFFFFFF</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:ellipsize">middle</item>
|
||||
</style>
|
||||
|
||||
<!-- TabsLayout RemoteTabs Row Url -->
|
||||
<style name="TabLayoutItemTextAppearance.Url">
|
||||
<style name="TabLayoutItemTextAppearance.Url"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:textColor">#FFA4A7A9</item>
|
||||
</style>
|
||||
|
||||
@ -579,8 +562,8 @@
|
||||
</style>
|
||||
|
||||
<style name="PopupAnimation">
|
||||
<item name="@android:windowEnterAnimation">@anim/popup_show</item>
|
||||
<item name="@android:windowExitAnimation">@anim/popup_hide</item>
|
||||
<item name="android:windowEnterAnimation">@anim/popup_show</item>
|
||||
<item name="android:windowExitAnimation">@anim/popup_hide</item>
|
||||
</style>
|
||||
|
||||
<style name="ToastBase">
|
||||
@ -737,7 +720,8 @@
|
||||
<item name="android:background">@drawable/tab_indicator_background</item>
|
||||
</style>
|
||||
|
||||
<style name="TabInput.Tab">
|
||||
<style name="TabInput.Tab"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:background">@drawable/tabs_strip_indicator</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:minHeight">@dimen/menu_item_row_height</item>
|
||||
@ -798,7 +782,8 @@
|
||||
<item name="android:layout_marginBottom">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="RemoteTabsPanelItem.TextAppearance.Linkified">
|
||||
<style name="RemoteTabsPanelItem.TextAppearance.Linkified"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="android:clickable">true</item>
|
||||
<item name="android:focusable">true</item>
|
||||
<item name="android:textColor">#0092DB</item>
|
||||
@ -820,8 +805,6 @@
|
||||
<item name="textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<style name="TabQueueActivity" parent="android:style/Theme.NoDisplay" />
|
||||
|
||||
<style name="ActivityStreamContextMenuText">
|
||||
<item name="android:textSize">16sp</item>
|
||||
</style>
|
||||
@ -831,7 +814,8 @@
|
||||
<item name="android:listDivider">@drawable/as_contextmenu_divider</item>
|
||||
</style>
|
||||
|
||||
<style name="ActivityStreamButton" parent="Widget.AppCompat.Button.Colored">
|
||||
<style name="ActivityStreamButton" parent="Widget.AppCompat.Button.Colored"
|
||||
tools:ignore="UnusedResources">
|
||||
<item name="colorButtonNormal">@color/link_blue</item>
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
</style>
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
@ -15,7 +16,6 @@ import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserContract.PageMetadata;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.db.BrowserProvider;
|
||||
import org.mozilla.gecko.db.LocalBrowserDB;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
@ -27,11 +27,8 @@ public class GlobalPageMetadataTest {
|
||||
public void testQueueing() throws Exception {
|
||||
BrowserDB db = new LocalBrowserDB("default");
|
||||
|
||||
BrowserProvider provider = new BrowserProvider();
|
||||
final ContentProvider provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
try {
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
|
||||
ShadowContentResolver cr = new ShadowContentResolver();
|
||||
ContentProviderClient pageMetadataClient = cr.acquireContentProviderClient(PageMetadata.CONTENT_URI);
|
||||
|
||||
@ -64,11 +61,8 @@ public class GlobalPageMetadataTest {
|
||||
// Start listening for events.
|
||||
GlobalPageMetadata.getInstance().init();
|
||||
|
||||
BrowserProvider provider = new BrowserProvider();
|
||||
final ContentProvider provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
try {
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
|
||||
ShadowContentResolver cr = new ShadowContentResolver();
|
||||
ContentProviderClient historyClient = cr.acquireContentProviderClient(BrowserContract.History.CONTENT_URI);
|
||||
ContentProviderClient pageMetadataClient = cr.acquireContentProviderClient(PageMetadata.CONTENT_URI);
|
||||
@ -171,4 +165,4 @@ public class GlobalPageMetadataTest {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,29 +3,21 @@
|
||||
|
||||
package org.mozilla.gecko.icons.loader;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.background.db.DelegatingTestContentProvider;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.db.BrowserProvider;
|
||||
import org.mozilla.gecko.icons.IconDescriptor;
|
||||
import org.mozilla.gecko.icons.IconRequest;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.icons.Icons;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@ -46,9 +38,7 @@ public class TestLegacyLoader {
|
||||
// We need to ensure we close our db connection properly.
|
||||
// This is the only test in this class that actually accesses a database. If that changes,
|
||||
// move BrowserProvider registration into a @Before method, and provider.shutdown into @After.
|
||||
final BrowserProvider provider = new BrowserProvider();
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
final ContentProvider provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
try {
|
||||
final IconRequest request = Icons.with(RuntimeEnvironment.application)
|
||||
.pageUrl(TEST_PAGE_URL)
|
||||
@ -61,8 +51,8 @@ public class TestLegacyLoader {
|
||||
|
||||
verify(loader).loadBitmapFromDatabase(request);
|
||||
Assert.assertNull(response);
|
||||
// Close any open db connections.
|
||||
} finally {
|
||||
// Close any open db connections.
|
||||
provider.shutdown();
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ public class TestLookupIconUrl {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MemoryStorage.get().evictAll();
|
||||
DiskStorage.get(RuntimeEnvironment.application).evictAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -12,13 +12,17 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.util.NetworkUtils.*;
|
||||
import org.mozilla.gecko.util.NetworkUtils.ConnectionSubType;
|
||||
import org.mozilla.gecko.util.NetworkUtils.ConnectionType;
|
||||
import org.mozilla.gecko.util.NetworkUtils.NetworkStatus;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.internal.ShadowExtractor;
|
||||
import org.robolectric.shadow.api.Shadow;
|
||||
import org.robolectric.shadows.ShadowConnectivityManager;
|
||||
import org.robolectric.shadows.ShadowNetworkInfo;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(TestRunner.class)
|
||||
public class NetworkUtilsTest {
|
||||
@ -31,7 +35,7 @@ public class NetworkUtilsTest {
|
||||
|
||||
// Not using Shadows.shadowOf(connectivityManager) because of Robolectric bug when using API23+
|
||||
// See: https://github.com/robolectric/robolectric/issues/1862
|
||||
shadowConnectivityManager = (ShadowConnectivityManager) ShadowExtractor.extract(connectivityManager);
|
||||
shadowConnectivityManager = (ShadowConnectivityManager) Shadow.extract(connectivityManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -182,4 +186,4 @@ public class NetworkUtilsTest {
|
||||
);
|
||||
assertEquals(NetworkStatus.UP, NetworkUtils.getNetworkStatus(connectivityManager));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
sdk=21
|
||||
sdk=23
|
||||
constants=org.mozilla.gecko.BuildConfig
|
||||
packageName=org.mozilla.gecko
|
||||
|
@ -1,6 +1,7 @@
|
||||
#filter substitution
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="@ANDROID_PACKAGE_NAME@"
|
||||
android:installLocation="internalOnly"
|
||||
android:versionCode="@ANDROID_VERSION_CODE@"
|
||||
@ -133,7 +134,7 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.WEB_SEARCH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
@ -159,7 +160,7 @@
|
||||
android:resource="@integer/assist_launch_icon_res"/>
|
||||
|
||||
<!-- For XPI installs from websites and the download manager. -->
|
||||
<intent-filter>
|
||||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="file" />
|
||||
@ -169,7 +170,7 @@
|
||||
</intent-filter>
|
||||
|
||||
<!-- For XPI installs from file: URLs. -->
|
||||
<intent-filter>
|
||||
<intent-filter tools:ignore="AppLinkUrlError">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:host="" />
|
||||
|
@ -27,6 +27,8 @@ GARBAGE_DIRS += classes db jars res sync services generated
|
||||
|
||||
gradle_dir := $(topobjdir)/gradle/build/mobile/android
|
||||
|
||||
ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
|
||||
# The bootclasspath is functionally identical to the classpath, but allows the
|
||||
# classes given to redefine classes in core packages, such as java.lang.
|
||||
# android.jar is here as it provides Android's definition of the Java Standard
|
||||
@ -143,7 +145,6 @@ uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||
java_bundled_libs := $(call uniq,$(java_bundled_libs))
|
||||
java_bundled_libs := $(subst $(NULL) ,:,$(strip $(java_bundled_libs)))
|
||||
|
||||
ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
GECKOVIEW_JARS = \
|
||||
constants.jar \
|
||||
gecko-R.jar \
|
||||
@ -175,16 +176,6 @@ ifdef MOZ_ANDROID_MLS_STUMBLER
|
||||
FENNEC_JARS += ../stumbler/stumbler.jar
|
||||
endif
|
||||
|
||||
else # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
|
||||
GECKOVIEW_JARS := $(gradle_dir)/geckoview/intermediates/bundles/debug/classes.jar
|
||||
FENNEC_JARS := $(gradle_dir)/app/intermediates/packaged/officialPhoton/debug/classes.jar
|
||||
|
||||
$(GECKOVIEW_JARS): .gradle.deps
|
||||
$(FENNEC_JARS): .gradle.deps
|
||||
|
||||
endif # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
|
||||
geckoview_jars_classpath := $(subst $(NULL) ,:,$(strip $(GECKOVIEW_JARS)))
|
||||
|
||||
# All the jars we're compiling from source. (not to be confused with
|
||||
@ -232,6 +223,8 @@ endif # MOZ_INSTALL_TRACKING
|
||||
|
||||
library_jars := $(subst $(NULL) ,:,$(strip $(library_jars)))
|
||||
|
||||
endif # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
|
||||
ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
define gradle_command
|
||||
$(1): $(2)
|
||||
@ -244,7 +237,7 @@ $(eval $(call gradle_command,.gradle.deps,.aapt.deps FORCE))
|
||||
|
||||
classes.dex: .gradle.deps
|
||||
$(REPORT_BUILD)
|
||||
cp $(gradle_dir)/app/intermediates/transforms/dex/officialPhoton/debug/folders/1000/1f/main/classes.dex $@
|
||||
cp $(gradle_dir)/app/intermediates/transforms/dexMerger/officialWithoutGeckoBinariesNoMinApiPhoton/debug/0/classes.dex classes.dex
|
||||
|
||||
GeneratedJNIWrappers.cpp GeneratedJNIWrappers.h GeneratedJNINatives.h : .gradle.deps
|
||||
$(REPORT_BUILD)
|
||||
@ -252,7 +245,7 @@ GeneratedJNIWrappers.cpp GeneratedJNIWrappers.h GeneratedJNINatives.h : .gradle.
|
||||
FennecJNIWrappers.cpp FennecJNIWrappers.h FennecJNINatives.h: .gradle.deps
|
||||
$(REPORT_BUILD)
|
||||
|
||||
else
|
||||
else # MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
|
||||
classes.dex: .proguard.deps
|
||||
$(REPORT_BUILD)
|
||||
$(DX) --dex --output=classes.dex --force-jumbo jars-proguarded
|
||||
@ -273,19 +266,6 @@ endif
|
||||
|
||||
proguard_config_dir=$(topsrcdir)/mobile/android/config/proguard
|
||||
|
||||
# This stanza ensures that the set of GeckoView classes does not depend on too
|
||||
# much of Fennec, where "too much" is defined as the set of potentially
|
||||
# non-GeckoView classes that GeckoView already depended on at a certain point in
|
||||
# time. The idea is to set a high-water mark that is not to be crossed.
|
||||
classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar
|
||||
.geckoview.deps: geckoview.ddf $(classycle_jar) $(ALL_JARS)
|
||||
$(JAVA) -cp $(classycle_jar) \
|
||||
classycle.dependency.DependencyChecker \
|
||||
-mergeInnerClasses \
|
||||
-dependencies=@$< \
|
||||
$(ALL_JARS)
|
||||
@$(TOUCH) $@
|
||||
|
||||
# First, we delete debugging information from libraries. Having line-number
|
||||
# information for libraries for which we lack the source isn't useful, so this
|
||||
# saves us a bit of space. Importantly, Proguard has a bug causing it to
|
||||
@ -312,7 +292,7 @@ classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar
|
||||
# outputs are fresher than the target, preventing a subsequent
|
||||
# invocation from thinking Proguard's outputs are stale. This is safe
|
||||
# because Make removes the target file if any recipe command fails.
|
||||
.proguard.deps: .geckoview.deps .bundled.proguard.deps $(ALL_JARS) $(proguard_config_dir)/proguard.cfg $(PROGUARD_JAR)
|
||||
.proguard.deps: .bundled.proguard.deps $(ALL_JARS) $(proguard_config_dir)/proguard.cfg $(PROGUARD_JAR)
|
||||
$(REPORT_BUILD)
|
||||
@$(TOUCH) $@
|
||||
$(JAVA) \
|
||||
@ -504,7 +484,7 @@ $(eval $(call gradle_command,.gradle.nodeps,AndroidManifest.xml $(constants_PP_J
|
||||
.aapt.nodeps: .gradle.nodeps FORCE
|
||||
@$(TOUCH) $@
|
||||
cp $(GRADLE_ANDROID_APP_APK) gecko-nodeps.ap_
|
||||
cp $(gradle_dir)/app/intermediates/transforms/dex/officialPhoton/debug/folders/1000/1f/main/classes.dex classes.dex
|
||||
cp $(gradle_dir)/app/intermediates/transforms/dexMerger/officialWithoutGeckoBinariesNoMinApiPhoton/debug/0/classes.dex classes.dex
|
||||
else
|
||||
# .aapt.nodeps: AndroidManifest.xml FORCE
|
||||
$(eval $(call aapt_command,.aapt.nodeps,AndroidManifest.xml FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/))
|
||||
|
@ -1,74 +0,0 @@
|
||||
# This is a Classycle dependency definition file that asserts that the contents
|
||||
# of the GeckoView library (Classycle set [lib]) is a dependency (but does not
|
||||
# depend) on Fennec (Classycle set [main]). The additional Classycle set
|
||||
# [middle] consists of classes referenced by GeckoView that probably should not
|
||||
# be referenced. We want this middle set to shrink over time.
|
||||
|
||||
show allResults
|
||||
|
||||
[lib] = \
|
||||
org.mozilla.gecko.gfx.* \
|
||||
org.mozilla.gecko.mozglue.* \
|
||||
org.mozilla.gecko.sqlite.* \
|
||||
org.mozilla.gecko.util.* \
|
||||
org.mozilla.gecko.AndroidGamepadManager \
|
||||
org.mozilla.gecko.AppConstants \
|
||||
org.mozilla.gecko.ContextGetter \
|
||||
org.mozilla.gecko.CrashHandler \
|
||||
org.mozilla.gecko.EventDispatcher \
|
||||
org.mozilla.gecko.GeckoAccessibility \
|
||||
org.mozilla.gecko.GeckoAppShell \
|
||||
org.mozilla.gecko.GeckoBatteryManager \
|
||||
org.mozilla.gecko.GeckoEditable \
|
||||
org.mozilla.gecko.GeckoEditableClient \
|
||||
org.mozilla.gecko.GeckoEditableListener \
|
||||
org.mozilla.gecko.GeckoEvent \
|
||||
org.mozilla.gecko.GeckoInputConnection \
|
||||
org.mozilla.gecko.GeckoJavaSampler \
|
||||
org.mozilla.gecko.GeckoNetworkManager \
|
||||
org.mozilla.gecko.GeckoProfile \
|
||||
org.mozilla.gecko.GeckoScreenOrientation \
|
||||
org.mozilla.gecko.GeckoSharedPrefs \
|
||||
org.mozilla.gecko.GeckoThread \
|
||||
org.mozilla.gecko.GeckoView \
|
||||
org.mozilla.gecko.GlobalHistory \
|
||||
org.mozilla.gecko.InputMethods \
|
||||
org.mozilla.gecko.NSSBridge \
|
||||
org.mozilla.gecko.NotificationClient \
|
||||
org.mozilla.gecko.NotificationHandler \
|
||||
org.mozilla.gecko.PrefsHelper \
|
||||
org.mozilla.gecko.SysInfo \
|
||||
org.mozilla.gecko.TouchEventInterceptor \
|
||||
org.mozilla.gecko.ZoomConstraints
|
||||
|
||||
[middle] = \
|
||||
org.mozilla.gecko.prompts.* \
|
||||
org.mozilla.gecko.FormAssistPopup \
|
||||
org.mozilla.gecko.GeckoActivity \
|
||||
org.mozilla.gecko.GeckoApp \
|
||||
org.mozilla.gecko.GeckoProfileDirectories \
|
||||
org.mozilla.gecko.GuestSession \
|
||||
org.mozilla.gecko.R \
|
||||
org.mozilla.gecko.Tab \
|
||||
org.mozilla.gecko.Tabs \
|
||||
org.mozilla.gecko.Telemetry \
|
||||
org.mozilla.gecko.TelemetryContract \
|
||||
org.mozilla.gecko.ThumbnailHelper \
|
||||
org.mozilla.gecko.db.BrowserDB \
|
||||
org.mozilla.gecko.db.LocalBrowserDB \
|
||||
org.mozilla.gecko.distribution.Distribution \
|
||||
org.mozilla.gecko.icons.*
|
||||
|
||||
[main] = org.mozilla.gecko.* excluding [lib] [middle]
|
||||
|
||||
check sets [lib] [middle] [main]
|
||||
|
||||
# Bug 1107134: it appears that Classycle can be fooled if the Java
|
||||
# compiler inlines a constant from [main] into [lib]. That is, [main]
|
||||
# really does depend on [lib] but Classycle only sees the dependency
|
||||
# with some javac versions. For now, disable the check. Yes, this
|
||||
# processing is useless without this check.
|
||||
# check [lib] directlyIndependentOf [main]
|
||||
|
||||
# This fails; if this passed, GeckoView would be ready to extract from Fennec.
|
||||
# check [lib] independentOf [middle]
|
@ -46,7 +46,9 @@ import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
|
||||
@SuppressLint("Registered") // This activity is only registered in the manifest if MOZ_CRASHREPORTER is set
|
||||
// Registered: This activity is only registered in the manifest if MOZ_CRASHREPORTER is set.
|
||||
// CutPasteId: This lint is not worth fixing. To fix it, cache all the findViewById results.
|
||||
@SuppressLint("Registered,CutPasteId")
|
||||
public class CrashReporter extends AppCompatActivity
|
||||
{
|
||||
private static final String LOGTAG = "GeckoCrashReporter";
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.activitystream;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
@ -216,8 +217,7 @@ public class ActivityStreamTelemetry {
|
||||
break;
|
||||
// While we also have a "blank" type, it is not used by Activity Stream.
|
||||
case BrowserContract.TopSites.TYPE_BLANK:
|
||||
default:
|
||||
throw new IllegalStateException("Unknown top site type: " + topSite.getType());
|
||||
throw new IllegalStateException("Unknown top site type :" + (int) topSite.getType());
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -226,4 +226,5 @@ public class Highlight implements WebpageRowModel {
|
||||
|
||||
// The Highlights cursor automatically notifies of data changes, so nothing needs to be done here.
|
||||
@Override
|
||||
public void onStateCommitted() {}}
|
||||
public void onStateCommitted() {}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.SiteIdentity;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.toolbar.SecurityModeUtil;
|
||||
import org.mozilla.gecko.toolbar.CustomTabsSecurityPopup;
|
||||
import org.mozilla.gecko.util.ColorUtil;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,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/. */
|
||||
|
||||
package org.mozilla.gecko.toolbar;
|
||||
package org.mozilla.gecko.customtabs;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
|
@ -42,8 +42,6 @@ import java.util.Arrays;
|
||||
*
|
||||
* * {@link AbstractPerProfileDatabaseProvider} provides a simple abstraction for
|
||||
* querying databases that are stored in the user's profile directory.
|
||||
* * {@link PerProfileDatabaseProvider} is a simple version that only allows a
|
||||
* single ContentProvider to access each per-profile database.
|
||||
* * {@link SharedBrowserDatabaseProvider} is an example of a per-profile provider
|
||||
* that allows for multiple providers to safely work with the same databases.
|
||||
*/
|
||||
@ -134,7 +132,7 @@ public abstract class AbstractTransactionalProvider extends ContentProvider {
|
||||
* If we're not in a batch, but we are in a write transaction,
|
||||
* end it.
|
||||
*
|
||||
* @see PerProfileDatabaseProvider#markWriteSuccessful(SQLiteDatabase)
|
||||
* @see AbstractTransactionalProvider#markWriteSuccessful(SQLiteDatabase)
|
||||
*/
|
||||
protected void endWrite(final SQLiteDatabase db) {
|
||||
if (isInBatch()) {
|
||||
|
@ -306,7 +306,11 @@ public class LocalBrowserDB extends BrowserDB {
|
||||
bookmarkValue.put(Bookmarks.FAVICON_ID, faviconID);
|
||||
faviconValues.add(iconValue);
|
||||
}
|
||||
} catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.wtf(LOGTAG, "Reflection failure.", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.wtf(LOGTAG, "Reflection failure.", e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Log.wtf(LOGTAG, "Reflection failure.", e);
|
||||
}
|
||||
}
|
||||
@ -502,7 +506,13 @@ public class LocalBrowserDB extends BrowserDB {
|
||||
faviconField.setAccessible(true);
|
||||
|
||||
return faviconField.getInt(null);
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
// We'll end up here for any default bookmark that doesn't have a favicon in
|
||||
// resources/raw/ (i.e., about:firefox). When this happens, the Favicons service will
|
||||
// fall back to the default branding icon for about pages. Non-about pages should always
|
||||
// specify an icon; otherwise, the placeholder globe favicon will be used.
|
||||
Log.d(LOGTAG, "No raw favicon resource found for " + name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// We'll end up here for any default bookmark that doesn't have a favicon in
|
||||
// resources/raw/ (i.e., about:firefox). When this happens, the Favicons service will
|
||||
// fall back to the default branding icon for about pages. Non-about pages should always
|
||||
|
@ -1,55 +0,0 @@
|
||||
/* 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 org.mozilla.gecko.db;
|
||||
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.db.PerProfileDatabases.DatabaseHelperFactory;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
/**
|
||||
* Abstract class containing methods needed to make a SQLite-based content
|
||||
* provider with a database helper of type T, where one database helper is
|
||||
* held per profile.
|
||||
*/
|
||||
public abstract class PerProfileDatabaseProvider<T extends SQLiteOpenHelper> extends AbstractPerProfileDatabaseProvider {
|
||||
private PerProfileDatabases<T> databases;
|
||||
|
||||
@Override
|
||||
protected PerProfileDatabases<T> getDatabases() {
|
||||
return databases;
|
||||
}
|
||||
|
||||
protected abstract String getDatabaseName();
|
||||
|
||||
/**
|
||||
* Creates and returns an instance of the appropriate DB helper.
|
||||
*
|
||||
* @param context to use to create the database helper
|
||||
* @param databasePath path to the DB file
|
||||
* @return instance of the database helper
|
||||
*/
|
||||
protected abstract T createDatabaseHelper(Context context, String databasePath);
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
synchronized (this) {
|
||||
databases = new PerProfileDatabases<T>(
|
||||
getContext(), getDatabaseName(), new DatabaseHelperFactory<T>() {
|
||||
@Override
|
||||
public T makeDatabaseHelper(Context context, String databasePath) {
|
||||
final T helper = createDatabaseHelper(context, databasePath);
|
||||
if (Versions.feature16Plus) {
|
||||
helper.setWriteAheadLoggingEnabled(true);
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.dlc;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.util.Log;
|
||||
@ -100,7 +101,7 @@ public abstract class BaseAction {
|
||||
} else if (content.isHyphenationDictionary()) {
|
||||
destinationDirectory = new File(context.getApplicationInfo().dataDir, "hyphenation");
|
||||
} else {
|
||||
throw new UnrecoverableDownloadContentException("Can't determine destination for kind: " + content.getKind());
|
||||
throw new UnrecoverableDownloadContentException("Can't determine destination for kind: " + (String) content.getKind());
|
||||
}
|
||||
|
||||
if (!destinationDirectory.exists() && !destinationDirectory.mkdirs()) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
package org.mozilla.gecko.dlc;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
@ -106,7 +107,7 @@ public class DownloadAction extends BaseAction {
|
||||
}
|
||||
|
||||
if (!content.isAssetArchive()) {
|
||||
Log.e(LOGTAG, "Downloaded content is not of type 'asset-archive': " + content.getType());
|
||||
Log.e(LOGTAG, "Downloaded content is not of type 'asset-archive': " + (String) content.getType());
|
||||
temporaryFile.delete();
|
||||
DownloadContentTelemetry.eventDownloadFailure(content, DownloadContentTelemetry.ERROR_LOGIC);
|
||||
continue;
|
||||
|
@ -1,68 +0,0 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* 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 org.mozilla.gecko.home;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ExpandableListView;
|
||||
|
||||
/**
|
||||
* <code>HomeExpandableListView</code> is a custom extension of
|
||||
* <code>ExpandableListView<code>, that packs a <code>HomeContextMenuInfo</code>
|
||||
* when any of its rows is long pressed.
|
||||
* <p>
|
||||
* This is the <code>ExpandableListView</code> equivalent of
|
||||
* <code>HomeListView</code>.
|
||||
*/
|
||||
public class HomeExpandableListView extends ExpandableListView
|
||||
implements OnItemLongClickListener {
|
||||
|
||||
// ContextMenuInfo associated with the currently long pressed list item.
|
||||
private HomeContextMenuInfo mContextMenuInfo;
|
||||
|
||||
// ContextMenuInfo factory.
|
||||
private HomeContextMenuInfo.ExpandableFactory mContextMenuInfoFactory;
|
||||
|
||||
public HomeExpandableListView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public HomeExpandableListView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public HomeExpandableListView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
setOnItemLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (mContextMenuInfoFactory == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// HomeExpandableListView items can correspond to groups and children.
|
||||
// The factory can determine whether to add context menu for either,
|
||||
// both, or none by unpacking the given position.
|
||||
mContextMenuInfo = mContextMenuInfoFactory.makeInfoForAdapter(view, position, id, getExpandableListAdapter());
|
||||
return showContextMenuForChild(HomeExpandableListView.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextMenuInfo getContextMenuInfo() {
|
||||
return mContextMenuInfo;
|
||||
}
|
||||
|
||||
public void setContextMenuInfoFactory(final HomeContextMenuInfo.ExpandableFactory factory) {
|
||||
mContextMenuInfoFactory = factory;
|
||||
}
|
||||
}
|
@ -294,12 +294,14 @@ public class UpdateService extends IntentService {
|
||||
public void run() {
|
||||
showPermissionNotification();
|
||||
sendCheckUpdateResult(CheckUpdateResult.NOT_AVAILABLE);
|
||||
}})
|
||||
}
|
||||
})
|
||||
.run(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startDownload(info, flags);
|
||||
}});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startDownload(UpdateInfo info, int flags) {
|
||||
|
@ -101,4 +101,8 @@ final class UnusedResourcesUtil {
|
||||
public static final int[] USED_IN_PAGE_ACTION = {
|
||||
R.drawable.add_to_homescreen
|
||||
};
|
||||
|
||||
public static final int[] USED_IN_LEANPLUM_EXPANDABLE_LIST_ACTIVITY = {
|
||||
R.style.Widget_ExpandableListView,
|
||||
};
|
||||
}
|
||||
|
@ -22,9 +22,6 @@ with Files('pocket-api-sandbox.token'):
|
||||
with Files('android-services.mozbuild'):
|
||||
BUG_COMPONENT = ('Android Background Services', 'Android Sync')
|
||||
|
||||
with Files('geckoview.ddf'):
|
||||
BUG_COMPONENT = ('Firefox for Android', 'GeckoView')
|
||||
|
||||
with Files('crashreporter/**'):
|
||||
BUG_COMPONENT = ('Firefox for Android', 'General')
|
||||
|
||||
@ -568,7 +565,6 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
|
||||
'db/LocalURLMetadata.java',
|
||||
'db/LoginsProvider.java',
|
||||
'db/PasswordsProvider.java',
|
||||
'db/PerProfileDatabaseProvider.java',
|
||||
'db/PerProfileDatabases.java',
|
||||
'db/RemoteClient.java',
|
||||
'db/RemoteTab.java',
|
||||
@ -666,7 +662,6 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
|
||||
'home/HomeConfigLoader.java',
|
||||
'home/HomeConfigPrefsBackend.java',
|
||||
'home/HomeContextMenuInfo.java',
|
||||
'home/HomeExpandableListView.java',
|
||||
'home/HomeFragment.java',
|
||||
'home/HomeListView.java',
|
||||
'home/HomePager.java',
|
||||
@ -1165,7 +1160,7 @@ gbjar.extra_jars += [CONFIG['ANDROID_DESIGN_AAR_LIB']]
|
||||
gbjar.extra_jars += [CONFIG['ANDROID_RECYCLERVIEW_V7_AAR_LIB']]
|
||||
gbjar.extra_jars += [CONFIG['ANDROID_CUSTOMTABS_AAR_LIB']]
|
||||
|
||||
gbjar.javac_flags += ['-Xlint:all,-deprecation,-fallthrough', '-J-Xmx512m', '-J-Xms128m']
|
||||
gbjar.javac_flags += ['-Xlint:all,-deprecation,-fallthrough,-cast', '-J-Xmx512m', '-J-Xms128m']
|
||||
|
||||
# gecko-thirdparty is a good place to put small independent libraries
|
||||
gtjar = add_java_jar('gecko-thirdparty')
|
||||
|
@ -1,22 +0,0 @@
|
||||
Copyright (c) 2003-2008, Franz-Josef Elmer, All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Binary file not shown.
101
mobile/android/docs/gradle.rst
Normal file
101
mobile/android/docs/gradle.rst
Normal file
@ -0,0 +1,101 @@
|
||||
.. -*- Mode: rst; fill-column: 80; -*-
|
||||
|
||||
=================================
|
||||
The Fennec Gradle configuration
|
||||
=================================
|
||||
|
||||
The Fennec Gradle configuration has three major facets:
|
||||
|
||||
1. separation into Gradle projects;
|
||||
2. Android-Gradle build configurations using `flavorDimensions`;
|
||||
3. integration into the larger `moz.build` build system.
|
||||
|
||||
Separation into Gradle projects
|
||||
===============================
|
||||
|
||||
The Fennec source code is separated into multiple Gradle projects. Right now,
|
||||
there are only a few: `:app`, `:geckoview`, `:thirdparty`, etc. Over time, pieces
|
||||
of the Fennec source code will be extracted into separate, more-or-less
|
||||
stand-alone Gradle projects (e.g., `:services`, `:stumbler`, `:media`) and use
|
||||
modern techniques such as dependency injection to configure themselves at
|
||||
runtime.
|
||||
|
||||
The `:omnijar` project is special and exists only to support integration with
|
||||
Android Studio.
|
||||
|
||||
The details of the Gradle projects are reflected in the root `settings.gradle`
|
||||
and the `**/build.gradle` files throughout the tree.
|
||||
|
||||
Android-Gradle build configurations
|
||||
===================================
|
||||
|
||||
The Fennec `:app` project uses the Android-Gradle build plugin
|
||||
`flavorDimensions` feature set to support many different configurations. The
|
||||
Gradle integration must support many often conflicting requirements; the flavor
|
||||
dimensions chosen support these requirements.
|
||||
|
||||
Version 3.0+ of the Android-Gradle build plugin improves support for "variant
|
||||
dependencies". This makes it easier for a consuming application (for us,
|
||||
`:app`) to use the appropriate configuration of consumed libraries (for us,
|
||||
`:geckoview`). This allows us to simplify the logic around packaging the Gecko
|
||||
libraries and Omnijar.
|
||||
|
||||
The details of the Android-Gradle build configurations are reflected
|
||||
`**/build.gradle` files throughout the tree, in the
|
||||
`mobile/android/gradle/*.gradle` files, and in the configuration baked into
|
||||
`mobile/android/gradle.configure`.
|
||||
|
||||
The notable flavor dimensions are:
|
||||
|
||||
audience
|
||||
--------
|
||||
|
||||
The `audience` flavor dimension determines who the build is for. "local"
|
||||
audiences are developers: they should get extra logging and as much support for
|
||||
building Fennec as possible. In particular, "local" audiences get support for
|
||||
modifying the Android manifest and regenerating the pre-processed `strings.xml`
|
||||
files while building with Gradle from within Android Studio.
|
||||
|
||||
"official" audiences are end users: they should get Mozilla's official branding
|
||||
and have security-sensitive developer features disabled. The "official"
|
||||
audience corresponds roughly to the `MOZILLA_OFFICIAL=1` build setting.
|
||||
|
||||
**Builds shipped to the Google Play Store are always for "official" audiences.**
|
||||
|
||||
geckoBinaries
|
||||
-------------
|
||||
|
||||
For deep historical reasons, Mozilla's build system has multiple stages, the
|
||||
most important of which are the build stage and the package stage. During the
|
||||
build stage, the Gecko compiled libraries (e.g., `libxul.so`) and the Omnijar
|
||||
have not yet been built. These libraries are only available during the package
|
||||
stage. Gradle builds always want to include the Gecko libraries and the
|
||||
Omnijar.
|
||||
|
||||
To accommodate the different stages, the build stage always invokes
|
||||
"withoutGeckoBinaries" Gradle configurations. These configurations don't expect
|
||||
or use the Gecko libraries or Omnijar. At the moment, the package stage also
|
||||
invokes "withoutGeckoBinaries", but in the future, the package stage will invoke
|
||||
"withGeckoBinaries" Gradle configurations to simplify the packaging of libraries
|
||||
and the omnijar.
|
||||
|
||||
**Local developers almost always want to build "withGeckoBinaries", so that the
|
||||
APK files produced can be run on device.**
|
||||
|
||||
minApi
|
||||
------
|
||||
|
||||
At various times in the past, Fennec has supported APK splits, producing APKs
|
||||
that support only specific Android versions. While this is not used at this
|
||||
time, there are certain developer options (i.e., options that should only apply
|
||||
to "local" audiences) that *also* depend on the target Android version. This
|
||||
flavor dimension allows to opt in to those options, improving the speed of
|
||||
development.
|
||||
|
||||
Integration into the larger `moz.build` build system
|
||||
====================================================
|
||||
|
||||
The details of the Gradle integration into the larger `moz.build` system are
|
||||
mostly captured in configuration baked into `mobile/android/gradle.configure`.
|
||||
This configuration is reflected in the Android-specific `mach android *`
|
||||
commands defined in `mobile/android/mach_commands.py`.
|
@ -20,6 +20,7 @@ Contents:
|
||||
defaultdomains
|
||||
shutdown
|
||||
push
|
||||
gradle
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
@ -2,6 +2,8 @@ buildDir "${topobjdir}/gradle/build/mobile/android/geckoview"
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
apply from: "${topsrcdir}/mobile/android/gradle/product_flavors.gradle"
|
||||
|
||||
// This converts MOZ_APP_VERSION into an integer
|
||||
// version code.
|
||||
//
|
||||
@ -38,12 +40,8 @@ def computeVersionCode() {
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.compileSdkVersion
|
||||
buildToolsVersion project.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
defaultPublishConfig 'release'
|
||||
publishNonDefault true
|
||||
|
||||
targetSdkVersion project.ext.targetSdkVersion
|
||||
minSdkVersion project.ext.minSdkVersion
|
||||
manifestPlaceholders = project.ext.manifestPlaceholders
|
||||
@ -103,14 +101,8 @@ android {
|
||||
buildConfigField 'boolean', 'MOZILLA_OFFICIAL', mozconfig.substs.MOZILLA_OFFICIAL ? 'true' : 'false';
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
withGeckoBinaries {
|
||||
initWith release
|
||||
}
|
||||
withoutGeckoBinaries { // For clarity and consistency throughout the tree.
|
||||
initWith release
|
||||
}
|
||||
}
|
||||
project.configureProductFlavors.delegate = it
|
||||
project.configureProductFlavors()
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
@ -154,21 +146,16 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:palette-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:palette-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
}
|
||||
|
||||
apply from: "${topsrcdir}/mobile/android/gradle/with_gecko_binaries.gradle"
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
// Like 'debug', 'release', or 'withGeckoBinaries'.
|
||||
def buildType = variant.buildType.name
|
||||
|
||||
// It would be most natural for :geckoview to always include the Gecko
|
||||
// binaries, but that's difficult; see the notes in
|
||||
// mobile/android/gradle/with_gecko_binaries.gradle. Instead :app uses
|
||||
// :geckoview:release and handles it's own Gecko binary inclusion.
|
||||
if (buildType.equals('withGeckoBinaries')) {
|
||||
// See the notes in mobile/android/app/build.gradle for details on including
|
||||
// Gecko binaries and the Omnijar.
|
||||
if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
|
||||
configureVariantWithGeckoBinaries(variant)
|
||||
}
|
||||
|
||||
@ -202,12 +189,12 @@ android.libraryVariants.all { variant ->
|
||||
options.addStringOption('noqualifier', 'java.lang');
|
||||
}
|
||||
|
||||
task "javadocJar${name.capitalize()}"(type: Jar, dependsOn: javadoc) {
|
||||
def javadocJar = task("javadocJar${name.capitalize()}", type: Jar, dependsOn: javadoc) {
|
||||
classifier = 'javadoc'
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
task "sourcesJar${name.capitalize()}"(type: Jar) {
|
||||
def sourcesJar = task("sourcesJar${name.capitalize()}", type: Jar) {
|
||||
classifier 'sources'
|
||||
description = "Generate Javadoc for build variant $name"
|
||||
destinationDir = new File(destinationDir, variant.baseName)
|
||||
@ -216,7 +203,7 @@ android.libraryVariants.all { variant ->
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
configureVariantWithJNIWrappers(variant, "Generated")
|
||||
configureLibraryVariantWithJNIWrappers(variant, "Generated")
|
||||
}
|
||||
|
||||
apply plugin: 'maven'
|
||||
@ -245,7 +232,7 @@ afterEvaluate {
|
||||
// The bundle tasks are only present when the particular configuration is
|
||||
// being built, so this task might not exist. (This is due to the way the
|
||||
// Android Gradle plugin defines things during configuration.)
|
||||
def bundleWithGeckoBinaries = tasks.findByName('bundleWithGeckoBinaries')
|
||||
def bundleWithGeckoBinaries = tasks.findByName('bundleOfficialWithGeckoBinariesNoMinApiRelease')
|
||||
if (!bundleWithGeckoBinaries) {
|
||||
return
|
||||
}
|
||||
@ -259,10 +246,10 @@ afterEvaluate {
|
||||
|
||||
artifacts {
|
||||
// Instead of default (release) configuration, publish one with Gecko binaries.
|
||||
archives bundleWithGeckoBinaries
|
||||
archives bundleOfficialWithGeckoBinariesNoMinApiRelease
|
||||
// Javadoc and sources for developer ergononomics.
|
||||
archives javadocJarWithGeckoBinaries
|
||||
archives sourcesJarWithGeckoBinaries
|
||||
archives javadocJarOfficialWithGeckoBinariesNoMinApiRelease
|
||||
archives sourcesJarOfficialWithGeckoBinariesNoMinApiRelease
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
||||
private final int mPlayerId;
|
||||
private boolean mExoplayerSuspended = false;
|
||||
|
||||
private enum MediaDecoderPlayState{
|
||||
private enum MediaDecoderPlayState {
|
||||
PLAY_STATE_PREPARING,
|
||||
PLAY_STATE_PAUSED,
|
||||
PLAY_STATE_PLAYING
|
||||
|
@ -2,9 +2,10 @@ buildDir "${topobjdir}/gradle/build/mobile/android/geckoview_example"
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
apply from: "${topsrcdir}/mobile/android/gradle/product_flavors.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.compileSdkVersion
|
||||
buildToolsVersion project.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
targetSdkVersion project.ext.targetSdkVersion
|
||||
@ -17,52 +18,27 @@ android {
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
// This is extremely frustrating, but the only way to do it automation for
|
||||
// now. Without this, we only get a "debugAndroidTest" configuration; we
|
||||
// have no "withoutGeckoBinariesAndroidTest" configuration.
|
||||
testBuildType "withoutGeckoBinaries"
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
withGeckoBinaries { // For consistency with :geckoview project in Task Cluster invocations.
|
||||
initWith debug
|
||||
}
|
||||
withoutGeckoBinaries { // Logical negation of withGeckoBinaries.
|
||||
initWith debug
|
||||
}
|
||||
}
|
||||
|
||||
project.configureProductFlavors.delegate = it
|
||||
project.configureProductFlavors()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile 'junit:junit:4.12'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
compile 'com.android.support:support-annotations:23.4.0'
|
||||
implementation 'com.android.support:support-annotations:23.4.0'
|
||||
|
||||
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
|
||||
androidTestCompile 'com.android.support.test:runner:0.5'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
|
||||
androidTestImplementation 'com.android.support.test:runner:0.5'
|
||||
// Not defining this library again results in test-app assuming 23.1.1, and the following errors:
|
||||
// "Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (23.4.0) and test app (23.1.1) differ."
|
||||
androidTestCompile 'com.android.support:support-annotations:23.4.0'
|
||||
androidTestImplementation 'com.android.support:support-annotations:23.4.0'
|
||||
|
||||
debugCompile project(path: ':geckoview', configuration: "debug")
|
||||
releaseCompile project(path: ':geckoview', configuration: "release")
|
||||
withGeckoBinariesCompile project(path: ':geckoview', configuration: "withGeckoBinaries")
|
||||
withoutGeckoBinariesCompile project(path: ':geckoview', configuration: "withoutGeckoBinaries")
|
||||
}
|
||||
|
||||
apply from: "${topsrcdir}/mobile/android/gradle/with_gecko_binaries.gradle"
|
||||
|
||||
android.applicationVariants.all { variant ->
|
||||
// Like 'debug', 'release', or 'withoutGeckoBinaries'.
|
||||
def buildType = variant.buildType.name
|
||||
|
||||
// It would be most natural for :geckoview to always include the Gecko
|
||||
// binaries, but that's difficult; see the notes in
|
||||
// mobile/android/gradle/with_gecko_binaries.gradle. Instead we handle our
|
||||
// own Gecko binary inclusion.
|
||||
if (!buildType.equals('withoutGeckoBinaries')) {
|
||||
configureVariantWithGeckoBinaries(variant)
|
||||
}
|
||||
implementation project(path: ':geckoview')
|
||||
}
|
||||
|
@ -46,9 +46,6 @@ def gradle_android_build_config():
|
||||
else:
|
||||
return s
|
||||
|
||||
# It's not really possible to abstract the GeckoView details just yet; post
|
||||
# Android-Gradle plugin 3.0+, the configurations can be more sensible and
|
||||
# we'll do this work.
|
||||
def variant(productFlavors, buildType):
|
||||
return namespace(
|
||||
productFlavors=productFlavors,
|
||||
@ -59,7 +56,13 @@ def gradle_android_build_config():
|
||||
|
||||
return namespace(
|
||||
app=namespace(
|
||||
variant=variant(('official', 'photon'), 'debug'),
|
||||
variant=variant(('official', 'withoutGeckoBinaries', 'noMinApi', 'photon'), 'debug'),
|
||||
),
|
||||
geckoview=namespace(
|
||||
variant=variant(('official', 'withGeckoBinaries', 'noMinApi'), 'release'),
|
||||
),
|
||||
geckoview_example=namespace(
|
||||
variant=variant(('official', 'withGeckoBinaries', 'noMinApi'), 'debug'),
|
||||
),
|
||||
)
|
||||
|
||||
@ -82,7 +85,7 @@ set_config('GRADLE_ANDROID_APP_VARIANT_NAME', gradle_android_app_variant_name)
|
||||
def gradle_android_app_tasks(build_config):
|
||||
'''Gradle tasks run by |mach android assemble-app|.'''
|
||||
return [
|
||||
'geckoview:generateJNIWrappersForGeneratedRelease',
|
||||
'geckoview:generateJNIWrappersForGenerated{geckoview.variant.name}'.format(geckoview=build_config.geckoview),
|
||||
'app:generateJNIWrappersForFennec{app.variant.name}'.format(app=build_config.app),
|
||||
'app:assemble{app.variant.name}'.format(app=build_config.app),
|
||||
'app:assemble{app.variant.name}AndroidTest'.format(app=build_config.app),
|
||||
@ -92,14 +95,39 @@ set_config('GRADLE_ANDROID_APP_TASKS', gradle_android_app_tasks)
|
||||
|
||||
|
||||
@depends(gradle_android_build_config, check_build_environment)
|
||||
@imports(_from='itertools', _import='imap')
|
||||
def gradle_android_app_apks(build_config, build_env):
|
||||
'''Paths to APK files produced by |mach android assemble-app|.'''
|
||||
flavor = '-'.join(build_config.app.variant.productFlavors)
|
||||
buildType = build_config.app.variant.buildType
|
||||
f = '{}/gradle/build/mobile/android/app/outputs/apk/app-{}-{}.apk'
|
||||
g = '{}/gradle/build/mobile/android/app/outputs/apk/app-{}-{}-androidTest.apk'
|
||||
return namespace(app_apk=f.format(build_env.topobjdir, flavor, buildType),
|
||||
app_androidTest_apk=g.format(build_env.topobjdir, flavor, buildType))
|
||||
def capitalize(s):
|
||||
# str.capitalize lower cases trailing letters.
|
||||
if s:
|
||||
return s[0].upper() + s[1:]
|
||||
else:
|
||||
return s
|
||||
|
||||
def uncapitalize(s):
|
||||
if s:
|
||||
return s[0].lower() + s[1:]
|
||||
else:
|
||||
return s
|
||||
|
||||
# Like 'officialPhoton'.
|
||||
productFlavor = uncapitalize(''.join(imap(capitalize, build_config.app.variant.productFlavors)))
|
||||
# Like 'official-photon'.
|
||||
product_flavor = '-'.join(build_config.app.variant.productFlavors)
|
||||
|
||||
substs = {
|
||||
'topobjdir': build_env.topobjdir,
|
||||
'productFlavor': productFlavor,
|
||||
'product_flavor': product_flavor,
|
||||
'buildType': build_config.app.variant.buildType,
|
||||
}
|
||||
|
||||
f = '{topobjdir}/gradle/build/mobile/android/app/outputs/apk/{productFlavor}/{buildType}/app-{product_flavor}-{buildType}.apk'
|
||||
g = '{topobjdir}/gradle/build/mobile/android/app/outputs/apk/androidTest/{productFlavor}/{buildType}/app-{product_flavor}-{buildType}-androidTest.apk'
|
||||
|
||||
return namespace(app_apk=f.format(**substs),
|
||||
app_androidTest_apk=g.format(**substs))
|
||||
|
||||
set_config('GRADLE_ANDROID_APP_APK', gradle_android_app_apks.app_apk)
|
||||
set_config('GRADLE_ANDROID_APP_ANDROIDTEST_APK', gradle_android_app_apks.app_androidTest_apk)
|
||||
@ -146,13 +174,13 @@ def gradle_android_findbugs_tasks(build_config):
|
||||
set_config('GRADLE_ANDROID_FINDBUGS_TASKS', gradle_android_findbugs_tasks)
|
||||
|
||||
|
||||
@dependable
|
||||
def gradle_android_archive_geckoview_tasks():
|
||||
@depends(gradle_android_build_config)
|
||||
def gradle_android_archive_geckoview_tasks(build_config):
|
||||
'''Gradle tasks run by |mach android archive-geckoview|.'''
|
||||
return [
|
||||
'geckoview:assembleWithGeckoBinaries',
|
||||
'geckoview_example:assembleWithGeckoBinaries',
|
||||
'geckoview_example:assembleWithGeckoBinariesAndroidTest',
|
||||
'geckoview:assemble{geckoview.variant.name}'.format(geckoview=build_config.geckoview),
|
||||
'geckoview_example:assemble{geckoview_example.variant.name}'.format(geckoview_example=build_config.geckoview_example),
|
||||
'geckoview_example:assemble{geckoview_example.variant.name}AndroidTest'.format(geckoview_example=build_config.geckoview_example),
|
||||
'geckoview:uploadArchives',
|
||||
]
|
||||
|
||||
|
@ -5,16 +5,13 @@
|
||||
|
||||
// Bug 1353055 - Strip 'vars' debugging information to agree with moz.build.
|
||||
ext.configureVariantDebugLevel = { variant ->
|
||||
// Like 'debug', 'release', or 'withGeckoBinaries'.
|
||||
// Like 'debug' or 'release'.
|
||||
def buildType = variant.buildType.name
|
||||
|
||||
// For :app, like 'local', 'localOld', or 'official'. For other projects, null.
|
||||
def audienceDimension = variant.productFlavors[0]?.name
|
||||
|
||||
// The default is 'lines,source,vars', which includes debugging information
|
||||
// that is quite large: roughly 500kb for Fennec. Therefore we remove
|
||||
// 'vars' unless we're producing a debug build, where it is useful.
|
||||
if (!'debug'.equals(buildType) || 'official'.equals(audienceDimension)) {
|
||||
if (!'debug'.equals(buildType) || (variant.productFlavors*.name).contains('official')) {
|
||||
variant.javaCompile.options.debugOptions.debugLevel = 'lines,source'
|
||||
}
|
||||
}
|
||||
|
48
mobile/android/gradle/product_flavors.gradle
Normal file
48
mobile/android/gradle/product_flavors.gradle
Normal file
@ -0,0 +1,48 @@
|
||||
/* -*- Mode: Groovy; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* 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/. */
|
||||
|
||||
ext.configureProductFlavors = {
|
||||
flavorDimensions "audience", "geckoBinaries", "minApi"
|
||||
productFlavors {
|
||||
local {
|
||||
dimension "audience"
|
||||
}
|
||||
|
||||
// Automation builds. We use "official" rather than "automation" to drive these builds down
|
||||
// the list of configurations that Android Studio offers, thereby making it _not_ the
|
||||
// default. This avoids a common issue with "omni.ja" not being packed into the default APK
|
||||
// built and deployed by Android Studio.
|
||||
official {
|
||||
dimension "audience"
|
||||
}
|
||||
|
||||
withGeckoBinaries {
|
||||
dimension "geckoBinaries"
|
||||
}
|
||||
|
||||
withoutGeckoBinaries {
|
||||
dimension "geckoBinaries"
|
||||
}
|
||||
|
||||
// For API 21+ - with pre-dexing, this will be faster for local development.
|
||||
minApi21 {
|
||||
dimension "minApi"
|
||||
|
||||
// For pre-dexing, setting `minSdkVersion 21` allows the Android gradle plugin to
|
||||
// pre-DEX each module and produce an APK that can be tested on
|
||||
// Android Lollipop without time consuming DEX merging processes.
|
||||
minSdkVersion 21
|
||||
dexOptions {
|
||||
preDexLibraries true
|
||||
}
|
||||
}
|
||||
|
||||
// For API < 21 - does not support pre-dexing because local development
|
||||
// is slow in that case.
|
||||
noMinApi {
|
||||
dimension "minApi"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,46 +1,22 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
/* -*- Mode: Groovy; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* 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/. */
|
||||
|
||||
// We run fairly hard into a fundamental limitation of the Android Gradle
|
||||
// plugin. There are many bugs filed about this, but
|
||||
// https://code.google.com/p/android/issues/detail?id=216978#c6 is a reason one.
|
||||
// The issue is that we need fine-grained control over when to include Gecko's
|
||||
// binary libraries into the GeckoView AAR and the Fennec APK, and that's hard
|
||||
// to achieve. In particular:
|
||||
//
|
||||
// * :app:official* wants :geckoview to not include Gecko binaries (official
|
||||
// * automation build, before package)
|
||||
//
|
||||
// * :geckoview:withLibraries wants :geckoview to include Gecko binaries
|
||||
// * (automation build, after package)
|
||||
//
|
||||
// * non-:app:official* wants :geckoview to include Gecko binaries (local
|
||||
// * build, always after package)
|
||||
//
|
||||
// publishNonDefault (see
|
||||
// http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication)
|
||||
// is intended to address this, but doesn't handle our case. That option always
|
||||
// builds *all* configurations, which fails when the required Gecko binaries
|
||||
// don't exist (automation build, before package). So instead, we make both
|
||||
// :app and :geckoview both know how to include the Gecko binaries, and use a
|
||||
// non-default, non-published :geckoview:withGeckoBinaries configuration to
|
||||
// handle automation's needs. Simple, right?
|
||||
|
||||
// The omnijar inputs are listed as resource directory inputs to a dummy JAR.
|
||||
// That arrangement labels them nicely in IntelliJ. See the comment in the
|
||||
// :omnijar project for more context.
|
||||
evaluationDependsOn(':omnijar')
|
||||
|
||||
task buildOmnijar(type:Exec) {
|
||||
task buildOmnijars(type:Exec) {
|
||||
dependsOn rootProject.generateCodeAndResources
|
||||
|
||||
// See comment in :omnijar project regarding interface mismatches here.
|
||||
inputs.file(project(':omnijar').sourceSets.main.resources.srcDirs).skipWhenEmpty()
|
||||
|
||||
// Produce a single output file.
|
||||
// Produce both the Fennec and the GeckoView omnijars.
|
||||
outputs.file "${topobjdir}/dist/fennec/assets/omni.ja"
|
||||
outputs.file "${topobjdir}/dist/geckoview/assets/omni.ja"
|
||||
|
||||
workingDir "${topobjdir}"
|
||||
|
||||
@ -60,97 +36,85 @@ task buildOmnijar(type:Exec) {
|
||||
}
|
||||
}
|
||||
|
||||
task syncOmnijarFromDistDir(type: Sync) {
|
||||
// :app needs the full Fennec omni.ja, whereas other projects need the GeckoView-specific omni.ja.
|
||||
def omnijar_dir = "app".equals(project.name) ? "fennec" : "geckoview"
|
||||
into("${project.buildDir}/generated/omnijar")
|
||||
from("${topobjdir}/dist/${omnijar_dir}/omni.ja",
|
||||
"${topobjdir}/dist/${omnijar_dir}/assets/omni.ja") {
|
||||
// Throw an exception if we find multiple, potentially conflicting omni.ja files.
|
||||
duplicatesStrategy 'fail'
|
||||
}
|
||||
}
|
||||
|
||||
task checkLibsExistInDistDir {
|
||||
doLast {
|
||||
if (syncLibsFromDistDir.source.empty) {
|
||||
throw new GradleException("Required JNI libraries not found in ${topobjdir}/dist/fennec/lib. Have you built and packaged?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task syncLibsFromDistDir(type: Sync, dependsOn: checkLibsExistInDistDir) {
|
||||
into("${project.buildDir}/generated/jniLibs")
|
||||
from("${topobjdir}/dist/fennec/lib")
|
||||
}
|
||||
|
||||
task checkAssetsExistInDistDir {
|
||||
doLast {
|
||||
if (syncAssetsFromDistDir.source.empty) {
|
||||
throw new GradleException("Required assets not found in ${topobjdir}/dist/fennec/assets. Have you built and packaged?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task syncAssetsFromDistDir(type: Sync, dependsOn: checkAssetsExistInDistDir) {
|
||||
into("${project.buildDir}/generated/assets")
|
||||
from("${topobjdir}/dist/fennec/assets") {
|
||||
exclude 'omni.ja'
|
||||
}
|
||||
}
|
||||
|
||||
ext.configureVariantWithGeckoBinaries = { variant ->
|
||||
// Like 'localPhoton' or 'localOldPhoton'; may be null.
|
||||
def productFlavor = ""
|
||||
def productFlavorNames = variant.productFlavors.collect { it.name.capitalize() }
|
||||
if (!productFlavorNames.isEmpty()) {
|
||||
productFlavor = productFlavorNames.join()
|
||||
// Groovy's `uncapitilize` is not yet available.
|
||||
def c = productFlavor.toCharArray()
|
||||
c[0] = Character.toLowerCase(c[0])
|
||||
productFlavor = new String(c)
|
||||
// :app needs the full Fennec omni.ja, whereas other projects need the
|
||||
// GeckoView-specific omni.ja.
|
||||
def omnijar_dir = "app".equals(project.name) ? "fennec" : "geckoview"
|
||||
def distDir = "${topobjdir}/dist/${omnijar_dir}"
|
||||
|
||||
def syncOmnijarFromDistDir = task("syncOmnijarFromDistDirFor${variant.name.capitalize()}", type: Sync) {
|
||||
doFirst {
|
||||
if (source.empty) {
|
||||
throw new GradleException("Required omnijar not found in ${source.asPath}. Have you built and packaged?")
|
||||
}
|
||||
}
|
||||
|
||||
into("${project.buildDir}/moz.build/src/${variant.name}/omnijar")
|
||||
from("${distDir}/omni.ja",
|
||||
"${distDir}/assets/omni.ja") {
|
||||
// Throw an exception if we find multiple, potentially conflicting omni.ja files.
|
||||
duplicatesStrategy 'fail'
|
||||
}
|
||||
}
|
||||
|
||||
// Like 'debug' or 'release'.
|
||||
def buildType = variant.buildType.name
|
||||
def syncLibsFromDistDir = task("syncLibsFromDistDirFor${variant.name.capitalize()}", type: Sync) {
|
||||
doFirst {
|
||||
if (source.empty) {
|
||||
throw new GradleException("Required JNI libraries not found in ${source.asPath}. Have you built and packaged?")
|
||||
}
|
||||
}
|
||||
|
||||
syncOmnijarFromDistDir.dependsOn buildOmnijar
|
||||
def generateAssetsTask = tasks.findByName("generate${productFlavor.capitalize()}${buildType.capitalize()}Assets")
|
||||
generateAssetsTask.dependsOn syncOmnijarFromDistDir
|
||||
generateAssetsTask.dependsOn syncLibsFromDistDir
|
||||
generateAssetsTask.dependsOn syncAssetsFromDistDir
|
||||
into("${project.buildDir}/moz.build/src/${variant.name}/jniLibs")
|
||||
from("${distDir}/lib")
|
||||
}
|
||||
|
||||
def sourceSet = productFlavor ? "${productFlavor}${buildType.capitalize()}" : buildType
|
||||
android.sourceSets."${sourceSet}".assets.srcDir syncOmnijarFromDistDir.destinationDir
|
||||
android.sourceSets."${sourceSet}".assets.srcDir syncAssetsFromDistDir.destinationDir
|
||||
android.sourceSets."${sourceSet}".jniLibs.srcDir syncLibsFromDistDir.destinationDir
|
||||
def syncAssetsFromDistDir = task("syncAssetsFromDistDirFor${variant.name.capitalize()}", type: Sync) {
|
||||
doFirst {
|
||||
if (source.empty) {
|
||||
throw new GradleException("Required assets not found in ${source.asPath}. Have you built and packaged?")
|
||||
}
|
||||
}
|
||||
|
||||
into("${project.buildDir}/moz.build/src/${variant.name}/assets")
|
||||
from("${distDir}/assets") {
|
||||
exclude 'omni.ja'
|
||||
}
|
||||
}
|
||||
|
||||
// Local (read, not 'official') builds want to reflect developer changes to
|
||||
// the Omnijar sources. To do this, the Gradle build calls out to the
|
||||
// moz.build system, which can be re-entrant. Official builds are driven by
|
||||
// the moz.build system and should never be re-entrant in this way.
|
||||
if (!((variant.productFlavors*.name).contains('official'))) {
|
||||
syncOmnijarFromDistDir.dependsOn buildOmnijars
|
||||
}
|
||||
|
||||
def assetGenTask = tasks.findByName("generate${variant.name.capitalize()}Assets")
|
||||
if ((variant.productFlavors*.name).contains('withGeckoBinaries')) {
|
||||
assetGenTask.dependsOn syncOmnijarFromDistDir
|
||||
assetGenTask.dependsOn syncLibsFromDistDir
|
||||
assetGenTask.dependsOn syncAssetsFromDistDir
|
||||
|
||||
android.sourceSets."${variant.name}".assets.srcDir syncOmnijarFromDistDir.destinationDir
|
||||
android.sourceSets."${variant.name}".assets.srcDir syncAssetsFromDistDir.destinationDir
|
||||
android.sourceSets."${variant.name}".jniLibs.srcDir syncLibsFromDistDir.destinationDir
|
||||
}
|
||||
}
|
||||
|
||||
ext.configureVariantWithJNIWrappers = { variant, module ->
|
||||
def jarTask
|
||||
if (module == 'Generated') {
|
||||
jarTask = tasks["package${variant.name.capitalize()}JarArtifact"]
|
||||
} else {
|
||||
jarTask = tasks["jar${variant.name.capitalize()}Classes"]
|
||||
}
|
||||
|
||||
if (jarTask.outputs.files.size() != 1) {
|
||||
throw new GradleException("Jar task output multiple files other than one single jar")
|
||||
}
|
||||
|
||||
// At configuration time, the classpath of dependencies with internal_impl
|
||||
// JAR files may not be correct. This manifests in
|
||||
ext.configureLibraryVariantWithJNIWrappers = { variant, module ->
|
||||
// Library variants have two essentially independent transform* tasks:
|
||||
//
|
||||
// 'Exception in thread "main" java.lang.NoClassDefFoundError: android/support/v4/app/ActivityCompatApi23$RequestPermissionsRequestCodeValidator'
|
||||
// - ...WithSyncLibJars... is used by assemble* and bundle*
|
||||
// - ...WithPrepareIntermediateJars... is used by consuming applications.
|
||||
//
|
||||
// when running |mach gradle clean app:generateJNI...|. We work around this
|
||||
// by configuring the classpath at evaluation-time, not configuration-time.
|
||||
//
|
||||
// The specific dependency on the `prepareDependencies` task may not be
|
||||
// necessary, but commits like
|
||||
// https://github.com/evant/gradle-retrolambda/commit/15108c65ee43be499a1359d9d4f88b0851d46769
|
||||
// suggest that it is. It certainly doesn't hurt.
|
||||
def prepareDependenciesTask = tasks.getByName("prepare${variant.name.capitalize()}Dependencies")
|
||||
// It's not really possible to insert something immediately _after_
|
||||
// ...WithPrepareIntermediateJars..., so we make the consuming moz.build
|
||||
// system invoke this target directly, and force the
|
||||
// ...WithPrepareIntermediateJars... dependency. The real consumer of the
|
||||
// JNI wrappers is the moz.build system, which always builds geckoview to
|
||||
// consume from Fennec, so that dependency likely adds less to the build time.
|
||||
def jarTask = tasks["transformClassesAndResourcesWithPrepareIntermediateJarsFor${variant.name.capitalize()}"]
|
||||
def output = jarTask.outputs.files.find({ it.absolutePath.contains('/classes.jar') })
|
||||
|
||||
def wrapperTask
|
||||
if (System.env.IS_LANGUAGE_REPACK == '1') {
|
||||
@ -160,7 +124,7 @@ ext.configureVariantWithJNIWrappers = { variant, module ->
|
||||
} else {
|
||||
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}", type: JavaExec) {
|
||||
classpath "${topobjdir}/build/annotationProcessors/annotationProcessors.jar"
|
||||
|
||||
|
||||
// Configure the classpath at evaluation-time, not at
|
||||
// configuration-time: see above comment.
|
||||
doFirst {
|
||||
@ -171,12 +135,11 @@ ext.configureVariantWithJNIWrappers = { variant, module ->
|
||||
|
||||
main = 'org.mozilla.gecko.annotationProcessors.AnnotationProcessor'
|
||||
args module
|
||||
args jarTask.outputs.files.iterator().next()
|
||||
|
||||
args output
|
||||
|
||||
workingDir "${topobjdir}/mobile/android/base"
|
||||
|
||||
|
||||
dependsOn jarTask
|
||||
dependsOn prepareDependenciesTask
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,3 +149,36 @@ ext.configureVariantWithJNIWrappers = { variant, module ->
|
||||
tasks["assemble${variant.name.capitalize()}"].dependsOn wrapperTask
|
||||
}
|
||||
}
|
||||
|
||||
ext.configureApplicationVariantWithJNIWrappers = { variant, module ->
|
||||
def jarTask = tasks["bundleAppClasses${variant.name.capitalize()}"]
|
||||
def output = jarTask.outputs.files.find({ it.absolutePath.contains('/classes.jar') })
|
||||
|
||||
def wrapperTask
|
||||
if (System.env.IS_LANGUAGE_REPACK == '1') {
|
||||
// Single-locale l10n repacks set `IS_LANGUAGE_REPACK=1` and don't
|
||||
// really have a build environment.
|
||||
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}")
|
||||
} else {
|
||||
wrapperTask = task("generateJNIWrappersFor${module}${variant.name.capitalize()}", type: JavaExec) {
|
||||
classpath "${topobjdir}/build/annotationProcessors/annotationProcessors.jar"
|
||||
|
||||
// Configure the classpath at evaluation-time, not at
|
||||
// configuration-time: see above comment.
|
||||
doFirst {
|
||||
classpath variant.javaCompile.classpath
|
||||
// Include android.jar.
|
||||
classpath variant.javaCompile.options.bootClasspath
|
||||
}
|
||||
|
||||
main = 'org.mozilla.gecko.annotationProcessors.AnnotationProcessor'
|
||||
args module
|
||||
args output
|
||||
|
||||
workingDir "${topobjdir}/mobile/android/base"
|
||||
|
||||
// This forces bundling, which isn't usually part of the assemble* process.
|
||||
dependsOn jarTask
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,11 +141,9 @@
|
||||
@BINPATH@/components/dom_range.xpt
|
||||
@BINPATH@/components/dom_security.xpt
|
||||
@BINPATH@/components/dom_sidebar.xpt
|
||||
@BINPATH@/components/dom_mobilemessage.xpt
|
||||
@BINPATH@/components/dom_storage.xpt
|
||||
@BINPATH@/components/dom_system.xpt
|
||||
@BINPATH@/components/dom_traversal.xpt
|
||||
@BINPATH@/components/dom_tv.xpt
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
@BINPATH@/components/dom_webspeechrecognition.xpt
|
||||
#endif
|
||||
@ -259,10 +257,6 @@
|
||||
; JavaScript components
|
||||
@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
|
||||
#ifdef MOZ_ANDROID_GCM
|
||||
@ -402,9 +396,6 @@
|
||||
@BINPATH@/components/PresentationDataChannelSessionTransport.manifest
|
||||
@BINPATH@/components/AndroidCastDeviceProvider.manifest
|
||||
@BINPATH@/components/AndroidCastDeviceProvider.js
|
||||
|
||||
@BINPATH@/components/TVSimulatorService.js
|
||||
@BINPATH@/components/TVSimulatorService.manifest
|
||||
#endif
|
||||
|
||||
@BINPATH@/components/mozIntl.manifest
|
||||
|
@ -414,7 +414,9 @@ class MachCommands(MachCommandBase):
|
||||
# $JAVA_HOME/bin/java into $JAVA_HOME.
|
||||
java_home = os.path.dirname(os.path.dirname(self.substs['JAVA']))
|
||||
|
||||
gradle_flags = shell_split(self.substs.get('GRADLE_FLAGS', ''))
|
||||
gradle_flags = self.substs.get('GRADLE_FLAGS', '') or \
|
||||
os.environ.get('GRADLE_FLAGS', '')
|
||||
gradle_flags = shell_split(gradle_flags)
|
||||
|
||||
# We force the Gradle JVM to run with the UTF-8 encoding, since we
|
||||
# filter strings.xml, which is really UTF-8; the ellipsis character is
|
||||
|
@ -11,9 +11,6 @@ with Files('**'):
|
||||
with Files('branding/**'):
|
||||
BUG_COMPONENT = ('Firefox for Android', 'General')
|
||||
|
||||
with Files('build/**'):
|
||||
BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support')
|
||||
|
||||
with Files('config/**'):
|
||||
BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support')
|
||||
|
||||
|
@ -8,13 +8,19 @@ import android.content.ContentProvider;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserProvider;
|
||||
import org.mozilla.gecko.db.TabsProvider;
|
||||
import org.robolectric.android.controller.ContentProviderController;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -22,17 +28,54 @@ import java.util.ArrayList;
|
||||
* Wrap a ContentProvider, appending &test=1 to all queries.
|
||||
*/
|
||||
public class DelegatingTestContentProvider extends ContentProvider {
|
||||
protected final ContentProvider mTargetProvider;
|
||||
protected ContentProvider mTargetProvider;
|
||||
|
||||
protected static Uri appendUriParam(Uri uri, String param, String value) {
|
||||
return uri.buildUpon().appendQueryParameter(param, value).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and register a new <tt>BrowserProvider</tt> that has test delegation.
|
||||
* <p>
|
||||
* Robolectric doesn't make it easy to parameterize a created
|
||||
* <tt>ContentProvider</tt>, so we modify a built-in helper to do it.
|
||||
* @return delegated <tt>ContentProvider</tt>.
|
||||
*/
|
||||
public static ContentProvider createDelegatingBrowserProvider() {
|
||||
final ContentProviderController<DelegatingTestContentProvider> contentProviderController
|
||||
= ContentProviderController.of(ReflectionHelpers.callConstructor(DelegatingTestContentProvider.class,
|
||||
ReflectionHelpers.ClassParameter.from(ContentProvider.class, new BrowserProvider())));
|
||||
return contentProviderController.create(BrowserContract.AUTHORITY).get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and register a new <tt>TabsProvider</tt> that has test delegation.
|
||||
* <p>
|
||||
* Robolectric doesn't make it easy to parameterize a created
|
||||
* <tt>ContentProvider</tt>, so we modify a built-in helper to do it.
|
||||
* @return delegated <tt>ContentProvider</tt>.
|
||||
*/
|
||||
public static ContentProvider createDelegatingTabsProvider() {
|
||||
final ContentProviderController<DelegatingTestContentProvider> contentProviderController
|
||||
= ContentProviderController.of(ReflectionHelpers.callConstructor(DelegatingTestContentProvider.class,
|
||||
ReflectionHelpers.ClassParameter.from(ContentProvider.class, new TabsProvider())));
|
||||
return contentProviderController.create(BrowserContract.TABS_AUTHORITY).get();
|
||||
}
|
||||
|
||||
public DelegatingTestContentProvider(ContentProvider targetProvider) {
|
||||
super();
|
||||
mTargetProvider = targetProvider;
|
||||
}
|
||||
|
||||
public void attachInfo(Context context, ProviderInfo info) {
|
||||
// With newer Robolectric versions, we must create the target provider
|
||||
// before calling into super. If we don't do this, the target
|
||||
// provider's onCreate() will witness a null getContext(), which the
|
||||
// Android documentation guarantees never happens on device.
|
||||
mTargetProvider.attachInfo(context, null);
|
||||
super.attachInfo(context, info);
|
||||
}
|
||||
|
||||
private Uri appendTestParam(Uri uri) {
|
||||
return appendUriParam(uri, BrowserContract.PARAM_IS_TEST, "1");
|
||||
}
|
||||
@ -88,6 +131,10 @@ public class DelegatingTestContentProvider extends ContentProvider {
|
||||
return mTargetProvider.call(method, arg, extras);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
mTargetProvider.shutdown();
|
||||
}
|
||||
|
||||
public ContentProvider getTargetProvider() {
|
||||
return mTargetProvider;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
@ -17,7 +18,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.TabsProvider;
|
||||
import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
|
||||
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
|
||||
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
|
||||
@ -35,13 +35,11 @@ public class TestTabsProvider {
|
||||
protected Tab testTab2;
|
||||
protected Tab testTab3;
|
||||
|
||||
protected TabsProvider provider;
|
||||
protected ContentProvider provider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
provider = new TabsProvider();
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.TABS_AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
provider = DelegatingTestContentProvider.createDelegatingTabsProvider();
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -13,6 +13,8 @@ import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
|
||||
import org.mozilla.gecko.sync.stage.CompletedStage;
|
||||
import org.mozilla.gecko.sync.stage.GlobalSyncStage;
|
||||
import org.mozilla.gecko.sync.stage.GlobalSyncStage.Stage;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
@ -26,7 +28,7 @@ public class MockGlobalSession extends MockPrefsGlobalSession {
|
||||
|
||||
public MockGlobalSession(SyncConfiguration config, GlobalSessionCallback callback)
|
||||
throws SyncConfigurationException, IllegalArgumentException, IOException, NonObjectJSONException {
|
||||
super(config, callback, null, null);
|
||||
super(config, callback, RuntimeEnvironment.application, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,9 +53,4 @@ public class MockPrefsGlobalSession extends GlobalSession {
|
||||
config.syncKeyBundle = syncKeyBundle;
|
||||
return new MockPrefsGlobalSession(config, callback, context, clientsDelegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
@ -17,12 +18,11 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.background.db.DelegatingTestContentProvider;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -41,8 +41,9 @@ import static org.mozilla.gecko.db.BrowserProviderGeneralTest.INVALID_TIMESTAMP;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.assertVersionsForSelection;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.bookmarksTestSyncUri;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.bookmarksTestUri;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.getBookmarksTestSyncIncrementLocalVersionUri;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.getBookmarkIdFromGuid;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest
|
||||
.getBookmarksTestSyncIncrementLocalVersionUri;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.insertBookmark;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.withDeleted;
|
||||
import static org.mozilla.gecko.db.BrowserProviderGeneralTest.withSync;
|
||||
@ -53,13 +54,11 @@ import static org.mozilla.gecko.db.BrowserProviderGeneralTest.withSync;
|
||||
@RunWith(TestRunner.class)
|
||||
public class BrowserProviderBookmarksTest {
|
||||
private ContentProviderClient bookmarksClient;
|
||||
private BrowserProvider provider;
|
||||
private ContentProvider provider;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
provider = new BrowserProvider();
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
|
||||
ShadowContentResolver contentResolver = new ShadowContentResolver();
|
||||
bookmarksClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.BOOKMARKS_CONTENT_URI);
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Browser;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -41,15 +41,12 @@ public class BrowserProviderGeneralTest {
|
||||
|
||||
private static final long INVALID_ID = -1;
|
||||
|
||||
private BrowserProvider provider;
|
||||
private ContentProvider provider;
|
||||
private ContentProviderClient browserClient;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
provider = new BrowserProvider();
|
||||
provider.onCreate();
|
||||
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
|
||||
ShadowContentResolver contentResolver = new ShadowContentResolver();
|
||||
browserClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.BOOKMARKS_CONTENT_URI);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.net.Uri;
|
||||
@ -14,21 +15,17 @@ import org.mozilla.gecko.background.db.DelegatingTestContentProvider;
|
||||
import org.mozilla.gecko.sync.repositories.android.BrowserContractHelpers;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BrowserProviderHistoryVisitsTestBase {
|
||||
/* package-private */ ShadowContentResolver contentResolver;
|
||||
/* package-private */ ContentProviderClient historyClient;
|
||||
/* package-private */ ContentProviderClient visitsClient;
|
||||
/* package-private */ Uri historyTestUri;
|
||||
/* package-private */ Uri visitsTestUri;
|
||||
/* package-private */ BrowserProvider provider;
|
||||
/* package-private */ ContentProvider provider;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
provider = new BrowserProvider();
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
|
||||
contentResolver = new ShadowContentResolver();
|
||||
historyClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.HISTORY_CONTENT_URI);
|
||||
|
@ -4,6 +4,7 @@
|
||||
package org.mozilla.gecko.db;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
@ -44,15 +45,13 @@ public class LocalBrowserDBTest {
|
||||
private static final String FOLDER_NAME = "folder1";
|
||||
|
||||
private Context context;
|
||||
private BrowserProvider provider;
|
||||
private ContentProvider provider;
|
||||
private ContentProviderClient bookmarkClient;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
context = RuntimeEnvironment.application;
|
||||
provider = new BrowserProvider();
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
|
||||
ShadowContentResolver contentResolver = new ShadowContentResolver();
|
||||
bookmarkClient = contentResolver.acquireContentProviderClient(BrowserContractHelpers.BOOKMARKS_CONTENT_URI);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
package org.mozilla.gecko.fxa.devices;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
@ -21,7 +22,6 @@ import org.mozilla.gecko.background.db.DelegatingTestContentProvider;
|
||||
import org.mozilla.gecko.background.fxa.FxAccountClient;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserProvider;
|
||||
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
|
||||
import org.mozilla.gecko.fxa.login.State;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
@ -119,12 +119,9 @@ public class TestFxAccountDeviceListUpdater {
|
||||
public void testBrowserProvider() {
|
||||
Uri uri = testUri(BrowserContract.RemoteDevices.CONTENT_URI);
|
||||
|
||||
BrowserProvider provider = new BrowserProvider();
|
||||
final ContentProvider provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
Cursor c = null;
|
||||
try {
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
|
||||
final ShadowContentResolver cr = new ShadowContentResolver();
|
||||
ContentProviderClient remoteDevicesClient = cr.acquireContentProviderClient(BrowserContract.RemoteDevices.CONTENT_URI);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
package org.mozilla.gecko.sync.repositories.android;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.net.Uri;
|
||||
@ -16,7 +17,6 @@ import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.background.db.DelegatingTestContentProvider;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.db.BrowserProvider;
|
||||
import org.robolectric.shadows.ShadowContentResolver;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@ -56,11 +56,8 @@ public class VisitsHelperTest {
|
||||
Uri historyTestUri = testUri(BrowserContract.History.CONTENT_URI);
|
||||
Uri visitsTestUri = testUri(BrowserContract.Visits.CONTENT_URI);
|
||||
|
||||
BrowserProvider provider = new BrowserProvider();
|
||||
final ContentProvider provider = DelegatingTestContentProvider.createDelegatingBrowserProvider();
|
||||
try {
|
||||
provider.onCreate();
|
||||
ShadowContentResolver.registerProvider(BrowserContract.AUTHORITY, new DelegatingTestContentProvider(provider));
|
||||
|
||||
final ShadowContentResolver cr = new ShadowContentResolver();
|
||||
ContentProviderClient historyClient = cr.acquireContentProviderClient(BrowserContractHelpers.HISTORY_CONTENT_URI);
|
||||
ContentProviderClient visitsClient = cr.acquireContentProviderClient(BrowserContractHelpers.VISITS_CONTENT_URI);
|
||||
|
12
mobile/android/thirdparty/build.gradle
vendored
12
mobile/android/thirdparty/build.gradle
vendored
@ -4,12 +4,8 @@ apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.compileSdkVersion
|
||||
buildToolsVersion project.ext.buildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
defaultPublishConfig 'release'
|
||||
publishNonDefault true
|
||||
|
||||
targetSdkVersion project.ext.targetSdkVersion
|
||||
minSdkVersion project.ext.minSdkVersion
|
||||
manifestPlaceholders = project.ext.manifestPlaceholders
|
||||
@ -47,11 +43,11 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
if (mozconfig.substs.MOZ_ANDROID_MMA) {
|
||||
compile "com.android.support:appcompat-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
compile "com.android.support:support-annotations:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
compile "com.google.android.gms:play-services-gcm:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.android.support:appcompat-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
|
||||
implementation "com.android.support:support-annotations:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
implementation "com.google.android.gms:play-services-gcm:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,13 +83,6 @@ interface nsINetUtil : nsISupports
|
||||
*/
|
||||
nsIURI toImmutableURI(in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* Create a simple nested URI using the result of
|
||||
* toImmutableURI on the passed-in aURI which may not be null.
|
||||
* Note: The return URI will not have had its spec set yet.
|
||||
*/
|
||||
nsIURI newSimpleNestedURI(in nsIURI aURI);
|
||||
|
||||
/** Escape every character with its %XX-escaped equivalent */
|
||||
const unsigned long ESCAPE_ALL = 0;
|
||||
|
||||
|
@ -1574,19 +1574,6 @@ nsIOService::ToImmutableURI(nsIURI* uri, nsIURI** result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::NewSimpleNestedURI(nsIURI* aURI, nsIURI** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aURI);
|
||||
|
||||
nsCOMPtr<nsIURI> safeURI;
|
||||
nsresult rv = NS_EnsureSafeToReturn(aURI, getter_AddRefs(safeURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_IF_ADDREF(*aResult = new nsSimpleNestedURI(safeURI));
|
||||
return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIOService::SetManageOfflineStatus(bool aManage)
|
||||
{
|
||||
|
@ -2133,7 +2133,7 @@ dnl ========================================================
|
||||
|
||||
case "$MOZ_BUILD_APP" in
|
||||
mobile/android)
|
||||
MOZ_ANDROID_SDK(23, 23, 25.0.3, 26.0.0 26.0.0-dev 25.3.2 25.3.1)
|
||||
MOZ_ANDROID_SDK(23, 23, 26.0.2, 26.0.0 26.0.0-dev 25.3.2 25.3.1)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
platform-tools
|
||||
build-tools;25.0.3
|
||||
build-tools;26.0.2
|
||||
platforms;android-23
|
||||
extras;android;m2repository
|
||||
extras;google;m2repository
|
||||
|
@ -38,13 +38,10 @@ ANDROID_IDE_ADVERTISEMENT = '''
|
||||
ADVERTISEMENT
|
||||
|
||||
You are building Firefox for Android. After your build completes, you can open
|
||||
the top source directory in IntelliJ or Android Studio directly and build using
|
||||
Gradle. See the documentation at
|
||||
the top source directory in Android Studio directly and build using Gradle.
|
||||
See the documentation at
|
||||
|
||||
https://developer.mozilla.org/en-US/docs/Simple_Firefox_for_Android_build
|
||||
|
||||
PLEASE BE AWARE THAT GRADLE AND INTELLIJ/ANDROID STUDIO SUPPORT IS EXPERIMENTAL.
|
||||
You should verify any changes using |mach build|.
|
||||
=============
|
||||
'''.strip()
|
||||
|
||||
|
@ -21,7 +21,7 @@ android-api-16/debug:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -73,7 +73,7 @@ android-x86/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -130,7 +130,7 @@ android-x86-nightly/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -178,7 +178,7 @@ android-api-16/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -230,7 +230,7 @@ android-api-16-nightly/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -283,7 +283,7 @@ android-x86-old-id/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -339,7 +339,7 @@ android-x86-old-id-nightly/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -388,7 +388,7 @@ android-api-16-old-id/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -439,7 +439,7 @@ android-api-16-old-id-nightly/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -488,7 +488,7 @@ android-api-16-gradle/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -534,7 +534,7 @@ android-aarch64/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
@ -586,7 +586,7 @@ android-aarch64-nightly/opt:
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview/maven/
|
||||
type: directory
|
||||
- name: public/build/geckoview_example.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/geckoview_example-withGeckoBinaries.apk
|
||||
path: /builds/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/geckoview_example/outputs/apk/officialWithGeckoBinariesNoMinApi/debug/geckoview_example-official-withGeckoBinaries-noMinApi-debug.apk
|
||||
type: file
|
||||
- name: public/build
|
||||
path: /builds/worker/artifacts/
|
||||
|
@ -5,7 +5,7 @@ set -x -e
|
||||
echo "running as" $(id)
|
||||
|
||||
: WORKSPACE ${WORKSPACE:=/builds/worker/workspace}
|
||||
: GRADLE_VERSION ${GRADLE_VERSION:=3.4.1}
|
||||
: GRADLE_VERSION ${GRADLE_VERSION:=4.1}
|
||||
|
||||
set -v
|
||||
|
||||
|
@ -72,7 +72,8 @@
|
||||
</remoteStorage>
|
||||
<externalConfiguration>
|
||||
<repositoryPolicy>RELEASE</repositoryPolicy>
|
||||
<checksumPolicy>STRICT</checksumPolicy>
|
||||
<!-- Google doesn't publish checksums. Why, Google, why? -->
|
||||
<checksumPolicy>STRICT_IF_EXISTS</checksumPolicy>
|
||||
<fileTypeValidation>true</fileTypeValidation>
|
||||
<downloadRemoteIndex>false</downloadRemoteIndex>
|
||||
<artifactMaxAge>-1</artifactMaxAge>
|
||||
|
@ -2767,13 +2767,8 @@ GeckoDriver.prototype.deleteSession = function() {
|
||||
// frame scripts can be safely reused
|
||||
Preferences.set(CONTENT_LISTENER_PREF, false);
|
||||
|
||||
// clean up state in each frame in each browser
|
||||
for (let win in this.browsers) {
|
||||
let browser = this.browsers[win];
|
||||
browser.knownFrames.forEach(() => {
|
||||
globalMessageManager.broadcastAsyncMessage("Marionette:Deregister");
|
||||
});
|
||||
}
|
||||
globalMessageManager.broadcastAsyncMessage("Marionette:Session:Delete");
|
||||
globalMessageManager.broadcastAsyncMessage("Marionette:Deregister");
|
||||
|
||||
for (let win of this.windows) {
|
||||
if (win.messageManager) {
|
||||
|
@ -46,7 +46,6 @@ Cu.import("chrome://marionette/content/session.js");
|
||||
|
||||
Cu.importGlobalProperties(["URL"]);
|
||||
|
||||
let outerWindowID = null;
|
||||
let curContainer = {frame: content, shadowRoot: null};
|
||||
|
||||
// Listen for click event to indicate one click has happened, so actions
|
||||
@ -447,7 +446,7 @@ const loadListener = {
|
||||
* an ID, we start the listeners. Otherwise, nothing happens.
|
||||
*/
|
||||
function registerSelf() {
|
||||
outerWindowID = winUtil.outerWindowID;
|
||||
let {outerWindowID} = winUtil;
|
||||
logger.debug(`Register listener.js for window ${outerWindowID}`);
|
||||
|
||||
sandboxes.clear();
|
||||
@ -459,10 +458,12 @@ function registerSelf() {
|
||||
action.inputStateMap = new Map();
|
||||
action.inputsToCancel = [];
|
||||
|
||||
// register will have the ID and a boolean describing if this is the
|
||||
// main process or not
|
||||
let register = sendSyncMessage("Marionette:Register", {outerWindowID});
|
||||
if (register[0].outerWindowID === outerWindowID) {
|
||||
let reply = sendSyncMessage("Marionette:Register", {outerWindowID});
|
||||
if (reply.length == 0) {
|
||||
logger.error("No reply from Marionette:Register");
|
||||
}
|
||||
|
||||
if (reply[0].outerWindowID === outerWindowID) {
|
||||
startListeners();
|
||||
sendAsyncMessage("Marionette:ListenersAttached", {outerWindowID});
|
||||
}
|
||||
@ -557,6 +558,7 @@ function startListeners() {
|
||||
addMessageListener("Marionette:reftestWait", reftestWaitFn);
|
||||
addMessageListener("Marionette:releaseActions", releaseActionsFn);
|
||||
addMessageListener("Marionette:sendKeysToElement", sendKeysToElementFn);
|
||||
addMessageListener("Marionette:Session:Delete", deleteSession);
|
||||
addMessageListener("Marionette:singleTap", singleTapFn);
|
||||
addMessageListener("Marionette:switchToFrame", switchToFrame);
|
||||
addMessageListener("Marionette:switchToParentFrame", switchToParentFrame);
|
||||
@ -594,13 +596,16 @@ function deregister() {
|
||||
removeMessageListener("Marionette:refresh", refresh);
|
||||
removeMessageListener("Marionette:releaseActions", releaseActionsFn);
|
||||
removeMessageListener("Marionette:sendKeysToElement", sendKeysToElementFn);
|
||||
removeMessageListener("Marionette:Session:Delete", deleteSession);
|
||||
removeMessageListener("Marionette:singleTap", singleTapFn);
|
||||
removeMessageListener("Marionette:switchToFrame", switchToFrame);
|
||||
removeMessageListener("Marionette:switchToParentFrame", switchToParentFrame);
|
||||
removeMessageListener("Marionette:switchToShadowRoot", switchToShadowRootFn);
|
||||
removeMessageListener("Marionette:takeScreenshot", takeScreenshotFn);
|
||||
removeMessageListener("Marionette:waitForPageLoaded", waitForPageLoaded);
|
||||
}
|
||||
|
||||
function deleteSession() {
|
||||
seenEls.clear();
|
||||
// reset container frame to the top-most frame
|
||||
curContainer = {frame: content, shadowRoot: null};
|
||||
|
@ -57,7 +57,9 @@ toolkit.jar:
|
||||
content/global/TopLevelVideoDocument.js
|
||||
content/global/timepicker.xhtml
|
||||
content/global/treeUtils.js
|
||||
#ifndef MOZ_FENNEC
|
||||
content/global/viewZoomOverlay.js
|
||||
#endif
|
||||
content/global/bindings/autocomplete.xml (widgets/autocomplete.xml)
|
||||
content/global/bindings/browser.xml (widgets/browser.xml)
|
||||
content/global/bindings/button.xml (widgets/button.xml)
|
||||
|
@ -141,6 +141,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
|
||||
'mozgtk_stub',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WAYLAND']:
|
||||
USE_LIBS += [
|
||||
'mozwayland',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_JPROF']:
|
||||
USE_LIBS += [
|
||||
'jprof',
|
||||
|
@ -56,7 +56,7 @@ void WindowSurfaceProvider::Initialize(
|
||||
#ifdef MOZ_WAYLAND
|
||||
void WindowSurfaceProvider::Initialize(nsWindow *aWidget)
|
||||
{
|
||||
MOZ_ASSERT(!aWidget->IsX11Display(),
|
||||
MOZ_ASSERT(aWidget->GetWaylandDisplay(),
|
||||
"We are supposed to have a Wayland display!");
|
||||
|
||||
mWidget = aWidget;
|
||||
|
@ -220,7 +220,10 @@ WaylandDisplayLoopLocked(wl_display* aDisplay,
|
||||
if (gWaylandDisplays[i]->Matches(aDisplay)) {
|
||||
if (gWaylandDisplays[i]->DisplayLoop()) {
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
NewRunnableFunction(&WaylandDisplayLoop, aDisplay), EVENT_LOOP_DELAY);
|
||||
NewRunnableFunction("WaylandDisplayLoop",
|
||||
&WaylandDisplayLoop,
|
||||
aDisplay),
|
||||
EVENT_LOOP_DELAY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -271,6 +274,7 @@ nsWaylandDisplay::GetShm()
|
||||
|
||||
wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue);
|
||||
wl_display_roundtrip_queue(mDisplay, mEventQueue);
|
||||
|
||||
MOZ_RELEASE_ASSERT(mShm, "Wayland registry query failed!");
|
||||
}
|
||||
|
||||
@ -305,8 +309,8 @@ nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay)
|
||||
mEventQueue = nullptr;
|
||||
} else {
|
||||
mEventQueue = wl_display_create_queue(mDisplay);
|
||||
MessageLoop::current()->PostTask(NewRunnableFunction(&WaylandDisplayLoop,
|
||||
mDisplay));
|
||||
MessageLoop::current()->PostTask(NewRunnableFunction(
|
||||
"WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay));
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,7 +581,9 @@ WindowSurfaceWayland::~WindowSurfaceWayland()
|
||||
// in compositor thread. We have to unref/delete WaylandDisplay in compositor
|
||||
// thread then and we can't use MessageLoop::current() here.
|
||||
mDisplayThreadMessageLoop->PostTask(
|
||||
NewRunnableFunction(&WaylandDisplayRelease, mWaylandDisplay->GetDisplay()));
|
||||
NewRunnableFunction("WaylandDisplayRelease",
|
||||
&WaylandDisplayRelease,
|
||||
mWaylandDisplay->GetDisplay()));
|
||||
} else {
|
||||
WaylandDisplayRelease(mWaylandDisplay->GetDisplay());
|
||||
}
|
||||
|
@ -16,6 +16,12 @@ with Files("*WindowSurface*"):
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
|
||||
DIRS += ['mozgtk']
|
||||
|
||||
if CONFIG['MOZ_WAYLAND']:
|
||||
if CONFIG['GLIB_LIBS']:
|
||||
DIRS += ['mozwayland']
|
||||
else:
|
||||
error('We support Wayland on glibc systems only, see Bug 1409707 for reference.')
|
||||
|
||||
EXPORTS += [
|
||||
'mozcontainer.h',
|
||||
'nsGTKToolkit.h',
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <gdk/gdkwayland.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include <atk/atk.h>
|
||||
@ -208,7 +209,12 @@ moz_container_init (MozContainer *container)
|
||||
{
|
||||
GdkDisplay *gdk_display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
|
||||
wl_display* display = gdk_wayland_display_get_wl_display(gdk_display);
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
|
||||
wl_display* display = sGdkWaylandDisplayGetWlDisplay(gdk_display);
|
||||
wl_registry* registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, container);
|
||||
wl_display_dispatch(display);
|
||||
@ -229,6 +235,14 @@ moz_container_init (MozContainer *container)
|
||||
static gboolean
|
||||
moz_container_map_surface(MozContainer *container)
|
||||
{
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlCompositor =
|
||||
(wl_compositor *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_compositor");
|
||||
static auto sGdkWaylandWindowGetWlSurface =
|
||||
(wl_surface *(*)(GdkWindow *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_window_get_wl_surface");
|
||||
|
||||
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
|
||||
if (GDK_IS_X11_DISPLAY(display))
|
||||
return false;
|
||||
@ -238,13 +252,13 @@ moz_container_map_surface(MozContainer *container)
|
||||
|
||||
if (!container->surface) {
|
||||
struct wl_compositor *compositor;
|
||||
compositor = gdk_wayland_display_get_wl_compositor(display);
|
||||
compositor = sGdkWaylandDisplayGetWlCompositor(display);
|
||||
container->surface = wl_compositor_create_surface(compositor);
|
||||
}
|
||||
|
||||
if (!container->subsurface) {
|
||||
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||
wl_surface* gtk_surface = gdk_wayland_window_get_wl_surface(window);
|
||||
wl_surface* gtk_surface = sGdkWaylandWindowGetWlSurface(window);
|
||||
if (!gtk_surface) {
|
||||
// We requested the underlying wl_surface too early when container
|
||||
// is not realized yet. We'll try again before first rendering
|
||||
@ -264,7 +278,7 @@ moz_container_map_surface(MozContainer *container)
|
||||
// Route input to parent wl_surface owned by Gtk+ so we get input
|
||||
// events from Gtk+.
|
||||
GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET (container));
|
||||
wl_compositor* compositor = gdk_wayland_display_get_wl_compositor(display);
|
||||
wl_compositor* compositor = sGdkWaylandDisplayGetWlCompositor(display);
|
||||
wl_region* region = wl_compositor_create_region(compositor);
|
||||
wl_surface_set_input_region(container->surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
13
widget/gtk/mozwayland/moz.build
Normal file
13
widget/gtk/mozwayland/moz.build
Normal file
@ -0,0 +1,13 @@
|
||||
# -*- Mode: python; 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/.
|
||||
|
||||
SOURCES += [
|
||||
'mozwayland.c',
|
||||
]
|
||||
|
||||
SharedLibrary('mozwayland')
|
||||
|
||||
CFLAGS += CONFIG['TK_CFLAGS']
|
273
widget/gtk/mozwayland/mozwayland.c
Normal file
273
widget/gtk/mozwayland/mozwayland.c
Normal file
@ -0,0 +1,273 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* 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 "mozilla/Types.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkwayland.h>
|
||||
|
||||
const struct wl_interface wl_buffer_interface;
|
||||
const struct wl_interface wl_callback_interface;
|
||||
const struct wl_interface wl_data_device_interface;
|
||||
const struct wl_interface wl_data_device_manager_interface;
|
||||
const struct wl_interface wl_keyboard_interface;
|
||||
const struct wl_interface wl_region_interface;
|
||||
const struct wl_interface wl_registry_interface;
|
||||
const struct wl_interface wl_shm_interface;
|
||||
const struct wl_interface wl_shm_pool_interface;
|
||||
const struct wl_interface wl_seat_interface;
|
||||
const struct wl_interface wl_surface_interface;
|
||||
const struct wl_interface wl_subsurface_interface;
|
||||
const struct wl_interface wl_subcompositor_interface;
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_event_queue_destroy(struct wl_event_queue *queue)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode,
|
||||
union wl_argument *args)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_proxy *
|
||||
wl_proxy_create(struct wl_proxy *factory,
|
||||
const struct wl_interface *interface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void *
|
||||
wl_proxy_create_wrapper(void *proxy)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_proxy_wrapper_destroy(void *proxy_wrapper)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_proxy *
|
||||
wl_proxy_marshal_constructor(struct wl_proxy *proxy,
|
||||
uint32_t opcode,
|
||||
const struct wl_interface *interface,
|
||||
...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_proxy *
|
||||
wl_proxy_marshal_constructor_versioned(struct wl_proxy *proxy,
|
||||
uint32_t opcode,
|
||||
const struct wl_interface *interface,
|
||||
uint32_t version,
|
||||
...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_proxy *
|
||||
wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
|
||||
uint32_t opcode, union wl_argument *args,
|
||||
const struct wl_interface *interface)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_proxy *
|
||||
wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy,
|
||||
uint32_t opcode,
|
||||
union wl_argument *args,
|
||||
const struct wl_interface *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_proxy_destroy(struct wl_proxy *proxy)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_proxy_add_listener(struct wl_proxy *proxy,
|
||||
void (**implementation)(void), void *data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT const void *
|
||||
wl_proxy_get_listener(struct wl_proxy *proxy)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_proxy_add_dispatcher(struct wl_proxy *proxy,
|
||||
wl_dispatcher_func_t dispatcher_func,
|
||||
const void * dispatcher_data, void *data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT void *
|
||||
wl_proxy_get_user_data(struct wl_proxy *proxy)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT uint32_t
|
||||
wl_proxy_get_version(struct wl_proxy *proxy)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT uint32_t
|
||||
wl_proxy_get_id(struct wl_proxy *proxy)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT const char *
|
||||
wl_proxy_get_class(struct wl_proxy *proxy)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_display *
|
||||
wl_display_connect(const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_display *
|
||||
wl_display_connect_to_fd(int fd)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_display_disconnect(struct wl_display *display)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_get_fd(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_dispatch(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_dispatch_queue(struct wl_display *display,
|
||||
struct wl_event_queue *queue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_dispatch_queue_pending(struct wl_display *display,
|
||||
struct wl_event_queue *queue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_dispatch_pending(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_get_error(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT uint32_t
|
||||
wl_display_get_protocol_error(struct wl_display *display,
|
||||
const struct wl_interface **interface,
|
||||
uint32_t *id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_flush(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_roundtrip_queue(struct wl_display *display,
|
||||
struct wl_event_queue *queue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_roundtrip(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT struct wl_event_queue *
|
||||
wl_display_create_queue(struct wl_display *display)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_prepare_read_queue(struct wl_display *display,
|
||||
struct wl_event_queue *queue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_prepare_read(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_display_cancel_read(struct wl_display *display)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_EXPORT int
|
||||
wl_display_read_events(struct wl_display *display)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
wl_log_set_handler_client(wl_log_func_t handler)
|
||||
{
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <gdk/gdkprivate.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkx.h>
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPlatformGtk.h"
|
||||
@ -51,6 +52,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeGTK, nsNativeTheme, nsITheme,
|
||||
nsIObserver)
|
||||
@ -1133,7 +1135,11 @@ nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext,
|
||||
gdk_rect, transparency);
|
||||
|
||||
if (!safeState) {
|
||||
gdk_flush();
|
||||
// gdk_flush() call from expose event crashes Gtk+ on Wayland
|
||||
// (Gnome BZ #773307)
|
||||
if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
|
||||
gdk_flush();
|
||||
}
|
||||
gLastGdkError = gdk_error_trap_pop ();
|
||||
|
||||
if (gLastGdkError) {
|
||||
|
@ -4986,7 +4986,7 @@ nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen)
|
||||
LOG(("nsWindow::MakeFullScreen [%p] aFullScreen %d\n",
|
||||
(void *)this, aFullScreen));
|
||||
|
||||
if (!IsFullscreenSupported(mShell)) {
|
||||
if (mIsX11Display && !IsFullscreenSupported(mShell)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
@ -6912,22 +6912,10 @@ nsWindow::RoundsWidgetCoordinatesTo()
|
||||
|
||||
void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData)
|
||||
{
|
||||
#ifdef MOZ_X11
|
||||
#ifdef MOZ_WAYLAND
|
||||
if (!mIsX11Display) {
|
||||
*aInitData = mozilla::widget::GtkCompositorWidgetInitData(
|
||||
(uintptr_t)nullptr,
|
||||
nsCString(nullptr),
|
||||
GetClientSize());
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
*aInitData = mozilla::widget::GtkCompositorWidgetInitData(
|
||||
mXWindow,
|
||||
nsCString(XDisplayString(mXDisplay)),
|
||||
GetClientSize());
|
||||
}
|
||||
#endif
|
||||
*aInitData = mozilla::widget::GtkCompositorWidgetInitData(
|
||||
(mXWindow != X11None) ? mXWindow : (uintptr_t)nullptr,
|
||||
mXDisplay ? nsCString(XDisplayString(mXDisplay)) : nsCString(),
|
||||
GetClientSize());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -6948,9 +6936,14 @@ nsWindow::IsComposited() const
|
||||
wl_display*
|
||||
nsWindow::GetWaylandDisplay()
|
||||
{
|
||||
// Available as of GTK 3.8+
|
||||
static auto sGdkWaylandDisplayGetWlDisplay =
|
||||
(wl_display *(*)(GdkDisplay *))
|
||||
dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
|
||||
|
||||
GdkDisplay* gdkDisplay = gdk_display_get_default();
|
||||
return mIsX11Display ? nullptr :
|
||||
gdk_wayland_display_get_wl_display(gdkDisplay);
|
||||
sGdkWaylandDisplayGetWlDisplay(gdkDisplay);
|
||||
}
|
||||
|
||||
wl_surface*
|
||||
|
@ -89,7 +89,7 @@ DBusRemoteClient::DoSendDBusCommandLine(const char *aProgram, const char *aProfi
|
||||
// D-Bus names can contain only [a-z][A-Z][0-9]_
|
||||
// characters so adjust the profile string properly.
|
||||
nsAutoCString profileName;
|
||||
nsresult rv = mozilla::Base64Encode(nsAutoCString(aProfileName), profileName);
|
||||
nsresult rv = mozilla::Base64Encode(nsAutoCString(aProfile), profileName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
profileName.ReplaceChar("+/=", '_');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user