mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Preliminary Android build support (#31086)
* Android build * Fixes * More fixes - Still failing in the linking step * More work on getting linking working Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * android: use mozjs with ndk r25c. loads servo.org more android build fixes. * fix ./mach run for android and make it follow logs Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * add experimental logic for compositor pause/resume Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * pass DPI from android to simpleservo Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * ci: add android workflow Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * switch to ANDROID_SDK_ROOT and ANDROID_NDK_ROOT vars Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * upgrade gradle to 4.10.1 Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * upgrade to gradle 5.1.1 Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * upgrade to gradle 8 and agp 8 Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * make compositing work again with external present Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * android: improve mach support for non-NixOS and CI Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * fix sampler compilation bug introduced in #30490 Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * ci: add android build to main workflow Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * gradle: set MinSdk = targetSdk = 30 NDK requires we compile against the minSdk API level which is 30 in our case. Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * add instructions for android in README.md Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * apk: move servosurface to servoview Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * apk: uncomment the mediasession callbacks on MainActivity Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * apk: fix crash on MainAtivity.onDestroy Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * apk: drop VR, arm 5 and unused code This commit drops: * support for google, oculusvr * support for arm5 architecture and also removes * fakeld scripts * unused java code Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * cleanup shell.nix Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * android: add FIXMEs for gstreamer code Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * apk: remove commented code and debug logs Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * cleanup ServoView.java Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * mach: comment call to download gstreamer deps for android Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * disable bluetooth for jniapi as blurdroid is broken Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * fixup! README.md * fixup! remove change in Cargo.toml * fixup! move shell variables together * fixup! cleanup jniapi/Cargo.toml comments * delete commented gstreamer related android code Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * remove unused config variable in servbuild Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * android: more cleanup Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * force no_static_freetype only for android * use actions to manage sdk, ndk and java Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * rename embedder event names to be more clear. Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * link to startup crash issue Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * fix lint issues Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * upgrade env_logger to 0.10 with duplicate exception libservo and android_logger can use env_logger 0.10 but quickcheck is still stuck on 0.8 and has not seen any activity in the last 2 years. This commit adds a duplicate exception until the quickcheck dependency can be upgraded (or replaced) Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * android: fix comments Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * disable jemalloc on android Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * fixup! replace linux with android in cfg --------- Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
8e6bdb69b1
commit
d7de206dbd
58 changed files with 923 additions and 1382 deletions
|
@ -9,9 +9,12 @@ publish = false
|
|||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
[target.'cfg(not(any(windows, target_os = "android")))'.dependencies]
|
||||
jemallocator = { workspace = true }
|
||||
jemalloc-sys = { workspace = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { workspace = true, features = ["heapapi"] }
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
libc = { workspace = true }
|
||||
|
|
|
@ -9,7 +9,7 @@ static ALLOC: Allocator = Allocator;
|
|||
|
||||
pub use crate::platform::*;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(any(windows, target_os = "android")))]
|
||||
mod platform {
|
||||
use std::os::raw::c_void;
|
||||
|
||||
|
@ -28,6 +28,21 @@ mod platform {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
mod platform {
|
||||
pub use std::alloc::System as Allocator;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
/// Get the size of a heap block.
|
||||
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
|
||||
libc::malloc_usable_size(ptr)
|
||||
}
|
||||
|
||||
pub mod libc_compat {
|
||||
pub use libc::{free, malloc, realloc};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
mod platform {
|
||||
pub use std::alloc::System as Allocator;
|
||||
|
|
|
@ -100,9 +100,9 @@ impl BackgroundHangMonitorRegister for HangMonitorRegister {
|
|||
not(any(target_arch = "arm", target_arch = "aarch64"))
|
||||
))]
|
||||
let sampler = crate::sampler_linux::LinuxSampler::new();
|
||||
#[cfg(all(
|
||||
any(target_os = "android", target_os = "linux"),
|
||||
any(target_arch = "arm", target_arch = "aarch64")
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
all(target_os = "linux", any(target_arch = "arm", target_arch = "aarch64"))
|
||||
))]
|
||||
let sampler = crate::sampler::DummySampler::new();
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ servo_rand = { path = "../rand" }
|
|||
uuid = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["bluetooth-test"]
|
||||
native-bluetooth = ["blurz", "blurdroid", "blurmac", "bluetooth-test"]
|
||||
bluetooth-test = ["blurmock"]
|
||||
|
||||
|
|
|
@ -501,6 +501,33 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.shutdown_state = ShutdownState::FinishedShuttingDown;
|
||||
}
|
||||
|
||||
/// The underlying native surface can be lost during servo's lifetime.
|
||||
/// On Android, for example, this happens when the app is sent to background.
|
||||
/// We need to unbind the surface so that we don't try to use it again.
|
||||
pub fn invalidate_native_surface(&mut self) {
|
||||
debug!("Invalidating native surface in compositor");
|
||||
if let Err(e) = self.webrender_surfman.unbind_native_surface_from_context() {
|
||||
warn!("Unbinding native surface from context failed ({:?})", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// On Android, this function will be called when the app moves to foreground
|
||||
/// and the system creates a new native surface that needs to bound to the current
|
||||
/// context.
|
||||
#[allow(unsafe_code)]
|
||||
pub fn replace_native_surface(&mut self, native_widget: *mut c_void, coords: DeviceIntSize) {
|
||||
debug!("Replacing native surface in compositor: {native_widget:?}");
|
||||
let connection = self.webrender_surfman.connection();
|
||||
let native_widget =
|
||||
unsafe { connection.create_native_widget_from_ptr(native_widget, coords.to_untyped()) };
|
||||
if let Err(e) = self
|
||||
.webrender_surfman
|
||||
.bind_native_surface_to_context(native_widget)
|
||||
{
|
||||
warn!("Binding native surface to context failed ({:?})", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_browser_message(&mut self, msg: CompositorMsg) -> bool {
|
||||
match (msg, self.shutdown_state) {
|
||||
(_, ShutdownState::FinishedShuttingDown) => {
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::time::Duration;
|
|||
use embedder_traits::{EmbedderProxy, EventLoopWaker};
|
||||
use euclid::Scale;
|
||||
use keyboard_types::KeyboardEvent;
|
||||
use libc::c_void;
|
||||
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId, TraversalDirection};
|
||||
use script_traits::{MediaSessionActionType, MouseButton, TouchEventType, TouchId, WheelDelta};
|
||||
use servo_geometry::DeviceIndependentPixel;
|
||||
|
@ -105,6 +106,14 @@ pub enum EmbedderEvent {
|
|||
ChangeBrowserVisibility(TopLevelBrowsingContextId, bool),
|
||||
/// Virtual keyboard was dismissed
|
||||
IMEDismissed,
|
||||
/// Sent on platforms like Android where the native widget surface can be
|
||||
/// automatically destroyed by the system, for example when the app
|
||||
/// is sent to background.
|
||||
InvalidateNativeSurface,
|
||||
/// Sent on platforms like Android where system recreates a new surface for
|
||||
/// the native widget when it is brough back to foreground. This event
|
||||
/// carries the pointer to the native widget and its new size.
|
||||
ReplaceNativeSurface(*mut c_void, DeviceIntSize),
|
||||
}
|
||||
|
||||
impl Debug for EmbedderEvent {
|
||||
|
@ -139,6 +148,8 @@ impl Debug for EmbedderEvent {
|
|||
EmbedderEvent::ChangeBrowserVisibility(..) => write!(f, "ChangeBrowserVisibility"),
|
||||
EmbedderEvent::IMEDismissed => write!(f, "IMEDismissed"),
|
||||
EmbedderEvent::ClearCache => write!(f, "ClearCache"),
|
||||
EmbedderEvent::InvalidateNativeSurface => write!(f, "InvalidateNativeSurface"),
|
||||
EmbedderEvent::ReplaceNativeSurface(..) => write!(f, "ReplaceNativeSurface"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
|
||||
use std::path::Path;
|
||||
|
||||
use log::warn;
|
||||
use ucd::{Codepoint, UnicodeBlock};
|
||||
|
||||
use super::xml::{Attribute, Node};
|
||||
use crate::text::util::is_cjk;
|
||||
|
||||
lazy_static! {
|
||||
lazy_static::lazy_static! {
|
||||
static ref FONT_LIST: FontList = FontList::new();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,6 @@ task_info = { path = "../../support/rust-task_info" }
|
|||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
regex = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||
[target.'cfg(not(any(target_os = "windows", target_os = "android")))'.dependencies]
|
||||
libc = { workspace = true }
|
||||
jemalloc-sys = { workspace = true }
|
||||
|
|
|
@ -387,16 +387,16 @@ impl ReportsForest {
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
mod system_reporter {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
use std::ffi::CString;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
use std::mem::size_of;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
use std::ptr::null_mut;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::c_int;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
use libc::{c_void, size_t};
|
||||
use profile_traits::mem::{Report, ReportKind, ReporterRequest};
|
||||
use profile_traits::path;
|
||||
|
@ -499,10 +499,10 @@ mod system_reporter {
|
|||
None
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
use jemalloc_sys::mallctl;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
fn jemalloc_stat(value_name: &str) -> Option<usize> {
|
||||
// Before we request the measurement of interest, we first send an "epoch"
|
||||
// request. Without that jemalloc gives cached statistics(!) which can be
|
||||
|
@ -549,7 +549,7 @@ mod system_reporter {
|
|||
Some(value as usize)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[cfg(any(target_os = "windows", target_os = "android"))]
|
||||
fn jemalloc_stat(_value_name: &str) -> Option<usize> {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -503,7 +503,14 @@ where
|
|||
EmbedderEvent::Resize => {
|
||||
return self.compositor.on_resize_window_event();
|
||||
},
|
||||
|
||||
EmbedderEvent::InvalidateNativeSurface => {
|
||||
self.compositor.invalidate_native_surface();
|
||||
},
|
||||
EmbedderEvent::ReplaceNativeSurface(native_widget, coords) => {
|
||||
self.compositor
|
||||
.replace_native_surface(native_widget, coords);
|
||||
self.compositor.composite();
|
||||
},
|
||||
EmbedderEvent::AllowNavigationResponse(pipeline_id, allowed) => {
|
||||
let msg = ConstellationMsg::AllowNavigationResponse(pipeline_id, allowed);
|
||||
if let Err(e) = self.constellation_chan.send(msg) {
|
||||
|
@ -1091,6 +1098,9 @@ fn default_user_agent_string_for(agent: UserAgent) -> &'static str {
|
|||
const DESKTOP_UA_STRING: &'static str =
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Servo/1.0 Firefox/111.0";
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
const DESKTOP_UA_STRING: &'static str = "";
|
||||
|
||||
match agent {
|
||||
UserAgent::Desktop => DESKTOP_UA_STRING,
|
||||
UserAgent::Android => "Mozilla/5.0 (Android; Mobile; rv:109.0) Servo/1.0 Firefox/111.0",
|
||||
|
|
|
@ -216,4 +216,28 @@ impl WebrenderSurfman {
|
|||
let ref context = self.0.context.borrow();
|
||||
device.get_proc_address(context, name)
|
||||
}
|
||||
|
||||
pub fn unbind_native_surface_from_context(&self) -> Result<(), Error> {
|
||||
let device = self.0.device.borrow_mut();
|
||||
let mut context = self.0.context.borrow_mut();
|
||||
let mut surface = device.unbind_surface_from_context(&mut context)?.unwrap();
|
||||
let _ = device.destroy_surface(&mut context, &mut surface)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn bind_native_surface_to_context(&self, native_widget: NativeWidget) -> Result<(), Error> {
|
||||
let mut device = self.0.device.borrow_mut();
|
||||
let mut context = self.0.context.borrow_mut();
|
||||
let surface_access = SurfaceAccess::GPUOnly;
|
||||
let surface_type = SurfaceType::Widget { native_widget };
|
||||
let surface = device.create_surface(&context, surface_access, surface_type)?;
|
||||
device
|
||||
.bind_surface_to_context(&mut context, surface)
|
||||
.map_err(|(err, mut surface)| {
|
||||
let _ = device.destroy_surface(&mut context, &mut surface);
|
||||
err
|
||||
})?;
|
||||
device.make_context_current(&context)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue