-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
first hack at support for running the App Loader inside Gadgetbridge
- Loading branch information
1 parent
caa5629
commit 373e967
Showing
2 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/* Detects if we're running under Gadgetbridge in a WebView, and if | ||
so it overwrites the 'Puck' library with a special one that calls back | ||
into Gadgetbridge to handle watch communications */ | ||
|
||
/*// test code | ||
Android = { | ||
bangleTx : function(data) { | ||
console.log("TX : "+JSON.stringify(data)); | ||
} | ||
};*/ | ||
|
||
if (typeof Android!=="undefined") { | ||
console.log("Running under Gadgetbridge, overwrite Puck library"); | ||
|
||
var isBusy = false; | ||
var queue = []; | ||
var connection = { | ||
cb : function(data) {}, | ||
write : function(data, writecb) { | ||
Android.bangleTx(data); | ||
Puck.writeProgress(data.length, data.length); | ||
if (writecb) setTimeout(writecb,10); | ||
}, | ||
close : function() {}, | ||
received : "", | ||
hadData : false | ||
} | ||
|
||
function bangleRx(data) { | ||
// document.getElementById("status").innerText = "RX:"+data; | ||
connection.received += data; | ||
connection.hadData = true; | ||
if (connection.cb) connection.cb(data); | ||
} | ||
|
||
function log(level, s) { | ||
if (Puck.log) Puck.log(level, s); | ||
} | ||
|
||
function handleQueue() { | ||
if (!queue.length) return; | ||
var q = queue.shift(); | ||
log(3,"Executing "+JSON.stringify(q)+" from queue"); | ||
if (q.type == "write") Puck.write(q.data, q.callback, q.callbackNewline); | ||
else log(1,"Unknown queue item "+JSON.stringify(q)); | ||
} | ||
|
||
/* convenience function... Write data, call the callback with data: | ||
callbackNewline = false => if no new data received for ~0.2 sec | ||
callbackNewline = true => after a newline */ | ||
function write(data, callback, callbackNewline) { | ||
let result; | ||
/// If there wasn't a callback function, then promisify | ||
if (typeof callback !== 'function') { | ||
callbackNewline = callback; | ||
|
||
result = new Promise((resolve, reject) => callback = (value, err) => { | ||
if (err) reject(err); | ||
else resolve(value); | ||
}); | ||
} | ||
|
||
if (isBusy) { | ||
log(3, "Busy - adding Puck.write to queue"); | ||
queue.push({type:"write", data:data, callback:callback, callbackNewline:callbackNewline}); | ||
return result; | ||
} | ||
|
||
var cbTimeout; | ||
function onWritten() { | ||
if (callbackNewline) { | ||
connection.cb = function(d) { | ||
var newLineIdx = connection.received.indexOf("\n"); | ||
if (newLineIdx>=0) { | ||
var l = connection.received.substr(0,newLineIdx); | ||
connection.received = connection.received.substr(newLineIdx+1); | ||
connection.cb = undefined; | ||
if (cbTimeout) clearTimeout(cbTimeout); | ||
cbTimeout = undefined; | ||
if (callback) | ||
callback(l); | ||
isBusy = false; | ||
handleQueue(); | ||
} | ||
}; | ||
} | ||
// wait for any received data if we have a callback... | ||
var maxTime = 300; // 30 sec - Max time we wait in total, even if getting data | ||
var dataWaitTime = callbackNewline ? 100/*10 sec if waiting for newline*/ : 3/*300ms*/; | ||
var maxDataTime = dataWaitTime; // max time we wait after having received data | ||
cbTimeout = setTimeout(function timeout() { | ||
cbTimeout = undefined; | ||
if (maxTime) maxTime--; | ||
if (maxDataTime) maxDataTime--; | ||
if (connection.hadData) maxDataTime=dataWaitTime; | ||
if (maxDataTime && maxTime) { | ||
cbTimeout = setTimeout(timeout, 100); | ||
} else { | ||
connection.cb = undefined; | ||
if (callback) | ||
callback(connection.received); | ||
isBusy = false; | ||
handleQueue(); | ||
connection.received = ""; | ||
} | ||
connection.hadData = false; | ||
}, 100); | ||
} | ||
|
||
if (!connection.txInProgress) connection.received = ""; | ||
isBusy = true; | ||
connection.write(data, onWritten); | ||
return result | ||
} | ||
|
||
// ---------------------------------------------------------- | ||
|
||
Puck = { | ||
/// Are we writing debug information? 0 is no, 1 is some, 2 is more, 3 is all. | ||
debug : Puck.debug, | ||
/// Should we use flow control? Default is true | ||
flowControl : true, | ||
/// Used internally to write log information - you can replace this with your own function | ||
log : function(level, s) { if (level <= this.debug) console.log("<BLE> "+s)}, | ||
/// Called with the current send progress or undefined when done - you can replace this with your own function | ||
writeProgress : Puck.writeProgress, | ||
connect : function(callback) { | ||
setTimeout(callback, 10); | ||
}, | ||
write : write, | ||
eval : function(expr, cb) { | ||
const response = write('\x10Bluetooth.println(JSON.stringify(' + expr + '))\n', true) | ||
.then(function (d) { | ||
try { | ||
return JSON.parse(d); | ||
} catch (e) { | ||
log(1, "Unable to decode " + JSON.stringify(d) + ", got " + e.toString()); | ||
return Promise.reject(d); | ||
} | ||
}); | ||
if (cb) { | ||
return void response.then(cb, (err) => cb(null, err)); | ||
} else { | ||
return response; | ||
} | ||
}, | ||
isConnected : function() { return true; }, | ||
getConnection : function() { return connection; }, | ||
close : function() { | ||
if (connection) | ||
connection.close(); | ||
}, | ||
}; | ||
// no need for header | ||
document.getElementsByTagName("header")[0].style="display:none"; | ||
// force connection attempt automatically | ||
setTimeout(function() { | ||
getInstalledApps(true).catch(err => { | ||
showToast("Device connection failed, "+err,"error"); | ||
}); | ||
}, 100); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters