1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/* 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::cell::RefCell;
use std::fs;
use std::os::raw::c_void;
use std::path::PathBuf;
use std::ptr::NonNull;
use std::rc::Rc;
use dpi::PhysicalSize;
use log::{debug, info, warn};
use raw_window_handle::{
DisplayHandle, OhosDisplayHandle, OhosNdkWindowHandle, RawDisplayHandle, RawWindowHandle,
WindowHandle,
};
use servo::{self, EventLoopWaker, ServoBuilder, WindowRenderingContext, resources};
use xcomponent_sys::OH_NativeXComponent;
use crate::egl::app_state::{Coordinates, RunningAppState, ServoWindowCallbacks};
use crate::egl::host_trait::HostTrait;
use crate::egl::ohos::InitOpts;
use crate::egl::ohos::resources::ResourceReaderInstance;
use crate::prefs::{ArgumentParsingResult, parse_command_line_arguments};
/// Initialize Servo. At that point, we need a valid GL context.
/// In the future, this will be done in multiple steps.
pub fn init(
options: InitOpts,
native_window: *mut c_void,
xcomponent: *mut OH_NativeXComponent,
waker: Box<dyn EventLoopWaker>,
callbacks: Box<dyn HostTrait>,
) -> Result<Rc<RunningAppState>, &'static str> {
info!("Entered simpleservo init function");
crate::init_crypto();
let resource_dir = PathBuf::from(&options.resource_dir).join("servo");
debug!("Resources are located at: {:?}", resource_dir);
resources::set(Box::new(ResourceReaderInstance::new(resource_dir.clone())));
// It would be nice if `from_cmdline_args()` could accept str slices, to avoid allocations here.
// Then again, this code could and maybe even should be disabled in production builds.
let mut args = vec!["servoshell".to_string()];
args.extend(
options
.commandline_args
.split("\u{1f}")
.map(|arg| arg.to_string()),
);
debug!("Servo commandline args: {:?}", args);
let config_dir = PathBuf::from(&options.cache_dir).join("servo");
debug!("Configs are located at: {:?}", config_dir);
let _ = crate::prefs::DEFAULT_CONFIG_DIR
.set(config_dir.clone())
.inspect_err(|e| {
warn!(
"Default Prefs Dir already previously filled. Got error {}",
e.display()
);
});
// Ensure cache dir exists before copy `prefs.json`
let _ = crate::prefs::default_config_dir().inspect(|path| {
if !path.exists() {
fs::create_dir_all(path).unwrap_or_else(|e| {
log::error!("Failed to create config directory at {:?}: {:?}", path, e)
})
}
});
// Try copy `prefs.json` from {this.context.resource_prefsDir}/servo/
// to `config_dir` if none exist
let source_prefs = resource_dir.join("prefs.json");
let target_prefs = config_dir.join("prefs.json");
if !target_prefs.exists() && source_prefs.exists() {
debug!("Copy {:?} to {:?}", source_prefs, target_prefs);
fs::copy(&source_prefs, &target_prefs).unwrap_or_else(|e| {
debug!("Copy failed! {:?}", e);
0
});
}
let (opts, preferences, servoshell_preferences) = match parse_command_line_arguments(args) {
ArgumentParsingResult::ContentProcess(..) => {
unreachable!("OHOS does not have support for multiprocess yet.")
},
ArgumentParsingResult::ChromeProcess(opts, preferences, servoshell_preferences) => {
(opts, preferences, servoshell_preferences)
},
};
crate::init_tracing(servoshell_preferences.tracing_filter.as_deref());
#[cfg(target_env = "ohos")]
crate::egl::ohos::set_log_filter(servoshell_preferences.log_filter.as_deref());
let Ok(window_size) = (unsafe { super::get_xcomponent_size(xcomponent, native_window) }) else {
return Err("Failed to get xcomponent size");
};
let coordinates = Coordinates::new(0, 0, window_size.width, window_size.height);
let display_handle = RawDisplayHandle::Ohos(OhosDisplayHandle::new());
let display_handle = unsafe { DisplayHandle::borrow_raw(display_handle) };
let native_window = NonNull::new(native_window).expect("Could not get native window");
let window_handle = RawWindowHandle::OhosNdk(OhosNdkWindowHandle::new(native_window));
let window_handle = unsafe { WindowHandle::borrow_raw(window_handle) };
let rendering_context = Rc::new(
WindowRenderingContext::new(
display_handle,
window_handle,
PhysicalSize::new(window_size.width as u32, window_size.height as u32),
)
.expect("Could not create RenderingContext"),
);
info!("before ServoWindowCallbacks...");
let window_callbacks = Rc::new(ServoWindowCallbacks::new(
callbacks,
RefCell::new(coordinates),
));
let servo = ServoBuilder::new(rendering_context.clone())
.opts(opts)
.preferences(preferences)
.event_loop_waker(waker)
.build();
let app_state = RunningAppState::new(
Some(options.url),
options.display_density as f32,
rendering_context,
servo,
window_callbacks,
servoshell_preferences,
);
Ok(app_state)
}
|