update electron android adb over browser

This commit is contained in:
Kenta420 2024-01-19 17:53:48 +07:00
parent 21109e4bf9
commit f6295a9c2f
26 changed files with 1551 additions and 172 deletions

View file

@ -0,0 +1,19 @@
// import type { AdbDaemonWebUsbDevice } from '@yume-chan/adb-daemon-webusb'
// import { AdbDaemonWebUsbDeviceManager } from '@yume-chan/adb-daemon-webusb'
import { webusb } from 'usb'
// const WebUsb: WebUSB = new WebUSB({ allowAllDevices: true })
// const Manager: AdbDaemonWebUsbDeviceManager = new AdbDaemonWebUsbDeviceManager(
// WebUsb
// )
export function getDevices() {
// const devices: AdbDaemonWebUsbDevice[] = await Manager.getDevices()
// if (!devices.length) {
// alert('No device connected')
// }
webusb.requestDevice({ filters: [] }).then(device => {
console.log(device)
})
}

View file

@ -0,0 +1,34 @@
import { type BrowserWindow } from 'electron'
export default function (
app: Electron.App,
win: BrowserWindow | null,
ipcMain: Electron.IpcMain,
shell: Electron.Shell
) {
ipcMain.on('deeplink', (_event, url) => {
// open browser
shell.openExternal(url)
})
app.on('open-url', (_event, url) => {
const paramsString = url.split('://')[1]
const kind = paramsString.split('?')[0]
const params = new URLSearchParams(paramsString)
if (kind === '/login') {
win?.webContents.send('loginSuccess', {
id: params.get('id'),
name: params.get('name'),
email: params.get('email'),
picture: params.get('picture'),
permissions: params.get('permissions'),
access_token: params.get('access_token'),
max_age: params.get('max_age'),
refresh_token: params.get('refresh_token')
})
}
})
}

View file

@ -25,4 +25,6 @@ declare namespace NodeJS {
// Used in Renderer process, expose in `preload.ts`
interface Window {
ipcRenderer: import('electron').IpcRenderer
electronRuntime: boolean
platform: NodeJS.Platform
}

View file

@ -0,0 +1,22 @@
import { findCredentials, getPassword, setPassword } from '@postman/node-keytar'
export function eventGetKeyChain(icpMain: Electron.IpcMain) {
icpMain.on('get-keyChain', (event, serviceName, account) => {
getPassword(serviceName, account).then(password => {
event.returnValue = password
})
})
icpMain.on('set-keyChain', (_event, serviceName, account, password) => {
setPassword(serviceName, account, password)
})
icpMain.on('delete-keyChain', (_event, serviceName, account) => {
setPassword(serviceName, account, '')
})
icpMain.handle('keyChainSync', async (_event, serviceName) => {
const credentials = await findCredentials(serviceName)
return credentials
})
}

View file

@ -1,5 +1,7 @@
import { app, BrowserWindow, ipcMain, shell } from 'electron'
import path from 'node:path'
import deeplink from './deeplink'
import { eventGetKeyChain } from './keychain'
// The built directory structure
//
@ -10,7 +12,7 @@ import path from 'node:path'
// │ │ ├── main.js
// │ │ └── preload.js
// │
process.env.DIST = path.join(__dirname, '../dist')
process.env.DIST = path.join(__dirname, '../dist-renderer')
process.env.VITE_PUBLIC = app.isPackaged
? process.env.DIST
: path.join(process.env.DIST, '../public')
@ -42,6 +44,61 @@ function createWindow() {
app.setAsDefaultProtocolClient('taobin-electron')
}
let grantedDeviceThroughPermHandler: Electron.USBDevice
win.webContents.session.on(
'select-usb-device',
(event, details, callback) => {
// Add events to handle devices being added or removed before the callback on
// `select-usb-device` is called.
win?.webContents.session.on('usb-device-added', (_event, device) => {
console.log('usb-device-added FIRED WITH', device)
// Optionally update details.deviceList
})
win?.webContents.session.on('usb-device-removed', (_event, device) => {
console.log('usb-device-removed FIRED WITH', device)
// Optionally update details.deviceList
})
event.preventDefault()
if (details.deviceList && details.deviceList.length > 0) {
const deviceToReturn = details.deviceList.find(
device => device.vendorId === 1478
)
if (deviceToReturn) {
callback(deviceToReturn.deviceId)
} else {
callback()
}
}
}
)
win.webContents.session.setPermissionCheckHandler(
(_webContents, permission) => {
if (permission === 'usb') {
return true
}
return false
}
)
win.webContents.session.setDevicePermissionHandler(details => {
console.log(details)
if (details.deviceType === 'usb' && details.device.vendorId == 1478) {
if (!grantedDeviceThroughPermHandler) {
grantedDeviceThroughPermHandler = details.device as Electron.USBDevice
return true
} else if (grantedDeviceThroughPermHandler.vendorId === 1478) {
return true
} else {
return false
}
}
return false
})
if (VITE_DEV_SERVER_URL) {
win.loadURL(VITE_DEV_SERVER_URL)
} else {
@ -68,17 +125,12 @@ app.on('activate', () => {
}
})
app.on('open-url', (_event, url) => {
win?.webContents.send('deeplink', url)
})
// Create mainWindow, load the rest of the app, etc...
// Create MainWindow, load the rest of the app, etc...
app.whenReady().then(() => {
createWindow()
})
// deeplink
deeplink(app, win, ipcMain, shell)
// deeplink
ipcMain.on('deeplink', (_event, url) => {
// open browser
shell.openExternal(url)
//keychain
eventGetKeyChain(ipcMain)
})

View file

@ -4,6 +4,8 @@ import { contextBridge, ipcRenderer } from 'electron'
// --------- Expose some API to the Renderer process ---------
contextBridge.exposeInMainWorld('ipcRenderer', withPrototype(ipcRenderer))
contextBridge.exposeInMainWorld('electronRuntime', true)
contextBridge.exposeInMainWorld('platform', process.platform)
// `exposeInMainWorld` can't detect attributes and methods of `prototype`, manually patching it.
function withPrototype(obj: Record<string, any>) {