mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Android life cycle improvements and Gradle integration
This commit is contained in:
parent
350d9c6c47
commit
7a2a90959e
30 changed files with 945 additions and 634 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -24,6 +24,10 @@ Servo.app
|
||||||
# IntelliJ
|
# IntelliJ
|
||||||
.idea
|
.idea
|
||||||
*.iws
|
*.iws
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
#Gradle
|
||||||
|
.gradle
|
||||||
|
|
||||||
# VSCode
|
# VSCode
|
||||||
.vscode
|
.vscode
|
||||||
|
|
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -39,11 +39,10 @@ source = "git+https://github.com/mmatyas/android-rs-injected-glue#1995be2c692d8d
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "angle"
|
name = "angle"
|
||||||
version = "0.1.2"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/angle?branch=servo#99128001400771ee9c8a74dcf54cf6fe11b1e532"
|
source = "git+https://github.com/servo/angle?branch=servo#a1371e8a160128677af863d1d73f150862ba42b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -266,13 +265,6 @@ name = "browserhtml"
|
||||||
version = "0.1.17"
|
version = "0.1.17"
|
||||||
source = "git+https://github.com/browserhtml/browserhtml?branch=crate#7c66ae9a3e29d35230d5b9f16d19a562b1312c87"
|
source = "git+https://github.com/browserhtml/browserhtml?branch=crate#7c66ae9a3e29d35230d5b9f16d19a562b1312c87"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "build-apk"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -2240,7 +2232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "script"
|
name = "script"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)",
|
"angle 0.2.0 (git+https://github.com/servo/angle?branch=servo)",
|
||||||
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"audio-video-metadata 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"audio-video-metadata 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2573,6 +2565,7 @@ dependencies = [
|
||||||
name = "servo_config"
|
name = "servo_config"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"android_injected_glue 0.2.2 (git+https://github.com/mmatyas/android-rs-injected-glue)",
|
||||||
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3324,7 +3317,7 @@ dependencies = [
|
||||||
"checksum alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b21f6ad9c9957eb5d70c3dee16d31c092b3cab339628f821766b05e6833d72b8"
|
"checksum alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b21f6ad9c9957eb5d70c3dee16d31c092b3cab339628f821766b05e6833d72b8"
|
||||||
"checksum android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d8289e9637439939cc92b1995b0972117905be88bc28116c86b64d6e589bcd38"
|
"checksum android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d8289e9637439939cc92b1995b0972117905be88bc28116c86b64d6e589bcd38"
|
||||||
"checksum android_injected_glue 0.2.2 (git+https://github.com/mmatyas/android-rs-injected-glue)" = "<none>"
|
"checksum android_injected_glue 0.2.2 (git+https://github.com/mmatyas/android-rs-injected-glue)" = "<none>"
|
||||||
"checksum angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
|
"checksum angle 0.2.0 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
|
||||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||||
"checksum app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a0c3b5be4ed53affe3e1a162b2e7ef9979bcaac80daa9026e9d7988c41e0e83"
|
"checksum app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a0c3b5be4ed53affe3e1a162b2e7ef9979bcaac80daa9026e9d7988c41e0e83"
|
||||||
|
|
|
@ -3,7 +3,6 @@ members = [
|
||||||
"ports/cef",
|
"ports/cef",
|
||||||
"ports/geckolib",
|
"ports/geckolib",
|
||||||
"ports/servo",
|
"ports/servo",
|
||||||
"support/android/build-apk",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
|
|
@ -27,3 +27,6 @@ env_logger = "0.4"
|
||||||
|
|
||||||
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))'.dependencies]
|
[target.'cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))'.dependencies]
|
||||||
xdg = "2.0"
|
xdg = "2.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
|
android_injected_glue = {git = "https://github.com/mmatyas/android-rs-injected-glue"}
|
||||||
|
|
|
@ -6,8 +6,12 @@
|
||||||
//! For linux based platforms, it uses the XDG base directory spec but provides
|
//! For linux based platforms, it uses the XDG base directory spec but provides
|
||||||
//! similar abstractions for non-linux platforms.
|
//! similar abstractions for non-linux platforms.
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use android_injected_glue;
|
||||||
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
||||||
use std::env;
|
use std::env;
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use std::ffi::CStr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
||||||
use xdg;
|
use xdg;
|
||||||
|
@ -20,8 +24,12 @@ pub fn default_config_dir() -> Option<PathBuf> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn default_config_dir() -> Option<PathBuf> {
|
pub fn default_config_dir() -> Option<PathBuf> {
|
||||||
Some(PathBuf::from("/sdcard/servo"))
|
let dir = unsafe {
|
||||||
|
CStr::from_ptr((*android_injected_glue::get_app().activity).externalDataPath)
|
||||||
|
};
|
||||||
|
Some(PathBuf::from(dir.to_str().unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
||||||
|
@ -32,8 +40,12 @@ pub fn default_data_dir() -> Option<PathBuf> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn default_data_dir() -> Option<PathBuf> {
|
pub fn default_data_dir() -> Option<PathBuf> {
|
||||||
Some(PathBuf::from("/sdcard/servo"))
|
let dir = unsafe {
|
||||||
|
CStr::from_ptr((*android_injected_glue::get_app().activity).internalDataPath)
|
||||||
|
};
|
||||||
|
Some(PathBuf::from(dir.to_str().unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), not(target_os = "android")))]
|
||||||
|
@ -44,8 +56,14 @@ pub fn default_cache_dir() -> Option<PathBuf> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn default_cache_dir() -> Option<PathBuf> {
|
pub fn default_cache_dir() -> Option<PathBuf> {
|
||||||
Some(PathBuf::from("/sdcard/servo"))
|
// TODO: Use JNI to call context.getCacheDir().
|
||||||
|
// There is no equivalent function in NDK/NativeActivity.
|
||||||
|
let dir = unsafe {
|
||||||
|
CStr::from_ptr((*android_injected_glue::get_app().activity).externalDataPath)
|
||||||
|
};
|
||||||
|
Some(PathBuf::from(dir.to_str().unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
extern crate android_injected_glue;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
#[macro_use] extern crate lazy_static;
|
#[macro_use] extern crate lazy_static;
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use android_injected_glue;
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
use std::env;
|
use std::env;
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use std::ffi::CStr;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -21,8 +25,12 @@ pub fn set_resources_path(path: Option<String>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn resources_dir_path() -> io::Result<PathBuf> {
|
pub fn resources_dir_path() -> io::Result<PathBuf> {
|
||||||
Ok(PathBuf::from("/sdcard/servo/"))
|
let dir = unsafe {
|
||||||
|
CStr::from_ptr((*android_injected_glue::get_app().activity).externalDataPath)
|
||||||
|
};
|
||||||
|
Ok(PathBuf::from(dir.to_str().unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
|
|
|
@ -94,7 +94,7 @@ linux-nightly:
|
||||||
android:
|
android:
|
||||||
- ./mach clean-nightlies --keep 3 --force
|
- ./mach clean-nightlies --keep 3 --force
|
||||||
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ./mach build --android --dev
|
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ./mach build --android --dev
|
||||||
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ./mach package --android --dev
|
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ANDROID_SDK=/home/servo/android/sdk/r25.2.3 ./mach package --android --dev
|
||||||
- bash ./etc/ci/lockfile_changed.sh
|
- bash ./etc/ci/lockfile_changed.sh
|
||||||
- bash ./etc/ci/manifest_changed.sh
|
- bash ./etc/ci/manifest_changed.sh
|
||||||
- python ./etc/ci/check_dynamic_symbols.py
|
- python ./etc/ci/check_dynamic_symbols.py
|
||||||
|
@ -102,7 +102,7 @@ android:
|
||||||
android-nightly:
|
android-nightly:
|
||||||
- ./mach clean-nightlies --keep 3 --force
|
- ./mach clean-nightlies --keep 3 --force
|
||||||
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ./mach build --android --release
|
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ./mach build --android --release
|
||||||
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ./mach package --android --release
|
- env SERVO_RUSTC_LLVM_ASSERTIONS=1 ANDROID_SDK=/home/servo/android/sdk/r25.2.3 ./mach package --android --release
|
||||||
- ./etc/ci/upload_nightly.sh android
|
- ./etc/ci/upload_nightly.sh android
|
||||||
|
|
||||||
arm32:
|
arm32:
|
||||||
|
|
|
@ -940,14 +940,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WindowProxy is not implemented for android yet
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
fn create_window_proxy(_: &Window) -> Option<glutin::WindowProxy> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
fn create_window_proxy(window: &Window) -> Option<glutin::WindowProxy> {
|
fn create_window_proxy(window: &Window) -> Option<glutin::WindowProxy> {
|
||||||
match window.kind {
|
match window.kind {
|
||||||
WindowKind::Window(ref window) => {
|
WindowKind::Window(ref window) => {
|
||||||
|
|
|
@ -33,6 +33,7 @@ extern crate sig;
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use servo::Browser;
|
use servo::Browser;
|
||||||
use servo::compositing::windowing::WindowEvent;
|
use servo::compositing::windowing::WindowEvent;
|
||||||
|
use servo::config;
|
||||||
use servo::config::opts::{self, ArgumentParsingResult};
|
use servo::config::opts::{self, ArgumentParsingResult};
|
||||||
use servo::config::servo_version;
|
use servo::config::servo_version;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -219,8 +220,9 @@ fn args() -> Vec<String> {
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
|
|
||||||
const PARAMS_FILE: &'static str = "/sdcard/servo/android_params";
|
let mut params_file = config::basedir::default_config_dir().unwrap();
|
||||||
match File::open(PARAMS_FILE) {
|
params_file.push("android_params");
|
||||||
|
match File::open(params_file.to_str().unwrap()) {
|
||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
let file = BufReader::new(&f);
|
let file = BufReader::new(&f);
|
||||||
|
@ -236,7 +238,7 @@ fn args() -> Vec<String> {
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("Failed to open params file '{}': {}",
|
debug!("Failed to open params file '{}': {}",
|
||||||
PARAMS_FILE,
|
params_file.to_str().unwrap(),
|
||||||
Error::description(&e));
|
Error::description(&e));
|
||||||
vec!["servo".to_owned(), "http://en.wikipedia.org/wiki/Rust".to_owned()]
|
vec!["servo".to_owned(), "http://en.wikipedia.org/wiki/Rust".to_owned()]
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,7 +28,6 @@ from servo.command_base import (
|
||||||
BuildNotFound,
|
BuildNotFound,
|
||||||
cd,
|
cd,
|
||||||
CommandBase,
|
CommandBase,
|
||||||
find_dep_path_newest,
|
|
||||||
is_macosx,
|
is_macosx,
|
||||||
is_windows,
|
is_windows,
|
||||||
get_browserhtml_path,
|
get_browserhtml_path,
|
||||||
|
@ -143,34 +142,12 @@ class PackageCommands(CommandBase):
|
||||||
target_dir = path.dirname(binary_path)
|
target_dir = path.dirname(binary_path)
|
||||||
if android:
|
if android:
|
||||||
if dev:
|
if dev:
|
||||||
env["NDK_DEBUG"] = "1"
|
task_name = "assembleArmDebug"
|
||||||
env["ANT_FLAVOR"] = "debug"
|
|
||||||
dev_flag = "-d"
|
|
||||||
else:
|
else:
|
||||||
env["ANT_FLAVOR"] = "release"
|
task_name = "assembleArmRelease"
|
||||||
dev_flag = ""
|
|
||||||
|
|
||||||
output_apk = "{}.apk".format(binary_path)
|
|
||||||
|
|
||||||
dir_to_apk = path.join(target_dir, "apk")
|
|
||||||
if path.exists(dir_to_apk):
|
|
||||||
print("Cleaning up from previous packaging")
|
|
||||||
delete(dir_to_apk)
|
|
||||||
shutil.copytree(path.join(dir_to_root, "support", "android", "apk"), dir_to_apk)
|
|
||||||
|
|
||||||
blurdroid_path = find_dep_path_newest('blurdroid', binary_path)
|
|
||||||
if blurdroid_path is None:
|
|
||||||
print("Could not find blurdroid package; perhaps you haven't built Servo.")
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
dir_to_libs = path.join(dir_to_apk, "libs")
|
|
||||||
if not path.exists(dir_to_libs):
|
|
||||||
os.makedirs(dir_to_libs)
|
|
||||||
shutil.copy2(blurdroid_path + '/out/blurdroid.jar', dir_to_libs)
|
|
||||||
try:
|
try:
|
||||||
with cd(path.join("support", "android", "build-apk")):
|
with cd(path.join("support", "android", "apk")):
|
||||||
subprocess.check_call(["cargo", "run", "--", dev_flag, "-o", output_apk, "-t", target_dir,
|
subprocess.check_call(["./gradlew", "--no-daemon", task_name], env=env)
|
||||||
"-r", dir_to_root], env=env)
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print("Packaging Android exited with return value %d" % e.returncode)
|
print("Packaging Android exited with return value %d" % e.returncode)
|
||||||
return e.returncode
|
return e.returncode
|
||||||
|
|
|
@ -83,11 +83,12 @@ class PostBuildCommands(CommandBase):
|
||||||
return
|
return
|
||||||
script = [
|
script = [
|
||||||
"am force-stop com.mozilla.servo",
|
"am force-stop com.mozilla.servo",
|
||||||
"echo servo >/sdcard/servo/android_params"
|
"echo servo >/sdcard/Android/data/com.mozilla.servo/files/android_params"
|
||||||
]
|
]
|
||||||
for param in params:
|
for param in params:
|
||||||
script += [
|
script += [
|
||||||
"echo '%s' >>/sdcard/servo/android_params" % param.replace("'", "\\'")
|
"echo '%s' >>/sdcard/Android/data/com.mozilla.servo/files/android_params"
|
||||||
|
% param.replace("'", "\\'")
|
||||||
]
|
]
|
||||||
script += [
|
script += [
|
||||||
"am start com.mozilla.servo/com.mozilla.servo.MainActivity",
|
"am start com.mozilla.servo/com.mozilla.servo.MainActivity",
|
||||||
|
|
|
@ -63,5 +63,7 @@
|
||||||
"session-history.max-length": 20,
|
"session-history.max-length": 20,
|
||||||
"shell.builtin-key-shortcuts.enabled": true,
|
"shell.builtin-key-shortcuts.enabled": true,
|
||||||
"shell.homepage": "https://servo.org",
|
"shell.homepage": "https://servo.org",
|
||||||
|
"shell.keep_screen_on.enabled": false,
|
||||||
|
"shell.native-orientation": "both",
|
||||||
"shell.native-titlebar.enabled": true
|
"shell.native-titlebar.enabled": true
|
||||||
}
|
}
|
||||||
|
|
299
support/android/apk/app/build.gradle
Normal file
299
support/android/apk/app/build.gradle
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
import groovy.io.FileType
|
||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
import java.util.regex.Matcher
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 25
|
||||||
|
buildToolsVersion "25.0.2"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.mozilla.servo"
|
||||||
|
minSdkVersion 18
|
||||||
|
targetSdkVersion 25
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0.0"
|
||||||
|
jackOptions {
|
||||||
|
enabled true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
incremental false
|
||||||
|
}
|
||||||
|
|
||||||
|
splits {
|
||||||
|
density {
|
||||||
|
enable false
|
||||||
|
}
|
||||||
|
abi {
|
||||||
|
enable false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java.srcDirs = ['src/main/java']
|
||||||
|
assets.srcDirs = ['../../../../resources']
|
||||||
|
}
|
||||||
|
armDebug {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(true, 'arm')]
|
||||||
|
}
|
||||||
|
armRelease {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(false, 'arm')]
|
||||||
|
}
|
||||||
|
armv7Debug {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(true, 'armv7')]
|
||||||
|
}
|
||||||
|
armv7Release {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(false, 'armv7')]
|
||||||
|
}
|
||||||
|
arm64Debug {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(true, 'arm64')]
|
||||||
|
}
|
||||||
|
arm64Release {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(false, 'arm64')]
|
||||||
|
}
|
||||||
|
x86Debug {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(true, 'x86')]
|
||||||
|
}
|
||||||
|
x86Release {
|
||||||
|
jniLibs.srcDirs = [getJniLibsPath(false, 'x86')]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
// Default debug and release build types are used as templates
|
||||||
|
debug {
|
||||||
|
jniDebuggable true
|
||||||
|
}
|
||||||
|
|
||||||
|
release {
|
||||||
|
signingConfig signingConfigs.debug // Change this to sign with a production key
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom build types
|
||||||
|
armDebug {
|
||||||
|
initWith(debug)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('arm')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
armRelease {
|
||||||
|
initWith(release)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('arm')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
armv7Debug {
|
||||||
|
initWith(debug)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('armv7')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
armv7Release {
|
||||||
|
initWith(release)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('armv7')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arm64Debug {
|
||||||
|
initWith(debug)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('arm64')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arm64Release {
|
||||||
|
initWith(release)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('arm64')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x86Debug {
|
||||||
|
initWith(debug)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('x86')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x86Release {
|
||||||
|
initWith(release)
|
||||||
|
ndk {
|
||||||
|
abiFilters getNDKAbi('x86')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore default 'debug' and 'release' build types
|
||||||
|
variantFilter { variant ->
|
||||||
|
if(variant.buildType.name.equals('release') || variant.buildType.name.equals('debug')) {
|
||||||
|
variant.setIgnore(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define apk output directory
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
variant.outputs.each { output ->
|
||||||
|
def name = variant.buildType.name
|
||||||
|
output.outputFile = new File(getApkPath(isDebug(name), getArch(name)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call our custom NDK Build task using flavor parameters
|
||||||
|
tasks.all {
|
||||||
|
compileTask ->
|
||||||
|
Pattern pattern = Pattern.compile(/^transformJackWithJackFor([\w\d]+)(Debug|Release)/);
|
||||||
|
Matcher matcher = pattern.matcher(compileTask.name);
|
||||||
|
// You can use this alternative pattern when jackCompiler is disabled
|
||||||
|
// Pattern pattern = Pattern.compile(/^compile([\w\d]+)(Debug|Release)/);
|
||||||
|
// Matcher matcher = pattern.matcher(compileTask.name);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
def taskName = "ndkbuild" + compileTask.name
|
||||||
|
tasks.create(name: taskName, type: Exec) {
|
||||||
|
def debug = compileTask.name.contains("Debug")
|
||||||
|
def arch = matcher.group(1)
|
||||||
|
commandLine getNdkDir(),
|
||||||
|
'APP_BUILD_SCRIPT=../jni/Android.mk',
|
||||||
|
'NDK_APPLICATION_MK=../jni/Application.mk',
|
||||||
|
'NDK_LIBS_OUT=' + getJniLibsPath(debug, arch),
|
||||||
|
'NDK_OUT=' + getTargetDir(debug, arch) + '/apk/obj',
|
||||||
|
'NDK_DEBUG=' + (debug ? '1' : '0'),
|
||||||
|
'APP_ABI=' + getNDKAbi(arch),
|
||||||
|
'SERVO_TARGET_DIR=' + getTargetDir(debug, arch)
|
||||||
|
}
|
||||||
|
|
||||||
|
compileTask.dependsOn taskName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
//Dependency list
|
||||||
|
def deps = [
|
||||||
|
new ServoDependency("blurdroid.jar", "blurdroid")
|
||||||
|
]
|
||||||
|
|
||||||
|
// Iterate all build types and dependencies
|
||||||
|
// For each dependency call the proper compile command and set the correct dependency path
|
||||||
|
def list = ['arm', 'armv7', 'arm64', 'x86']
|
||||||
|
for (arch in list) {
|
||||||
|
for (debug in [true, false]) {
|
||||||
|
String basePath = getTargetDir(debug, arch) + "/build"
|
||||||
|
String cmd = arch + (debug ? "Debug" : "Release") + "Compile"
|
||||||
|
|
||||||
|
for (ServoDependency dep: deps) {
|
||||||
|
String path = findDependencyPath(basePath, dep.fileName, dep.folderFilter)
|
||||||
|
if (path) {
|
||||||
|
"${cmd}" files(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility methods
|
||||||
|
String getTargetDir(boolean debug, String arch) {
|
||||||
|
def basePath = project.rootDir.getParentFile().getParentFile().getParentFile().absolutePath
|
||||||
|
return basePath + '/target/' + getRustTarget(arch) + '/' + (debug ? 'debug' : 'release')
|
||||||
|
}
|
||||||
|
|
||||||
|
String getApkPath(boolean debug, String arch) {
|
||||||
|
return getTargetDir(debug, arch) + '/servo.apk'
|
||||||
|
}
|
||||||
|
|
||||||
|
String getJniLibsPath(boolean debug, String arch) {
|
||||||
|
return getTargetDir(debug, arch) + '/apk/jniLibs'
|
||||||
|
}
|
||||||
|
|
||||||
|
String getArch(String buildType) {
|
||||||
|
return buildType.replaceAll(/(Debug|Release)/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDebug(String buildType) {
|
||||||
|
return buildType.contains("Debug")
|
||||||
|
}
|
||||||
|
|
||||||
|
String getRustTarget(String arch) {
|
||||||
|
switch (arch.toLowerCase()) {
|
||||||
|
case 'arm' : return 'arm-linux-androideabi'
|
||||||
|
case 'armv7' : return 'armv7-linux-androideabi'
|
||||||
|
case 'arm64' : return 'aarch64-linux-android'
|
||||||
|
case 'x86' : return 'x86'
|
||||||
|
default: throw new GradleException("Invalid target architecture " + arch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getNDKAbi(String arch) {
|
||||||
|
switch (arch.toLowerCase()) {
|
||||||
|
case 'arm' : return 'armeabi'
|
||||||
|
case 'armv7' : return 'armeabi-v7a'
|
||||||
|
case 'arm64' : return 'arm64-v8a'
|
||||||
|
case 'x86' : return 'x86'
|
||||||
|
default: throw new GradleException("Invalid target architecture " + arch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getNdkDir() {
|
||||||
|
// Read environment variable used in rust build system
|
||||||
|
String ndkDir = System.getenv('ANDROID_NDK')
|
||||||
|
if (ndkDir == null) {
|
||||||
|
ndkDir = System.getenv('ANDROID_NDK_HOME')
|
||||||
|
}
|
||||||
|
if (ndkDir == null) {
|
||||||
|
// Fallback to ndkDir in local.properties
|
||||||
|
def rootDir = project.rootDir
|
||||||
|
def localProperties = new File(rootDir, "local.properties")
|
||||||
|
Properties properties = new Properties()
|
||||||
|
localProperties.withInputStream { instr ->
|
||||||
|
properties.load(instr)
|
||||||
|
}
|
||||||
|
|
||||||
|
ndkDir = properties.getProperty('ndk.dir')
|
||||||
|
}
|
||||||
|
|
||||||
|
def cmd = Os.isFamily(Os.FAMILY_WINDOWS) ? 'ndk-build.cmd' : 'ndk-build'
|
||||||
|
def ndkbuild = new File(ndkDir + '/' + cmd)
|
||||||
|
if (!ndkbuild.exists()) {
|
||||||
|
throw new GradleException("Please set a valid NDK_HOME environment variable" +
|
||||||
|
"or ndk.dir path in local.properties file");
|
||||||
|
}
|
||||||
|
return ndkbuild.absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
// folderFilter can be used to improve search performance
|
||||||
|
String findDependencyPath(String basePath, String filename, String folderFilter) {
|
||||||
|
File path = new File(basePath);
|
||||||
|
if (!path.exists()) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folderFilter) {
|
||||||
|
path.eachDir {
|
||||||
|
if (it.name.contains(folderFilter)) {
|
||||||
|
path = new File(it.absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def result = ''
|
||||||
|
path.eachFileRecurse(FileType.FILES) {
|
||||||
|
if(it.name.equals(filename)) {
|
||||||
|
result = it.absolutePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServoDependency {
|
||||||
|
public ServoDependency(String fileName, String folderFilter = null) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.folderFilter = folderFilter;
|
||||||
|
}
|
||||||
|
public String fileName;
|
||||||
|
public String folderFilter;
|
||||||
|
}
|
|
@ -1,13 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- BEGIN_INCLUDE(manifest) -->
|
<!-- BEGIN_INCLUDE(manifest) -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto"
|
||||||
package="com.mozilla.servo"
|
package="com.mozilla.servo">
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="1.0">
|
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="18" />
|
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||||
|
|
||||||
<uses-feature android:glEsVersion="0x00020000" android:required="true"></uses-feature>
|
|
||||||
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
|
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
@ -16,9 +12,10 @@
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||||
|
|
||||||
<application android:label="Servo" android:icon="@mipmap/servo">
|
<application android:label="Servo" android:icon="@mipmap/servo">
|
||||||
<activity android:name="com.mozilla.servo.MainActivity"
|
<activity android:name=".MainActivity"
|
||||||
android:label="Servo"
|
android:label="Servo"
|
||||||
android:configChanges="orientation|keyboardHidden">
|
android:configChanges="orientation|keyboardHidden|screenSize">
|
||||||
|
<meta-data android:name="android.app.lib_name" android:value="servo" />
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
|
@ -0,0 +1,299 @@
|
||||||
|
package com.mozilla.servo;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.webkit.URLUtil;
|
||||||
|
|
||||||
|
import com.mozilla.servo.BuildConfig;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.System;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
|
||||||
|
public class MainActivity extends android.app.NativeActivity {
|
||||||
|
private static final String LOGTAG = "Servo";
|
||||||
|
private boolean mFullScreen = false;
|
||||||
|
private static final String PREF_KEY_RESOURCES_SYNC = "res_sync_v";
|
||||||
|
|
||||||
|
static {
|
||||||
|
Log.i(LOGTAG, "Loading the NativeActivity");
|
||||||
|
|
||||||
|
// Libaries should be loaded in reverse dependency order
|
||||||
|
System.loadLibrary("c++_shared");
|
||||||
|
System.loadLibrary("servo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
try {
|
||||||
|
extractAssets();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if (intent != null && intent.getAction().equals(Intent.ACTION_VIEW)) {
|
||||||
|
final String url = intent.getDataString();
|
||||||
|
if (url != null && URLUtil.isValidUrl(url)) {
|
||||||
|
Log.d(LOGTAG, "Received url "+url);
|
||||||
|
set_url(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject preferences = loadPreferences();
|
||||||
|
boolean keepScreenOn = preferences.optBoolean("shell.keep_screen_on.enabled", false);
|
||||||
|
mFullScreen = !preferences.optBoolean("shell.native-titlebar.enabled", false);
|
||||||
|
String orientation = preferences.optString("shell.native-orientation", "both");
|
||||||
|
|
||||||
|
// Handle orientation preference
|
||||||
|
if (orientation.equalsIgnoreCase("portrait")) {
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
}
|
||||||
|
else if (orientation.equalsIgnoreCase("landscape")) {
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Handle keep screen on preference
|
||||||
|
if (keepScreenOn) {
|
||||||
|
keepScreenOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle full screen preference
|
||||||
|
if (mFullScreen) {
|
||||||
|
addFullScreenListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
Log.d(LOGTAG, "onStop");
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
Log.d(LOGTAG, "onPause");
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
Log.d(LOGTAG, "onPause");
|
||||||
|
if (mFullScreen) {
|
||||||
|
setFullScreen();
|
||||||
|
}
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
if (hasFocus && mFullScreen) {
|
||||||
|
setFullScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// keep the device's screen turned on and bright.
|
||||||
|
private void keepScreenOn() {
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dim toolbar and make the view fullscreen
|
||||||
|
private void setFullScreen() {
|
||||||
|
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // Hides navigation bar
|
||||||
|
| View.SYSTEM_UI_FLAG_FULLSCREEN; // Hides status bar
|
||||||
|
if( android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
||||||
|
flags |= getImmersiveFlag();
|
||||||
|
} else {
|
||||||
|
flags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
|
||||||
|
}
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(19)
|
||||||
|
private int getImmersiveFlag() {
|
||||||
|
return View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFullScreenListener() {
|
||||||
|
View decorView = getWindow().getDecorView();
|
||||||
|
decorView.setOnSystemUiVisibilityChangeListener(
|
||||||
|
new View.OnSystemUiVisibilityChangeListener() {
|
||||||
|
public void onSystemUiVisibilityChange(int visibility) {
|
||||||
|
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
||||||
|
setFullScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String loadAsset(String file) {
|
||||||
|
InputStream is = null;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
is = getAssets().open(file);
|
||||||
|
reader = new BufferedReader(new InputStreamReader(is));
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
result.append(line).append('\n');
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(LOGTAG, Log.getStackTraceString(e));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
if (reader != null) {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
if (is != null) {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOGTAG, Log.getStackTraceString(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject loadPreferences() {
|
||||||
|
String json = loadAsset("prefs.json");
|
||||||
|
try {
|
||||||
|
return new JSONObject(json);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(LOGTAG, Log.getStackTraceString(e));
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean needsToExtractAssets(String path) {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
int version = BuildConfig.VERSION_CODE;
|
||||||
|
|
||||||
|
if (!new File(path).exists()) {
|
||||||
|
// Assets folder doesn't exist, resources need to be copied
|
||||||
|
prefs.edit().putInt(PREF_KEY_RESOURCES_SYNC, version).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != prefs.getInt(PREF_KEY_RESOURCES_SYNC, -1)) {
|
||||||
|
// Also force a reextract when the version changes and the resources may be updated
|
||||||
|
// This can be improved by generating a hash or version number of the resources
|
||||||
|
// instead of using version code of the app
|
||||||
|
prefs.edit().putInt(PREF_KEY_RESOURCES_SYNC, version).apply();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getAppDataDir() {
|
||||||
|
File file = getExternalFilesDir(null);
|
||||||
|
return file != null ? file : getFilesDir();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* extracts assets/ in the APK to /sdcard/servo.
|
||||||
|
*/
|
||||||
|
private void extractAssets() throws IOException {
|
||||||
|
String path = getAppDataDir().getAbsolutePath();
|
||||||
|
if (!needsToExtractAssets(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZipFile zipFile = null;
|
||||||
|
File targetDir = new File(path);
|
||||||
|
try {
|
||||||
|
zipFile = new ZipFile(this.getApplicationInfo().sourceDir);
|
||||||
|
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
|
||||||
|
ZipEntry entry = e.nextElement();
|
||||||
|
if (entry.isDirectory() || !entry.getName().startsWith("assets/")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
File targetFile = new File(targetDir, entry.getName().substring("assets/".length()));
|
||||||
|
targetFile.getParentFile().mkdirs();
|
||||||
|
byte[] tempBuffer = new byte[(int)entry.getSize()];
|
||||||
|
BufferedInputStream is = null;
|
||||||
|
FileOutputStream os = null;
|
||||||
|
try {
|
||||||
|
is = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||||
|
os = new FileOutputStream(targetFile);
|
||||||
|
is.read(tempBuffer);
|
||||||
|
os.write(tempBuffer);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (is != null) {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
if (os != null) {
|
||||||
|
os.close();
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(LOGTAG, Log.getStackTraceString(ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (zipFile != null) {
|
||||||
|
zipFile.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOGTAG, Log.getStackTraceString(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void set_url(String url) {
|
||||||
|
try {
|
||||||
|
File file = new File(getAppDataDir() + "/android_params");
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
PrintStream out = new PrintStream(new FileOutputStream(file, false));
|
||||||
|
out.println("# The first line here should be the \"servo\" argument (without quotes) and the");
|
||||||
|
out.println("# last should be the URL to load.");
|
||||||
|
out.println("# Blank lines and those beginning with a '#' are ignored.");
|
||||||
|
out.println("# Each line should be a separate parameter as would be parsed by the shell.");
|
||||||
|
out.println("# For example, \"servo -p 10 http://en.wikipedia.org/wiki/Rust\" would take 4");
|
||||||
|
out.println("# lines (the \"-p\" and \"10\" are separate even though they are related).");
|
||||||
|
out.println("servo");
|
||||||
|
out.println("-w");
|
||||||
|
String absUrl = url.replace("file:///storage/emulated/0/", "/sdcard/");
|
||||||
|
out.println(absUrl);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOGTAG, Log.getStackTraceString(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 509 KiB After Width: | Height: | Size: 509 KiB |
17
support/android/apk/build.gradle
Normal file
17
support/android/apk/build.gradle
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
buildDir = rootDir.absolutePath + "/../../../target/gradle"
|
||||||
|
}
|
|
@ -1,92 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project name="Servo" default="help">
|
|
||||||
|
|
||||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
|
||||||
It contains the path to the SDK. It should *NOT* be checked into
|
|
||||||
Version Control Systems. -->
|
|
||||||
<property file="local.properties" />
|
|
||||||
|
|
||||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
|
||||||
'android' tool to add properties to it.
|
|
||||||
This is the place to change some Ant specific build properties.
|
|
||||||
Here are some properties you may want to change/update:
|
|
||||||
|
|
||||||
source.dir
|
|
||||||
The name of the source directory. Default is 'src'.
|
|
||||||
out.dir
|
|
||||||
The name of the output directory. Default is 'bin'.
|
|
||||||
|
|
||||||
For other overridable properties, look at the beginning of the rules
|
|
||||||
files in the SDK, at tools/ant/build.xml
|
|
||||||
|
|
||||||
Properties related to the SDK location or the project target should
|
|
||||||
be updated using the 'android' tool with the 'update' action.
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property file="ant.properties" />
|
|
||||||
|
|
||||||
<!-- if sdk.dir was not set from one of the property file, then
|
|
||||||
get it from the ANDROID_HOME env var.
|
|
||||||
This must be done before we load project.properties since
|
|
||||||
the proguard config can use sdk.dir -->
|
|
||||||
<property environment="env" />
|
|
||||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
|
||||||
<isset property="env.ANDROID_HOME" />
|
|
||||||
</condition>
|
|
||||||
|
|
||||||
<!-- The project.properties file is created and updated by the 'android'
|
|
||||||
tool, as well as ADT.
|
|
||||||
|
|
||||||
This contains project specific properties such as project target, and library
|
|
||||||
dependencies. Lower level build properties are stored in ant.properties
|
|
||||||
(or in .classpath for Eclipse projects).
|
|
||||||
|
|
||||||
This file is an integral part of the build system for your
|
|
||||||
application and should be checked into Version Control Systems. -->
|
|
||||||
<loadproperties srcFile="project.properties" />
|
|
||||||
|
|
||||||
<!-- quick check on sdk.dir -->
|
|
||||||
<fail
|
|
||||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
|
||||||
unless="sdk.dir"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Import per project custom build rules if present at the root of the project.
|
|
||||||
This is the place to put custom intermediary targets such as:
|
|
||||||
-pre-build
|
|
||||||
-pre-compile
|
|
||||||
-post-compile (This is typically used for code obfuscation.
|
|
||||||
Compiled code location: ${out.classes.absolute.dir}
|
|
||||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
|
||||||
-post-package
|
|
||||||
-post-build
|
|
||||||
-pre-clean
|
|
||||||
-->
|
|
||||||
<import file="custom_rules.xml" optional="true" />
|
|
||||||
|
|
||||||
<!-- Import the actual build file.
|
|
||||||
|
|
||||||
To customize existing targets, there are two options:
|
|
||||||
- Customize only one target:
|
|
||||||
- copy/paste the target into this file, *before* the
|
|
||||||
<import> task.
|
|
||||||
- customize it to your needs.
|
|
||||||
- Customize the whole content of build.xml
|
|
||||||
- copy/paste the content of the rules files (minus the top node)
|
|
||||||
into this file, replacing the <import> task.
|
|
||||||
- customize to your needs.
|
|
||||||
|
|
||||||
***********************
|
|
||||||
****** IMPORTANT ******
|
|
||||||
***********************
|
|
||||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
|
||||||
in order to avoid having your file be overridden by tools such as "android update project"
|
|
||||||
-->
|
|
||||||
<!-- version-tag: 1 -->
|
|
||||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
|
||||||
|
|
||||||
</project>
|
|
BIN
support/android/apk/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
support/android/apk/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
support/android/apk/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
support/android/apk/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
160
support/android/apk/gradlew
vendored
Executable file
160
support/android/apk/gradlew
vendored
Executable file
|
@ -0,0 +1,160 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
support/android/apk/gradlew.bat
vendored
Normal file
90
support/android/apk/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
|
@ -12,11 +12,11 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
|
MY_LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_PATH:= $(SERVO_TARGET_DIR)
|
||||||
LOCAL_MODULE := servo
|
LOCAL_MODULE := servo
|
||||||
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmain.so
|
LOCAL_SRC_FILES := libservo.so
|
||||||
include $(PREBUILT_SHARED_LIBRARY)
|
include $(PREBUILT_SHARED_LIBRARY)
|
||||||
|
|
||||||
# $(call import-module)
|
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
APP_ABI := armeabi
|
NDK_TOOLCHAIN_VERSION := 4.9
|
||||||
APP_PLATFORM := $(ANDROID_PLATFORM)
|
APP_MODULES := c++_shared servo
|
||||||
|
APP_PLATFORM := android-18
|
||||||
|
APP_STL:= c++_shared
|
||||||
|
|
1
support/android/apk/settings.gradle
Normal file
1
support/android/apk/settings.gradle
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include ':app'
|
|
@ -1,118 +0,0 @@
|
||||||
package com.mozilla.servo;
|
|
||||||
import android.app.NativeActivity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.lang.System;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
|
|
||||||
public class MainActivity extends android.app.NativeActivity {
|
|
||||||
private static final String LOGTAG="ServoWrapper";
|
|
||||||
static {
|
|
||||||
Log.i(LOGTAG, "Loading the NativeActivity");
|
|
||||||
// libmain.so contains all of Servo native code with the injected glue.
|
|
||||||
System.loadLibrary("main");
|
|
||||||
Log.i(LOGTAG, "libmain.so loaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void set_url(String url) {
|
|
||||||
try {
|
|
||||||
PrintStream out = new PrintStream(new FileOutputStream("/sdcard/servo/android_params"));
|
|
||||||
out.println("# The first line here should be the \"servo\" argument (without quotes) and the");
|
|
||||||
out.println("# last should be the URL to load.");
|
|
||||||
out.println("# Blank lines and those beginning with a '#' are ignored.");
|
|
||||||
out.println("# Each line should be a separate parameter as would be parsed by the shell.");
|
|
||||||
out.println("# For example, \"servo -p 10 http://en.wikipedia.org/wiki/Rust\" would take 4");
|
|
||||||
out.println("# lines (the \"-p\" and \"10\" are separate even though they are related).");
|
|
||||||
out.println("servo");
|
|
||||||
out.println("-w");
|
|
||||||
String absUrl = url.replace("file:///storage/emulated/0/", "/sdcard/");
|
|
||||||
out.println(absUrl);
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
if (needsToExtractAssets()) {
|
|
||||||
try {
|
|
||||||
extractAssets();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
final Intent intent = getIntent();
|
|
||||||
if (intent.getAction().equals(Intent.ACTION_VIEW)) {
|
|
||||||
final String url = intent.getDataString();
|
|
||||||
Log.d(LOGTAG, "Received url "+url);
|
|
||||||
set_url(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop(); // Always call the superclass method first
|
|
||||||
|
|
||||||
Log.d(LOGTAG, "got onStop; finishing servo activity");
|
|
||||||
finish();
|
|
||||||
|
|
||||||
// Glutin and the Java wrapper libraries that we use currently do not support restoring
|
|
||||||
// Servo after Android has sent it to the background, as the resources were reclaimed.
|
|
||||||
// Until we either address that in glutin or move to a library that supports recreating
|
|
||||||
// the native resources after being restored, we just forcibly shut Servo down when it
|
|
||||||
// is sent to the background.
|
|
||||||
int pid = android.os.Process.myPid();
|
|
||||||
android.os.Process.killProcess(pid);
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean needsToExtractAssets() {
|
|
||||||
// todo: also force a reextract when the resources are updated.
|
|
||||||
return !(new File("/sdcard/servo").exists());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* extracts assets/ in the APK to /sdcard/servo.
|
|
||||||
*/
|
|
||||||
private void extractAssets() throws IOException {
|
|
||||||
ZipFile zipFile = null;
|
|
||||||
File targetDir = new File("/sdcard/servo");
|
|
||||||
try {
|
|
||||||
zipFile = new ZipFile(this.getApplicationInfo().sourceDir);
|
|
||||||
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
|
|
||||||
ZipEntry entry = e.nextElement();
|
|
||||||
if (entry.isDirectory() || !entry.getName().startsWith("assets/")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
File targetFile = new File(targetDir, entry.getName().substring("assets/".length()));
|
|
||||||
targetFile.getParentFile().mkdirs();
|
|
||||||
byte[] tempBuffer = new byte[(int)entry.getSize()];
|
|
||||||
BufferedInputStream is = null;
|
|
||||||
FileOutputStream os = null;
|
|
||||||
try {
|
|
||||||
is = new BufferedInputStream(zipFile.getInputStream(entry));
|
|
||||||
os = new FileOutputStream(targetFile);
|
|
||||||
is.read(tempBuffer);
|
|
||||||
os.write(tempBuffer);
|
|
||||||
} finally {
|
|
||||||
if (is != null) is.close();
|
|
||||||
if (os != null) os.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (zipFile != null) zipFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
35
support/android/build-apk/Cargo.lock
generated
35
support/android/build-apk/Cargo.lock
generated
|
@ -1,35 +0,0 @@
|
||||||
[root]
|
|
||||||
name = "build-apk"
|
|
||||||
version = "0.0.1"
|
|
||||||
dependencies = [
|
|
||||||
"walkdir 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "kernel32-sys"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "walkdir"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-build"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
[package]
|
|
||||||
|
|
||||||
name = "build-apk"
|
|
||||||
version = "0.0.1"
|
|
||||||
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>", "The Servo Project Developers"]
|
|
||||||
license = "MPL-2.0"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "build-apk"
|
|
||||||
path = "src/main.rs"
|
|
||||||
test = false
|
|
||||||
doc = false
|
|
||||||
bench = false
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
walkdir = "1.0"
|
|
|
@ -1,299 +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/. */
|
|
||||||
|
|
||||||
extern crate walkdir;
|
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
use std::fs::DirBuilder;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::process;
|
|
||||||
use std::process::{Command, Stdio};
|
|
||||||
use walkdir::WalkDir;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let (args, passthrough) = parse_arguments();
|
|
||||||
|
|
||||||
// Find all the native shared libraries that exist in the target directory.
|
|
||||||
let mut native_shared_libs = find_native_libs(&args);
|
|
||||||
|
|
||||||
// Get the SDK path from the ANDROID_HOME env.
|
|
||||||
let sdk_path = env::var("ANDROID_HOME").ok().expect("Please set the ANDROID_HOME environment variable");
|
|
||||||
let sdk_path = Path::new(&sdk_path);
|
|
||||||
|
|
||||||
// Get the NDK path from NDK_HOME env.
|
|
||||||
let ndk_path = env::var("NDK_HOME").ok().expect("Please set the NDK_HOME environment variable");
|
|
||||||
let ndk_path = Path::new(&ndk_path);
|
|
||||||
|
|
||||||
// Get the target android platform from ANDROID_PLATFORM env. Expecting "android-{version}"
|
|
||||||
let android_platform = env::var("ANDROID_PLATFORM")
|
|
||||||
.ok()
|
|
||||||
.expect("Please set the ANDROID_PLATFORM environment variable");
|
|
||||||
|
|
||||||
// Add the C++ runtime .so
|
|
||||||
{
|
|
||||||
let libcpp_base_path = ndk_path.join("sources").join("cxx-stl").join("llvm-libc++").join("libs");
|
|
||||||
let libcpp_filename = "libc++_shared.so";
|
|
||||||
let libcpp_path = libcpp_base_path.join("armeabi").join(libcpp_filename);
|
|
||||||
native_shared_libs.insert(libcpp_filename.to_string(), libcpp_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the standalone NDK path from NDK_STANDALONE env.
|
|
||||||
// let standalone_path = env::var("NDK_STANDALONE").ok().unwrap_or("/opt/ndk_standalone".to_string());
|
|
||||||
// let standalone_path = Path::new(&standalone_path);
|
|
||||||
|
|
||||||
let debug = passthrough.contains(&"-d".to_string());
|
|
||||||
|
|
||||||
// Set the build directory that will contain all the necessary files to create the apk
|
|
||||||
let directory = args.target_path.join("apk");
|
|
||||||
let resdir = args.root_path.join("resources/");
|
|
||||||
|
|
||||||
// executing ndk-build
|
|
||||||
env::set_var("V", "1");
|
|
||||||
if debug {
|
|
||||||
env::set_var("NDK_DEBUG", "1");
|
|
||||||
env::set_var("APP_OPTIM", "0");
|
|
||||||
} else {
|
|
||||||
// Overrides android:debuggable propery in the .xml file.
|
|
||||||
env::set_var("APP_OPTIM", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy libservo.so into the jni folder for inclusion in the build
|
|
||||||
// TODO: pass/detect target architecture
|
|
||||||
{
|
|
||||||
let source = &args.target_path.join("libservo.so");
|
|
||||||
let target_dir = &directory.join("jni").join("armeabi");
|
|
||||||
let _ = DirBuilder::new().recursive(true).create(target_dir);
|
|
||||||
let target = target_dir.join("libmain.so");
|
|
||||||
println!("Copying the file {:?} to {:?}", source, target);
|
|
||||||
fs::copy(source, target).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let ndkcmd = Command::new(ndk_path.join("ndk-build"))
|
|
||||||
.arg("-B")
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if ndkcmd.is_err() || ndkcmd.unwrap().code().unwrap() != 0 {
|
|
||||||
println!("Error while executing program `ndk-build`, or missing program.");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the additional native libs into the libs directory.
|
|
||||||
for (name, path) in native_shared_libs.iter() {
|
|
||||||
let target = &directory.join("libs").join("armeabi").join(name);
|
|
||||||
println!("Copying the file {:?} to {:?}", name, target);
|
|
||||||
fs::copy(path, target).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy over the resources
|
|
||||||
let cpcmd = Command::new("cp")
|
|
||||||
.arg("-R")
|
|
||||||
.arg(&resdir)
|
|
||||||
.arg(&directory.join("assets"))
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if cpcmd.is_err() || cpcmd.unwrap().code().unwrap() != 0 {
|
|
||||||
println!("Error while copying files from the resources dir to the assets dir");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the project
|
|
||||||
let androidcmd = Command::new(sdk_path.join("tools").join("android"))
|
|
||||||
.arg("update")
|
|
||||||
.arg("project")
|
|
||||||
.arg("--name")
|
|
||||||
.arg("Servo")
|
|
||||||
.arg("--target")
|
|
||||||
.arg(&android_platform)
|
|
||||||
.arg("--path")
|
|
||||||
.arg(".")
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if androidcmd.is_err() || androidcmd.unwrap().code().unwrap() != 0 {
|
|
||||||
println!("Error while updating the project with the android command");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the APK
|
|
||||||
let mut antcmd = Command::new("ant");
|
|
||||||
if debug {
|
|
||||||
antcmd.arg("debug");
|
|
||||||
} else {
|
|
||||||
antcmd.arg("release");
|
|
||||||
}
|
|
||||||
let antresult = antcmd.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if antresult.is_err() || antresult.unwrap().code().unwrap() != 0 {
|
|
||||||
println!("Error while executing program `ant`, or missing program.");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copying apk file to the requested output
|
|
||||||
// Release builds also need to be signed. For now, we use a simple debug
|
|
||||||
// signing key.
|
|
||||||
if debug {
|
|
||||||
fs::copy(&directory.join("bin").join("Servo-debug.apk"), &args.output).unwrap();
|
|
||||||
} else {
|
|
||||||
let keystore_dir = env::home_dir().expect("Please have a home directory");
|
|
||||||
let keystore_dir = Path::new(&keystore_dir).join(".keystore");
|
|
||||||
let keytoolcmd = Command::new("keytool")
|
|
||||||
.arg("-list")
|
|
||||||
.arg("-storepass")
|
|
||||||
.arg("android")
|
|
||||||
.arg("-alias")
|
|
||||||
.arg("androiddebugkey")
|
|
||||||
.arg("-keystore")
|
|
||||||
.arg(&keystore_dir)
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if keytoolcmd.is_err() || keytoolcmd.unwrap().code().unwrap() != 0 {
|
|
||||||
let keytoolcreatecmd = Command::new("keytool")
|
|
||||||
.arg("-genkeypair")
|
|
||||||
.arg("-keystore")
|
|
||||||
.arg(&keystore_dir)
|
|
||||||
.arg("-storepass")
|
|
||||||
.arg("android")
|
|
||||||
.arg("-alias")
|
|
||||||
.arg("androiddebugkey")
|
|
||||||
.arg("-keypass")
|
|
||||||
.arg("android")
|
|
||||||
.arg("-dname")
|
|
||||||
.arg("CN=Android Debug,O=Android,C=US")
|
|
||||||
.arg("-keyalg")
|
|
||||||
.arg("RSA")
|
|
||||||
.arg("-validity")
|
|
||||||
.arg("365")
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if keytoolcreatecmd.is_err() || keytoolcreatecmd.unwrap().code().unwrap() != 0 {
|
|
||||||
println!("Error while using `keytool` to create the debug keystore.");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let jarsigncmd = Command::new("jarsigner")
|
|
||||||
.arg("-digestalg")
|
|
||||||
.arg("SHA1")
|
|
||||||
.arg("-sigalg")
|
|
||||||
.arg("MD5withRSA")
|
|
||||||
.arg("-storepass")
|
|
||||||
.arg("android")
|
|
||||||
.arg("-keystore")
|
|
||||||
.arg(&keystore_dir)
|
|
||||||
.arg(&directory.join("bin").join("Servo-release-unsigned.apk"))
|
|
||||||
.arg("androiddebugkey")
|
|
||||||
.stdout(Stdio::inherit())
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.current_dir(directory.clone())
|
|
||||||
.status();
|
|
||||||
if jarsigncmd.is_err() || jarsigncmd.unwrap().code().unwrap() != 0 {
|
|
||||||
println!("Error while using `jarsign` to sign the APK.");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::copy(&directory.join("bin").join("Servo-release-unsigned.apk"),
|
|
||||||
&args.output)
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Args {
|
|
||||||
output: PathBuf,
|
|
||||||
root_path: PathBuf,
|
|
||||||
target_path: PathBuf,
|
|
||||||
shared_libraries: HashSet<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_arguments() -> (Args, Vec<String>) {
|
|
||||||
let mut result_output = None;
|
|
||||||
let mut result_root_path = None;
|
|
||||||
let mut result_target_path = None;
|
|
||||||
let mut result_shared_libraries = HashSet::new();
|
|
||||||
let mut result_passthrough = Vec::new();
|
|
||||||
|
|
||||||
let args = env::args();
|
|
||||||
let mut args = args.skip(1);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let arg = match args.next() {
|
|
||||||
None => {
|
|
||||||
return (Args {
|
|
||||||
output: result_output.expect("Could not find -o argument"),
|
|
||||||
root_path: result_root_path.expect("Could not find -r enlistment root argument"),
|
|
||||||
target_path: result_target_path.expect("Could not find -t target path argument"),
|
|
||||||
shared_libraries: result_shared_libraries,
|
|
||||||
},
|
|
||||||
result_passthrough)
|
|
||||||
},
|
|
||||||
Some(arg) => arg,
|
|
||||||
};
|
|
||||||
|
|
||||||
match &*arg {
|
|
||||||
"-o" => {
|
|
||||||
result_output = Some(PathBuf::from(args.next().expect("-o must be followed by the output name")));
|
|
||||||
},
|
|
||||||
"-r" => {
|
|
||||||
result_root_path = Some(PathBuf::from(args.next()
|
|
||||||
.expect("-r must be followed by the enlistment root directory")));
|
|
||||||
},
|
|
||||||
"-t" => {
|
|
||||||
result_target_path = Some(PathBuf::from(args.next()
|
|
||||||
.expect("-t must be followed by the target output directory")));
|
|
||||||
},
|
|
||||||
"-l" => {
|
|
||||||
let name = args.next().expect("-l must be followed by a library name");
|
|
||||||
result_shared_libraries.insert(vec!["lib", &name, ".so"].concat());
|
|
||||||
|
|
||||||
// Also pass these through.
|
|
||||||
result_passthrough.push(arg);
|
|
||||||
result_passthrough.push(name);
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
if arg.starts_with("-l") {
|
|
||||||
result_shared_libraries.insert(vec!["lib", &arg[2..], ".so"].concat());
|
|
||||||
}
|
|
||||||
result_passthrough.push(arg)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_native_libs(args: &Args) -> HashMap<String, PathBuf> {
|
|
||||||
let mut native_shared_libs: HashMap<String, PathBuf> = HashMap::new();
|
|
||||||
|
|
||||||
// Add requested .so files
|
|
||||||
for dir_entry in WalkDir::new(&args.target_path) {
|
|
||||||
let dir_entry = dir_entry.unwrap();
|
|
||||||
let path = dir_entry.path();
|
|
||||||
|
|
||||||
match (path.file_name(), path.extension()) {
|
|
||||||
(Some(file_name), Some(extension)) => {
|
|
||||||
let file_name = file_name.to_str().unwrap();
|
|
||||||
|
|
||||||
if file_name.starts_with("lib") && extension == "so" && args.shared_libraries.contains(file_name) {
|
|
||||||
println!("Adding the file {:?}", file_name);
|
|
||||||
native_shared_libs.insert(file_name.to_string(), path.to_path_buf().clone());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
native_shared_libs
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue