Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adb sideload support #368

Open
upintheairsheep opened this issue Jan 15, 2022 · 1 comment
Open

Adb sideload support #368

upintheairsheep opened this issue Jan 15, 2022 · 1 comment
Labels
type:enhancement New feature or request

Comments

@upintheairsheep
Copy link
Contributor

Add support to sideload a rom, but say not recommend as it is really fragile and this isn't really stable.

@yume-chan yume-chan added the type:enhancement New feature or request label Jan 15, 2022
@alangecker
Copy link

alangecker commented Dec 16, 2022

I've just worked on the ya-webadb based sideload feature and want to share it. Maybe someone finds the time to create a proper PR - I still stuggle a bit with the huge repo :D

const ADB_EXIT_SUCCESS = 'DONEDONE'
const ADB_EXIT_FAILURE = 'FAILFAIL'
const ADB_SIDELOAD_CHUNK_SIZE = 65536

async function adbSideload(device: Adb, data: Blob, onProgress: (percentage: number) => void = (_) => {}) {
    const socket = await device.createSocket(`sideload-host:${data.size}:${ADB_SIDELOAD_CHUNK_SIZE}`)
    const reader = socket.readable.getReader()
    const writer = socket.writable.getWriter()

    try {
        let transmittedBytes = 0
        while(true) {
            const res = await reader.read()
            if(res.done) {
                throw new Error('reader unexpectedly ended')
            }
            const resStr = Buffer.from(res.value).toString('ascii')
            if(resStr == ADB_EXIT_SUCCESS) {
                break
            } else if (resStr == ADB_EXIT_FAILURE) {
                throw new Error('sideload failed')
            }
            const requestedBlock = parseInt(resStr)
            const offset = requestedBlock * ADB_SIDELOAD_CHUNK_SIZE;
            if(offset > data.size) {
                throw new Error(`"adb: failed to read block ${requestedBlock} at offset ${offset}, past end ${data.size}`)
            }
    
            const end = Math.min(offset + ADB_SIDELOAD_CHUNK_SIZE, data.size)
            const chunk = data.slice(offset, end)
            await writer.write(new Uint8Array(await chunk.arrayBuffer()))
    
            transmittedBytes += chunk.size
    

            onProgress(transmittedBytes/data.size*100 * 0.99)
        }
    } catch(err) {
        await socket.close().catch(() => {})
        throw err
    }
    await socket.close()
}

#edit: I've used Buffer to convert the Uint8Array to a string, which is not available in the browser. this should be therefore replaced with something cross-platform compatible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants