Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions crates/ability/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,13 @@ impl OpenHarmonyAppInner {
}

type EventLoop = Arc<RefCell<Option<Box<dyn FnMut(Event) + Sync + Send>>>>;
type BackPressInterceptor = Arc<RefCell<Option<Box<dyn FnMut() -> bool + Sync + Send>>>>;

#[derive(Clone)]
pub struct OpenHarmonyApp {
pub(crate) inner: Arc<RwLock<OpenHarmonyAppInner>>,
pub(crate) event_loop: EventLoop,
pub(crate) back_press_interceptor: BackPressInterceptor,
pub(crate) ime: Arc<RefCell<Option<IME>>>,
is_keyboard_show: Arc<Mutex<bool>>,
}
Expand Down Expand Up @@ -212,6 +214,8 @@ impl OpenHarmonyApp {
#[allow(clippy::arc_with_non_send_sync)]
event_loop: Arc::new(RefCell::new(None)),
#[allow(clippy::arc_with_non_send_sync)]
back_press_interceptor: Arc::new(RefCell::new(None)),
#[allow(clippy::arc_with_non_send_sync)]
ime: Arc::new(RefCell::new(None)),
is_keyboard_show: Arc::new(Mutex::new(false)),
}
Expand Down Expand Up @@ -369,6 +373,18 @@ impl OpenHarmonyApp {
self.event_loop.replace(Some(static_handler));
HAS_EVENT.store(true, std::sync::atomic::Ordering::SeqCst);
}

/// Register back press interceptor. Return `true` to intercept back action, `false` to pass through.
pub fn on_back_press_intercept<'a, F: FnMut() -> bool + 'a>(&self, interceptor: F) {
let static_handler = unsafe {
std::mem::transmute::<
Box<dyn FnMut() -> bool + 'a>,
Box<dyn FnMut() -> bool + 'static + Sync + Send>,
>(Box::new(interceptor))
};

self.back_press_interceptor.replace(Some(static_handler));
}
}

impl Default for OpenHarmonyApp {
Expand Down
14 changes: 14 additions & 0 deletions crates/ability/src/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct EnvironmentCallback<'a> {
pub struct WindowStageEventCallback<'a> {
pub on_window_stage_create: Function<'a, (), ()>,
pub on_window_stage_destroy: Function<'a, (), ()>,
pub on_back_press_intercept: Function<'a, (), bool>,
pub on_ability_create: Function<'a, (), ()>,
pub on_ability_destroy: Function<'a, (), ()>,
pub on_ability_save_state: Function<'a, (), ()>,
Expand Down Expand Up @@ -199,6 +200,18 @@ pub fn create_lifecycle_handle<'a>(
Ok(())
})?;

let on_back_press_intercept_app = app.clone();
let on_back_press_intercept =
env.create_function_from_closure("on_back_press_intercept", move |_ctx| {
let intercept = on_back_press_intercept_app
.back_press_interceptor
.borrow_mut()
.as_mut()
.map(|h| h())
.unwrap_or(true);
Ok(intercept)
})?;

