update electron android adb over browser
This commit is contained in:
parent
21109e4bf9
commit
f6295a9c2f
26 changed files with 1551 additions and 172 deletions
19
client-electron/electron/adb/adbDaemonUSB.ts
Normal file
19
client-electron/electron/adb/adbDaemonUSB.ts
Normal 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)
|
||||
})
|
||||
}
|
||||
34
client-electron/electron/deeplink.ts
Normal file
34
client-electron/electron/deeplink.ts
Normal 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')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
2
client-electron/electron/electron-env.d.ts
vendored
2
client-electron/electron/electron-env.d.ts
vendored
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
22
client-electron/electron/keychain.ts
Normal file
22
client-electron/electron/keychain.ts
Normal 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
|
||||
})
|
||||
}
|
||||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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>) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue