Skip to content

Commit

Permalink
add ipc features
Browse files Browse the repository at this point in the history
  • Loading branch information
lazytiger committed Dec 21, 2023
1 parent 6f78fd9 commit 9a0a7cc
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<item name="android:windowFullscreen">true</item>
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:windowFullscreen">true</item>
<!-- Customize your theme here. -->
</style>
</resources>
54 changes: 48 additions & 6 deletions mobile2/backend/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod platform;
use std::sync::RwLock;

use crate::platform::{init_builder, init_logging};
use anyhow::Result;
use lazy_static::lazy_static;
use wry::{
application::{
event::{Event, StartCause, WindowEvent},
Expand All @@ -11,9 +11,20 @@ use wry::{
webview::{WebView, WebViewBuilder},
};

use crate::{
platform::{init_builder, init_logging},
types::{Error, IPCRequest, MobileTrojanLoop},
};

mod platform;
mod types;

lazy_static! {
pub static ref LOOPER: RwLock<MobileTrojanLoop> = MobileTrojanLoop::new();
}
pub fn main() -> Result<()> {
init_logging();
let event_loop = EventLoop::new();
let event_loop = LOOPER.write().unwrap().looper.take().unwrap();

let mut webview = None;
event_loop.run(move |event, event_loop, control_flow| {
Expand All @@ -30,16 +41,31 @@ pub fn main() -> Result<()> {
webview.take();
*control_flow = ControlFlow::Exit;
}
Event::UserEvent(code) => {
if let Some(webview) = &webview {
if let Err(err) = webview.evaluate_script(&code) {
log::error!("run code:{} failed:{}", code, err);
}
}
}
_ => (),
}
});
}

fn handle_ipc(s: &String) -> Result<()> {
fn handle_ipc(s: &String) -> Result<(), types::Error> {
let request: IPCRequest = serde_json::from_str(s.as_str())?;
match request.method.as_str() {
"startInit" => {
log::info!("start init now");
set_config("".to_string())?;
}
_ => {}
}
Ok(())
}

fn build_webview(event_loop: &EventLoopWindowTarget<()>) -> Result<WebView> {
fn build_webview(event_loop: &EventLoopWindowTarget<String>) -> Result<WebView> {
let window = WindowBuilder::new()
.with_title("Trojan Mobile App")
.build(event_loop)?;
Expand All @@ -48,7 +74,6 @@ fn build_webview(event_loop: &EventLoopWindowTarget<()>) -> Result<WebView> {
// If you want to use custom protocol, set url like this and add files like index.html to assets directory.
.with_url("wry://assets/index.html")?
.with_devtools(true)
.with_initialization_script("console.log('hello world from init script');")
.with_ipc_handler(|_, s| {
if let Err(err) = handle_ipc(&s) {
log::error!("call ipc:{} failed:{:?}", s, err);
Expand All @@ -59,3 +84,20 @@ fn build_webview(event_loop: &EventLoopWindowTarget<()>) -> Result<WebView> {

Ok(webview)
}

fn call_js(code: String) -> Result<(), Error> {
LOOPER
.read()
.map_err(|err| Error::Lock(err.to_string()))?
.proxy
.send_event(code)?;
Ok(())
}

pub fn set_config(data: String) -> Result<(), Error> {
call_js(format!("window.setConfig('{}');", data))
}

pub fn set_app_list(data: String) -> Result<(), Error> {
call_js(format!("window.setAppList('{}');", data))
}
40 changes: 40 additions & 0 deletions mobile2/backend/src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use derive_more::From;
use serde::Deserialize;
use std::{env::JoinPathsError, sync::RwLock};
use wry::application::event_loop::{EventLoop, EventLoopBuilder, EventLoopClosed, EventLoopProxy};

pub struct MobileTrojanLoop {
pub looper: Option<EventLoop<String>>,
pub proxy: EventLoopProxy<String>,
}

unsafe impl Sync for MobileTrojanLoop {}
unsafe impl Send for MobileTrojanLoop {}

impl MobileTrojanLoop {
pub fn new() -> RwLock<Self> {
let looper = EventLoopBuilder::with_user_event().build();
let proxy = looper.create_proxy();
RwLock::new(Self {
looper: Some(looper),
proxy,
})
}
}

#[derive(Deserialize, Default, Debug)]
pub struct IPCRequest {
pub method: String,
pub payload: String,
}

#[derive(From, Debug)]
pub enum Error {
#[cfg(target_os = "android")]
JNI(jni::errors::Error),
JSON(serde_json::Error),
Lock(String),
IPC(EventLoopClosed<String>),
Path(JoinPathsError),
IO(std::io::Error),
}
37 changes: 35 additions & 2 deletions mobile2/frontend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,49 @@
*/

// Plugins
import { registerPlugins } from '@/plugins'
import {registerPlugins} from '@/plugins'

// Components
import App from './App.vue'

// Composables
import { createApp } from 'vue'
import {createApp} from 'vue'
import router from "@/router";

const app = createApp(App)

registerPlugins(app)

app.mount('#app')

declare global {
interface Window {
ipc: IPCHandle;

setConfig(data: String): void

setAppList(data: String): void

setError(data: String): void
}

interface IPCHandle {
postMessage(msg: String): void
}
}

window.setConfig = (data) => {
router.push("/")
}

window.setError = (err) => {

}

window.setAppList = (data) => {

}

if (window.ipc != undefined) {
window.ipc.postMessage(JSON.stringify({method: "startInit", payload: ""}))
}
Loading

0 comments on commit 9a0a7cc

Please sign in to comment.