From 88ffe9f7a56ef0981805a7b8264f870947cebcf5 Mon Sep 17 00:00:00 2001 From: Jonathan Schwender <55576758+jschwe@users.noreply.github.com> Date: Tue, 24 Sep 2024 06:29:53 +0200 Subject: [PATCH] ohos: Bundle resource files in hap (#33513) Bundle resource files into the .hap, so they are available as files in the application sandbox, instead of included into the shared library. This should slightly reduce the binary size in debug and release mode. Signed-off-by: Jonathan Schwender Signed-off-by: Jonathan Schwender --- ports/servoshell/egl/android.rs | 1 + .../servoshell/egl/{ => android}/resources.rs | 30 ++++++++--------- ports/servoshell/egl/android/simpleservo.rs | 4 +-- ports/servoshell/egl/mod.rs | 1 - ports/servoshell/egl/ohos.rs | 3 ++ ports/servoshell/egl/ohos/resources.rs | 33 +++++++++++++++++++ ports/servoshell/egl/ohos/simpleservo.rs | 12 +++++-- ports/servoshell/egl/servo_glue.rs | 4 +++ python/servo/package_commands.py | 4 +++ .../entry/src/main/ets/pages/Index.ets | 6 ++++ 10 files changed, 77 insertions(+), 21 deletions(-) rename ports/servoshell/egl/{ => android}/resources.rs (53%) create mode 100644 ports/servoshell/egl/ohos/resources.rs diff --git a/ports/servoshell/egl/android.rs b/ports/servoshell/egl/android.rs index f53ed5b2f51..d3b09769627 100644 --- a/ports/servoshell/egl/android.rs +++ b/ports/servoshell/egl/android.rs @@ -4,6 +4,7 @@ #![allow(non_snake_case)] +mod resources; mod simpleservo; use std::collections::HashMap; diff --git a/ports/servoshell/egl/resources.rs b/ports/servoshell/egl/android/resources.rs similarity index 53% rename from ports/servoshell/egl/resources.rs rename to ports/servoshell/egl/android/resources.rs index 9ada47afdb4..fb9d837aeb6 100644 --- a/ports/servoshell/egl/resources.rs +++ b/ports/servoshell/egl/android/resources.rs @@ -16,32 +16,32 @@ impl ResourceReaderInstance { impl ResourceReaderMethods for ResourceReaderInstance { fn read(&self, res: Resource) -> Vec { Vec::from(match res { - Resource::Preferences => &include_bytes!("../../../resources/prefs.json")[..], + Resource::Preferences => &include_bytes!("../../../../resources/prefs.json")[..], Resource::HstsPreloadList => { - &include_bytes!("../../../resources/hsts_preload.json")[..] + &include_bytes!("../../../../resources/hsts_preload.json")[..] }, - Resource::BadCertHTML => &include_bytes!("../../../resources/badcert.html")[..], - Resource::NetErrorHTML => &include_bytes!("../../../resources/neterror.html")[..], - Resource::UserAgentCSS => &include_bytes!("../../../resources/user-agent.css")[..], - Resource::ServoCSS => &include_bytes!("../../../resources/servo.css")[..], + Resource::BadCertHTML => &include_bytes!("../../../../resources/badcert.html")[..], + Resource::NetErrorHTML => &include_bytes!("../../../../resources/neterror.html")[..], + Resource::UserAgentCSS => &include_bytes!("../../../../resources/user-agent.css")[..], + Resource::ServoCSS => &include_bytes!("../../../../resources/servo.css")[..], Resource::PresentationalHintsCSS => { - &include_bytes!("../../../resources/presentational-hints.css")[..] + &include_bytes!("../../../../resources/presentational-hints.css")[..] }, - Resource::QuirksModeCSS => &include_bytes!("../../../resources/quirks-mode.css")[..], - Resource::RippyPNG => &include_bytes!("../../../resources/rippy.png")[..], - Resource::DomainList => &include_bytes!("../../../resources/public_domains.txt")[..], + Resource::QuirksModeCSS => &include_bytes!("../../../../resources/quirks-mode.css")[..], + Resource::RippyPNG => &include_bytes!("../../../../resources/rippy.png")[..], + Resource::DomainList => &include_bytes!("../../../../resources/public_domains.txt")[..], Resource::BluetoothBlocklist => { - &include_bytes!("../../../resources/gatt_blocklist.txt")[..] + &include_bytes!("../../../../resources/gatt_blocklist.txt")[..] }, Resource::MediaControlsCSS => { - &include_bytes!("../../../resources/media-controls.css")[..] + &include_bytes!("../../../../resources/media-controls.css")[..] }, Resource::MediaControlsJS => { - &include_bytes!("../../../resources/media-controls.js")[..] + &include_bytes!("../../../../resources/media-controls.js")[..] }, - Resource::CrashHTML => &include_bytes!("../../../resources/crash.html")[..], + Resource::CrashHTML => &include_bytes!("../../../../resources/crash.html")[..], Resource::DirectoryListingHTML => { - &include_bytes!("../../../resources/directory-listing.html")[..] + &include_bytes!("../../../../resources/directory-listing.html")[..] }, }) } diff --git a/ports/servoshell/egl/android/simpleservo.rs b/ports/servoshell/egl/android/simpleservo.rs index d5b9a73ebc8..194203d9102 100644 --- a/ports/servoshell/egl/android/simpleservo.rs +++ b/ports/servoshell/egl/android/simpleservo.rs @@ -27,8 +27,8 @@ use servo::webrender_traits::RenderingContext; use servo::{self, gl, Servo}; use surfman::{Connection, SurfaceType}; +use crate::egl::android::resources::ResourceReaderInstance; use crate::egl::host_trait::HostTrait; -use crate::egl::resources::ResourceReaderInstance; use crate::egl::servo_glue::{ Coordinates, ServoEmbedderCallbacks, ServoGlue, ServoWindowCallbacks, }; @@ -173,7 +173,7 @@ pub fn init( ); SERVO.with(|s| { - let mut servo_glue = ServoGlue::new(rendering_context, servo.servo, window_callbacks); + let mut servo_glue = ServoGlue::new(rendering_context, servo.servo, window_callbacks, None); let _ = servo_glue.process_event(EmbedderEvent::NewWebView(url, servo.browser_id)); *s.borrow_mut() = Some(servo_glue); }); diff --git a/ports/servoshell/egl/mod.rs b/ports/servoshell/egl/mod.rs index 28074756b57..b67dea98d1c 100644 --- a/ports/servoshell/egl/mod.rs +++ b/ports/servoshell/egl/mod.rs @@ -14,5 +14,4 @@ mod ohos; mod log; mod host_trait; -mod resources; mod servo_glue; diff --git a/ports/servoshell/egl/ohos.rs b/ports/servoshell/egl/ohos.rs index d5bf4b4dafb..363125dc287 100644 --- a/ports/servoshell/egl/ohos.rs +++ b/ports/servoshell/egl/ohos.rs @@ -31,6 +31,7 @@ use super::gl_glue; use super::host_trait::HostTrait; use super::servo_glue::ServoGlue; +mod resources; mod simpleservo; // Todo: in the future these libraries should be added by Rust sys-crates @@ -47,6 +48,8 @@ pub struct InitOpts { pub url: String, pub device_type: String, pub os_full_name: String, + /// Path to application data bundled with the servo app, e.g. web-pages. + pub resource_dir: String, pub display_density: f64, } diff --git a/ports/servoshell/egl/ohos/resources.rs b/ports/servoshell/egl/ohos/resources.rs new file mode 100644 index 00000000000..77d8fe68892 --- /dev/null +++ b/ports/servoshell/egl/ohos/resources.rs @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::fs; +use std::path::PathBuf; + +use servo::embedder_traits::resources::{Resource, ResourceReaderMethods}; + +pub(crate) struct ResourceReaderInstance { + resource_dir: PathBuf, +} + +impl ResourceReaderInstance { + pub(crate) fn new(resource_dir: PathBuf) -> Self { + assert!(resource_dir.is_dir()); + Self { resource_dir } + } +} + +impl ResourceReaderMethods for ResourceReaderInstance { + fn read(&self, res: Resource) -> Vec { + let file_path = self.resource_dir.join(res.filename()); + fs::read(&file_path).expect("failed to read resource file") + } + + fn sandbox_access_files(&self) -> Vec { + vec![] + } + + fn sandbox_access_files_dirs(&self) -> Vec { + vec![] + } +} diff --git a/ports/servoshell/egl/ohos/simpleservo.rs b/ports/servoshell/egl/ohos/simpleservo.rs index 226a5c18fc7..4dad52c0c75 100644 --- a/ports/servoshell/egl/ohos/simpleservo.rs +++ b/ports/servoshell/egl/ohos/simpleservo.rs @@ -23,8 +23,8 @@ use servo::{self, gl, Servo}; use surfman::{Connection, SurfaceType}; use crate::egl::host_trait::HostTrait; +use crate::egl::ohos::resources::ResourceReaderInstance; use crate::egl::ohos::InitOpts; -use crate::egl::resources::ResourceReaderInstance; use crate::egl::servo_glue::{ Coordinates, ServoEmbedderCallbacks, ServoGlue, ServoWindowCallbacks, }; @@ -41,7 +41,8 @@ pub fn init( ) -> Result { info!("Entered simpleservo init function"); crate::init_tracing(); - resources::set(Box::new(ResourceReaderInstance::new())); + let resource_dir = PathBuf::from(&options.resource_dir).join("servo"); + resources::set(Box::new(ResourceReaderInstance::new(resource_dir))); gl.clear_color(1.0, 1.0, 1.0, 1.0); gl.clear(gl::COLOR_BUFFER_BIT); @@ -96,7 +97,12 @@ pub fn init( CompositeTarget::Window, ); - let mut servo_glue = ServoGlue::new(rendering_context, servo.servo, window_callbacks); + let mut servo_glue = ServoGlue::new( + rendering_context, + servo.servo, + window_callbacks, + Some(options.resource_dir), + ); let initial_url = ServoUrl::parse(options.url.as_str()) .inspect_err(|e| error!("Invalid initial Servo URL `{}`. Error: {e:?}", options.url)) diff --git a/ports/servoshell/egl/servo_glue.rs b/ports/servoshell/egl/servo_glue.rs index 48e3954bdb2..b5739f2ba50 100644 --- a/ports/servoshell/egl/servo_glue.rs +++ b/ports/servoshell/egl/servo_glue.rs @@ -23,6 +23,7 @@ use servo::keyboard_types::{Key, KeyState, KeyboardEvent}; use servo::script_traits::{ MediaSessionActionType, MouseButton, TouchEventType, TouchId, TraversalDirection, }; +use servo::servo_url::ServoUrl; use servo::style_traits::DevicePixel; use servo::webrender_api::ScrollLocation; use servo::webrender_traits::RenderingContext; @@ -85,6 +86,7 @@ pub struct ServoGlue { need_present: bool, callbacks: Rc, events: Vec, + resource_dir: Option, context_menu_sender: Option>, /// List of top-level browsing contexts. @@ -106,6 +108,7 @@ impl ServoGlue { rendering_context: RenderingContext, servo: Servo, callbacks: Rc, + resource_dir: Option, ) -> Self { Self { rendering_context, @@ -114,6 +117,7 @@ impl ServoGlue { need_present: false, callbacks, events: vec![], + resource_dir, context_menu_sender: None, webviews: HashMap::default(), creation_order: vec![], diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py index cad2a73f275..6ddf378c2c5 100644 --- a/python/servo/package_commands.py +++ b/python/servo/package_commands.py @@ -194,6 +194,10 @@ class PackageCommands(CommandBase): print("Cleaning up from previous packaging") delete(ohos_target_dir) shutil.copytree(ohos_app_dir, ohos_target_dir) + resources_src_dir = path.join(self.get_top_dir(), "resources") + resources_app_dir = path.join(ohos_target_dir, "AppScope", "resources", "resfile", "servo") + os.makedirs(resources_app_dir, exist_ok=True) + shutil.copytree(resources_src_dir, resources_app_dir, dirs_exist_ok=True) # Map non-debug profiles to 'release' buildMode HAP. if build_type.is_custom(): diff --git a/support/openharmony/entry/src/main/ets/pages/Index.ets b/support/openharmony/entry/src/main/ets/pages/Index.ets index 96c5a65846b..f9eda7854a7 100644 --- a/support/openharmony/entry/src/main/ets/pages/Index.ets +++ b/support/openharmony/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,4 @@ +import { common } from '@kit.AbilityKit'; import display from '@ohos.display'; import deviceInfo from '@ohos.deviceInfo'; @@ -13,6 +14,7 @@ interface InitOpts { url: string; deviceType: string, osFullName: string, + resourceDir: string, displayDensity: number, } @@ -47,6 +49,7 @@ struct Index { libraryname: 'servoshell', } @State urlToLoad: string = 'https://servo.org' + private context = getContext(this) as common.UIAbilityContext; build() { Column() { @@ -82,11 +85,14 @@ struct Index { .focusable(true) .onLoad((xComponentContext) => { this.xComponentContext = xComponentContext as ServoXComponentInterface; + let resource_dir: string = this.context.resourceDir; + console.debug("Resources are located at %s", resource_dir); let init_options: InitOpts = { url: this.urlToLoad, deviceType: get_device_type(), osFullName: deviceInfo.osFullName, displayDensity: get_density(), + resourceDir: resource_dir, } this.xComponentContext.initServo(init_options) this.xComponentContext.registerURLcallback((new_url) => {