let on_ability_create_app = app.clone();
let on_ability_create = env.create_function_from_closure("on_ability_create", move |_ctx| {
if let Some(ref mut h) = *on_ability_create_app.event_loop.borrow_mut() {
Expand Down Expand Up @@ -261,6 +274,7 @@ pub fn create_lifecycle_handle<'a>(
window_stage_event_callback: WindowStageEventCallback {
on_window_stage_create,
on_window_stage_destroy,
on_back_press_intercept,
on_ability_create,
on_ability_destroy,
on_ability_save_state,
Expand Down
2 changes: 1 addition & 1 deletion rust_ability/AppScope/resources/base/element/string.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "rust_ability"
}
]
}
}
7 changes: 3 additions & 4 deletions rust_ability/AppScope/resources/base/media/layered_image.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
"layered-image": {
"background": "$media:background",
"foreground": "$media:foreground"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,9 @@ export class RustAbility extends UIAbility {
wantParam[STATE_KEY] = ret as string;
return AbilityConstant.OnSaveResult.RECOVERY_AGREE;
}

onBackPress(): boolean {
const intercept = this.lifecycle?.windowStageEventCallback.onBackPressIntercept();
return intercept ?? true;
}
}
1 change: 1 addition & 0 deletions rust_ability/ability_rust/src/main/ets/ability/type.ets
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface KeyboardCallback {
export interface WindowStageEventCallback {
onWindowStageCreate: () => void;
onWindowStageDestroy: () => void;
onBackPressIntercept: () => boolean;
onAbilityCreate: (arg: string) => void;
onAbilityDestroy: () => void;
onAbilitySaveState: () => string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,12 @@ export class RustWebviewNodeController extends NodeController {
return getCookies(url) as string;
};
const loadUrl = (url: string, header?: Record<string, string>) => {
const headers = Object.keys((header || {}) as Record<string, string>).reduce(
(t, i) => {
if (!!header![i]) {
t.push({ headerKey: i, headerValue: header![i] });
}
return t;
},
[] as Array<WebHeader>,
);
const headers = Object.keys((header || {}) as Record<string, string>).reduce((t, i) => {
if (!!header![i]) {
t.push({ headerKey: i, headerValue: header![i] });
}
return t;
}, [] as Array<WebHeader>);
controller.loadUrl(url, headers);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "page from package"
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "page from package"
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "page from package"
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "50fp"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
"layered-image": {
"background": "$media:background",
"foreground": "$media:foreground"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"src": [
"pages/Index"
]
}
}
15 changes: 15 additions & 0 deletions rust_example/xcomponent_example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use openharmony_ability_derive::ability;
static INNER_APP: LazyLock<RwLock<Option<OpenHarmonyApp>>> = LazyLock::new(|| RwLock::new(None));
static PERMISSION_REQUESTED: AtomicBool = AtomicBool::new(false);
static MAIN_THREAD_DEMO_REQUESTED: AtomicBool = AtomicBool::new(false);
static BACK_PRESS_INTERCEPT_ENABLED: AtomicBool = AtomicBool::new(true);

#[napi_derive_ohos::napi]
pub async fn demo_request_permission_from_main_thread() -> Result<Vec<i32>> {
Expand Down Expand Up @@ -42,10 +43,24 @@ pub async fn demo_request_permission_from_main_thread() -> Result<Vec<i32>> {
Ok(codes)
}

#[napi_derive_ohos::napi]
pub fn toggle_back_press_intercept() -> bool {
let current = BACK_PRESS_INTERCEPT_ENABLED.load(Ordering::SeqCst);
let next = !current;
BACK_PRESS_INTERCEPT_ENABLED.store(next, Ordering::SeqCst);
hilog_info!(format!("back press intercept set to: {}", next).as_str());
next
}

#[ability]
fn openharmony_app(app: OpenHarmonyApp) {
INNER_APP.write().unwrap().replace(app.clone());
let permission_app = app.clone();
app.on_back_press_intercept(|| {
let intercept = BACK_PRESS_INTERCEPT_ENABLED.load(Ordering::SeqCst);
hilog_info!(format!("on_back_press_intercept => {}", intercept).as_str());
intercept
});

app.run_loop(move |types| match types {
Event::SurfaceCreate => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "webview_example"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
"layered-image": {
"background": "$media:background",
"foreground": "$media:foreground"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "50fp"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
"layered-image": {
"background": "$media:background",
"foreground": "$media:foreground"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"src": [
"pages/Index"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"value": "example"
}
]
}
}
17 changes: 14 additions & 3 deletions xcomponent_example/entry/src/main/ets/pages/Index.ets
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import { DefaultXComponent } from "@ohos-rs/ability";
import { demoRequestPermissionFromMainThread } from "libxcomponent_example.so";
import {
demoRequestPermissionFromMainThread,
toggleBackPressIntercept,
} from "libxcomponent_example.so";

@Entry
@Component
struct Index {
private permissionDemoCalled: boolean = false;
@State interceptEnabled: boolean = true;

async handleClick() {
const re: number[] = await demoRequestPermissionFromMainThread();
console.log(`${re}`);
}

handleToggleBackIntercept() {
this.interceptEnabled = toggleBackPressIntercept();
console.log(`backPressIntercept=${this.interceptEnabled}`);
}

build() {
Row() {
Column() {
Button()
Button("request permission demo")
.onClick(() => this.handleClick())
Button(this.interceptEnabled ? "back intercept: ON" : "back intercept: OFF")
.onClick(() => this.handleToggleBackIntercept())
Text("Swipe back to test intercept behavior.")
DefaultXComponent()
}.width("100%")
}.height("100%");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
"layered-image": {
"background": "$media:background",
"foreground": "$media:foreground"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"src": [
"pages/Index"
]
}
}