Mapbox Navigation Off Route Detection not working - mapbox-android

I'm trying to test off route detection in mapbox navigation and it is not working. I've traced through and the OffRouteDetector.isUserOffRouteWith is getting called, but the status.getRouteState() is only ever returning "INITIALIZED" (which is not the expected RouteState.OFFROUTE)
I suspect there's an edge case I'm hitting as I'm using a trip with a start and end that are very far away from my current location. As such, it never "gets going". However, this is a valid scenario in my application (it involves stored routes that are immutable due to public safety concerns).
I've made an issue (that was closed) on github, but for background, it is here
EDIT:
Here is some code to get closer to what I'm trying to do. This is from the onCreate of the MainActivity of a default android studio project:
String jsonRoute = "{\"routes\":[{\"legs\":[{\"steps\":[{\"intersections\":[{\"out\":1,\"entry\":[false,true],\"bearings\":[0,90],\"location\":[-71.45082724993496,43.070903929852619],\"in\":0},{\"out\":1,\"entry\":[false,true],\"bearings\":[27,90],\"location\":[-71.444301000091471,43.023085298378462],\"in\":0}],\"driving_side\":\"right\",\"weight\":7560.0,\"geometry\":\"mbxcqArekhgCoG{B}HmGuHaLaGiT{#mPHs[bJggEUqYiA_KgCcJyKyVyGgJ\",\"maneuver\":{\"bearing_after\":90,\"type\":\"depart\",\"modifier\":\"\",\"bearing_before\":0,\"location\":[-71.45082724993496,43.070903929852619],\"instruction\":\"Travel on NO NAME\"},\"duration\":0.0,\"distance\":547.06000000000006,\"name\":\"NO NAME\",\"mode\":\"driving\",\"voiceInstructions\":[{\"distanceAlongGeometry\":547.06000000000006,\"announcement\":\"Travel on NO NAME, then Turn right onto US-3 [NH-28], [HOOKSETT RD]\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">Travel on NO NAME, then Turn right onto US-3 [NH-28], [HOOKSETT RD]</prosody></amazon:effect></speak>\"},{\"distanceAlongGeometry\":90.0,\"announcement\":\"Turn right onto US-3 [NH-28], [HOOKSETT RD]\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">Turn right onto US-3 [NH-28], [HOOKSETT RD]</prosody></amazon:effect></speak>\"}],\"bannerInstructions\":[{\"distanceAlongGeometry\":547.06000000000006,\"primary\":{\"text\":\"US-3 / NH-28 / HOOKSETT RD\",\"type\":\"turn\",\"modifier\":\"right\",\"degrees\":0,\"components\":[{\"type\":\"text\",\"text\":\"US-3\",\"delimiter\":false},{\"type\":\"delimiter\",\"text\":\"/\",\"delimiter\":true},{\"type\":\"text\",\"text\":\"NH-28\",\"delimiter\":false},{\"type\":\"delimiter\",\"text\":\"/\",\"delimiter\":true},{\"type\":\"text\",\"text\":\"HOOKSETT RD\",\"delimiter\":false}]},\"secondary\":null}]},{\"intersections\":[{\"out\":1,\"entry\":[false,true],\"bearings\":[27,90],\"location\":[-71.444301000091471,43.023085298378462],\"in\":0},{\"out\":1,\"entry\":[false,true],\"bearings\":[197,211],\"location\":[-71.444535949177578,43.0230007289918],\"in\":0}],\"driving_side\":\"right\",\"weight\":6677.0,\"geometry\":\"}yycqAzk_hgCpLqOrNaNhTqMlfAsm#|\\\\eSb`#{ZvoBinBrKkJ~t#cg#r\\\\wQvrHimDv}Asz#xz#gd#n\\\\}PrpAil#prCmvAhgBa_A|m#qZvPcJlx#{]l_#iN~GuC~VgFpO}#bGEd[zBvo#jJ|cAeHvoCsWn]eJzuAkf#p`#aQ|sBypAzSkKrMsExPmDlUgAzNx#~OrC|NjFvaBp|#h]dMtmAbZb`Bv`#h\\\\fOxpCvtB|SjSrKxNjO`\\\\~FtNzKp_#xI|NrI`JvlHdmG\",\"maneuver\":{\"bearing_after\":90,\"type\":\"turn\",\"modifier\":\"right\",\"bearing_before\":27,\"location\":[-71.444301000091471,43.023085298378462],\"instruction\":\"Turn right onto US-3 [NH-28], [HOOKSETT RD]\"},\"duration\":186.0,\"distance\":5921.12,\"name\":\"US-3\",\"mode\":\"driving\",\"voiceInstructions\":[{\"distanceAlongGeometry\":5792.4000000000005,\"announcement\":\"In 3.6miles, I-93 SB ON RAMP\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">In 3.6miles, I-93 SB ON RAMP</prosody></amazon:effect></speak>\"},{\"distanceAlongGeometry\":90.0,\"announcement\":\"I-93 SB ON RAMP\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">I-93 SB ON RAMP</prosody></amazon:effect></speak>\"}],\"bannerInstructions\":[{\"distanceAlongGeometry\":5921.12,\"primary\":{\"text\":\"I-93 NB EXIT 9 OFF RAMP\",\"type\":\"turn\",\"modifier\":\"straight\",\"degrees\":0,\"components\":[{\"type\":\"text\",\"text\":\"I-93 NB EXIT 9 OFF RAMP\",\"delimiter\":false}]},\"secondary\":null}]},{\"intersections\":[{\"out\":1,\"entry\":[false,true],\"bearings\":[197,211],\"location\":[-71.444535949177578,43.0230007289918],\"in\":0},{\"out\":1,\"entry\":[false,true],\"bearings\":[126,135],\"location\":[-71.2864750743811,42.81703500887609],\"in\":0}],\"driving_side\":\"right\",\"weight\":838.0,\"geometry\":\"im|`qA~srggCfe#`l#lGlLtDpZ]~LoDpReEfJoHbIw`Ajt#mPlEiIQyNcGuFkG_HmUq#}QV{EfB_MfAqDpIaOxtAetA\",\"maneuver\":{\"bearing_after\":211,\"type\":\"turn\",\"modifier\":\"straight\",\"bearing_before\":197,\"location\":[-71.444535949177578,43.0230007289918],\"instruction\":\"I-93 SB ON RAMP\"},\"duration\":23.0,\"distance\":788.41,\"name\":\"I-93 NB EXIT 9 OFF RAMP\",\"mode\":\"driving\",\"voiceInstructions\":[{\"distanceAlongGeometry\":643.6,\"announcement\":\"In 0.4miles, Continue straight on I-93 SOUTH\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">In 0.4miles, Continue straight on I-93 SOUTH</prosody></amazon:effect></speak>\"},{\"distanceAlongGeometry\":90.0,\"announcement\":\"Continue straight on I-93 SOUTH\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">Continue straight on I-93 SOUTH</prosody></amazon:effect></speak>\"}],\"bannerInstructions\":[{\"distanceAlongGeometry\":788.41,\"primary\":{\"text\":\"I-93 SOUTH\",\"type\":\"turn\",\"modifier\":\"straight\",\"degrees\":0,\"components\":[{\"type\":\"text\",\"text\":\"I-93 SOUTH\",\"delimiter\":false}]},\"secondary\":null}]},{\"intersections\":[{\"out\":1,\"entry\":[false,true],\"bearings\":[126,135],\"location\":[-71.2864750743811,42.81703500887609],\"in\":0},{\"out\":1,\"entry\":[false,true],\"bearings\":[136,140],\"location\":[-71.275545391600389,42.809408142172572],\"in\":0}],\"driving_side\":\"right\",\"weight\":27322.0,\"geometry\":\"_h|`qAtbsggCbE}C~FgGbxK_zIloDguC|i#w`#j\\\\mSn\\\\}Pf]aOf`AmYx`#aIjdGmz#nrCqb#rb#}Irs#uSzo#s^x]{ZvZ}_#hO}TzV}f#lMy\\\\tJsZfu#auCxdA}gE`W_z#b_#}zApO_h#pHsRnIoQ`JiQbJ{NpXq]`[sXn\\\\cT`_#eO|c#mMxp#kN|]gIpiAyVho#oLjcBeR`wBmIb{DiQpq#cFl~BuZvmDcf#|a#eF|u#sGdQk#xPgAvc#w#|uDaHz}CsIv{#}Gvr#kR`k#sWvpB{eAjfAij#`o#cZf}#}XvkB{_#ft#_Qtp#qYbXoRzZiZbXm^x`Ak{A`^mk#na#_k#|m#k~#zDsEvF}HzYm[~KqLlLsKrPoLlzAajAx]yZz\\\\c_#xN}Q~MyS~s#{hAzd#ov#hrKetP~n#caA`NyS|J_M|\\\\gb#l\\\\{\\\\n^k[z_#gYfr#ua#bo#sWr_#_Od|Aif#lrAoc#~cCsw#blA}`#riBql#tk#}T`_A_e#pyDgaCvpUauNhlAyp#b}B{fAv`#}TlwH}zCzjK}dEphAki#dj#{[viAuu#l}#ut#xgAifAfpIg~JjcFwbGhSgTh_#s\\\\r]yVfb#wVld#yRxWsJlM{D`tW}kHhvBwo#nl#qXnr#cc#|pAqhAto#g{#tj#k_AlWyi#lUeh#~^sgAr\\\\usAl`#abC~]qxBvU_wAvYoyAnJqb#fT}v#j]ghAd]q{#xSqe#ls#{tAlWoc#dTy[hv#qeAd]o`#nm#{l#r}UouSt}#u{#~z#w_AdcDkfEtmBkfCvZy_#p^sa#l^u]d_#y[haAup#vp#q\\\\|cAgf#|wA_n#xi#w\\\\xm#sYtlHcgDdnAek#nvAko#v~#ic#lx#of#\",\"maneuver\":{\"bearing_after\":135,\"type\":\"turn\",\"modifier\":\"straight\",\"bearing_before\":126,\"location\":[-71.2864750743811,42.81703500887609],\"instruction\":\"Continue straight on I-93 SOUTH\"},\"duration\":803.0,\"distance\":27320.82,\"name\":\"I-93 SOUTH\",\"mode\":\"driving\",\"voiceInstructions\":[{\"distanceAlongGeometry\":25744.0,\"announcement\":\"In 16miles, I-93 SB EXIT 3 OFF RAMP TO NH-111\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">In 16miles, I-93 SB EXIT 3 OFF RAMP TO NH-111</prosody></amazon:effect></speak>\"},{\"distanceAlongGeometry\":90.0,\"announcement\":\"I-93 SB EXIT 3 OFF RAMP TO NH-111\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">I-93 SB EXIT 3 OFF RAMP TO NH-111</prosody></amazon:effect></speak>\"}],\"bannerInstructions\":[]},{\"intersections\":[{\"out\":1,\"entry\":[false,true],\"bearings\":[136,140],\"location\":[-71.275545391600389,42.809408142172572],\"in\":0},{\"out\":1,\"entry\":[false,true],\"bearings\":[90,0],\"location\":[-71.408027396106363,42.771592398141067],\"in\":0}],\"driving_side\":\"right\",\"weight\":1481.0,\"geometry\":\"c_jtpAzk~}fC`o#c]br#}o#~f#eo#n\\\\uh#`e#{_AdZyw#dW_}#lnAcnEz^yrAnBaHhM_\\\\lJgPfKmN|O{KbIgCzQ_D`FpAxC|CjBjKpCn`#\",\"maneuver\":{\"bearing_after\":140,\"type\":\"turn\",\"modifier\":\"straight\",\"bearing_before\":136,\"location\":[-71.275545391600389,42.809408142172572],\"instruction\":\"I-93 SB EXIT 3 OFF RAMP TO NH-111\"},\"duration\":41.0,\"distance\":1383.74,\"name\":\"I-93 I93 S OFF RAMP\",\"mode\":\"driving\",\"voiceInstructions\":[{\"distanceAlongGeometry\":1287.2,\"announcement\":\"In 0.8miles, Merge onto NH-111 [INDIAN ROCK RD]\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">In 0.8miles, Merge onto NH-111 [INDIAN ROCK RD]</prosody></amazon:effect></speak>\"},{\"distanceAlongGeometry\":90.0,\"announcement\":\"Merge onto NH-111 [INDIAN ROCK RD]\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">Merge onto NH-111 [INDIAN ROCK RD]</prosody></amazon:effect></speak>\"}],\"bannerInstructions\":[{\"distanceAlongGeometry\":1383.74,\"primary\":{\"text\":\"NH-111 / INDIAN ROCK RD\",\"type\":\"turn\",\"modifier\":\"straight\",\"degrees\":0,\"components\":[{\"type\":\"text\",\"text\":\"NH-111\",\"delimiter\":false},{\"type\":\"delimiter\",\"text\":\"/\",\"delimiter\":true},{\"type\":\"text\",\"text\":\"INDIAN ROCK RD\",\"delimiter\":false}]},\"secondary\":null}]},{\"intersections\":[{\"out\":1,\"entry\":[false,true],\"bearings\":[90,0],\"location\":[-71.408027396106363,42.771592398141067],\"in\":0}],\"driving_side\":\"right\",\"weight\":20698.0,\"geometry\":\"mb{spAx`i}fCLhi#~CvvAzj#laHlN|u#dyAnwFpIh\\\\tLvo#jM`gAjJ~|Afb#`gHhDfn#rDz`#rH`g#zObt#~Vns#~`#pu#lv#pdAxbBjuBxUj^vIfUtOhc#zSzw#vC`SnIt}#v#lfAuBbj#gDb`#urAlhNcWtlB}dA`rGiuBjjM_UxxA_OtcBuCfl#iB|bACxu#pCdpAl_AfnMzNjoBzIxu#hJfm#`UncApT~p#dc#fbAph#n{#ds#nfAhuBphDhtAnuBthC`eEr{AnnCfkAvwBdwBvvDz[bf#pqA~bBdwB|rCpe#~o#vg#py#f_#zx#h~G~vPhTti#ba#xoAvMnj#ppAbgG~\\\\p|At]zxAt]`pA`f#n}Ap\\\\p`ArdBduEro#|dB`cChrG\",\"maneuver\":{\"bearing_after\":0,\"type\":\"arrive\",\"modifier\":\"\",\"bearing_before\":90,\"location\":[-71.408027396106363,42.771592398141067],\"instruction\":\"Merge onto NH-111 [INDIAN ROCK RD]\"},\"duration\":503.0,\"distance\":12421.48,\"name\":\"NH-111\",\"mode\":\"driving\",\"voiceInstructions\":[{\"distanceAlongGeometry\":12389.300000000001,\"announcement\":\"In 7.7miles, Arrive at destination.\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">In 7.7miles, Arrive at destination.</prosody></amazon:effect></speak>\"},{\"distanceAlongGeometry\":90.0,\"announcement\":\"Arrive at destination.\",\"ssmlAnnouncement\":\"<speak><amazon:effect name=\\\"drc\\\"><prosody rate=\\\"1.08\\\">Arrive at destination.</prosody></amazon:effect></speak>\"}],\"bannerInstructions\":[{\"distanceAlongGeometry\":12421.48,\"primary\":{\"text\":\"NH-111 / CENTRAL ST\",\"type\":\"arrive\",\"modifier\":\"\",\"degrees\":0,\"components\":[{\"type\":\"text\",\"text\":\"NH-111\",\"delimiter\":false},{\"type\":\"delimiter\",\"text\":\"/\",\"delimiter\":true},{\"type\":\"text\",\"text\":\"CENTRAL ST\",\"delimiter\":false}]},\"secondary\":null}]}],\"summary\":\"NO NAME, 1.4mi S of Hooksett - NH-111, 3.1mi NE of Nashua\",\"duration\":1556.0,\"distance\":48366.5390625,\"weight\":66578.0}],\"geometry\":\"mbxcqArekhgCoG{BcOoNyEyKwDgTQif#bJggEUqYiA_KcI{UwNiVdUkX~EgEv{Ae|#`w#yh#`aAu~#tt#{t#rKkJ~t#cg#vr#m^b|BceAze#uTzV{KlhDydB|`Aei#nVyLnuAyp#huHowDhWcN~VqLzt#mZxZeKdP}CtWcAd[zBta#lHvU|#~kEy`#ni#mO|bBin#vPaJ|_Awl#tQcL`WwOzSkKrMsExPmDbPw#hDOzNx#rWjFj_#dQlq#v_#bh#vVb{Ax_#b`Bv`#h\\\\fOzaCbhBr[rXzRdVpIjPxRnh#zElQlOvUxgH`iG|HjGhk#xs#rC`KlBdTkAlT}EfQ{FtIueA|x#mPlEcToCuKqK{EiNwBuRXgLfB_MtDmJfKoNjyAiwAjn#wh#j|JyaIf`DmhC|i#w`#j\\\\mSn\\\\}Pf]aOd_#yLhOyEvOyDx`#aIr\\\\wErlKq|AzdAiYzo#s^x]{ZhLaNvf#it#nV_k#tXs|#zsA}kF~]i{A`W_z#vWofAnNmh#lG_SpHsRnIoQ`JiQdWs_#nKyL`[sXfMwIfNkIbOoG|NuF|c#mMzx#_Q`iA_Wp}#sQnlBoTlZe#nxHk_#ffAiK~hAuPvmDcf#zs#eI~c#sD~b#sBvrHqMtXeCzhBsJvr#kRlcG}{CxO_Hr^_Mr]}Jt_#kIbpBoa#~^_Ln_#mQtK}Gth#_f#|o#_`A`hAgfBrvAorBhn#mq#lLsKt|#_q#jn#qe#hv#ct#~J}LrnHgiLvuE}kH`~#}uAzh#gp#l\\\\{\\\\n^k[z_#gYfr#ua#bo#sWr_#_OroDyjAv{HcgCtk#}T`_A_e#|hOcjJl_D{nBd_CswA~a#oXlWwNhe#mZtn#e^flAsm#vb#mSnkAkl#dhMccFh`HyqCxz#cd#zdAcq#`uAifAv}Ae~AthOirQhi#al#h_#s\\\\r]yVfb#wVld#yRxWsJriRskFx_AaWtdDu~#thAe^nl#qX`i#g\\\\|a#yZlw#ss#vWe\\\\zr#}eAd_#ws#pl#exAfj#cpBd[uiBl[qqBx`#caCnH}`#rTaeAxTa}#rY{`Ap\\\\g~#zUkj#lPg]zj#mfAlWoc#fl#s{#`m#qv#z|#q}#feP_oNluA_nA|`BovAt}#u{#~z#w_Axc#{j#j~BozCd}A}rBnOmRtE{Frs#qz#ln#uk#dOyMhaAup#tuBycA|wA_n#xi#w\\\\xmBg|#~dNcqGrWoO|MgJ`o#c]br#}o#zu#ecAn^}o#db#c`AlZ}~#jxAoiFjb#{{AdCsHbIkRrDgG`QmWhKyHvRmHzL{A`FpAxC|CjBjKpCn`#Lhi#~CvvA`b#foFxGdq#lN|u#lv#`xCrZjjAtPjp#nE`VjPpfApNdwBfb#`gH|IbpA~CzWlMdo#`FbSzM`a#bHlQpSna#~]dj#nhAtxAd_AbjAxUj^lDvI~Txn#zSzw#`H|f#xFfbAPx_#cChx#kTjbCqbAdfKqg#zoDyV`|Aab#tgCox#p`Fsp#xzDyZ|pBeGnl#oKlcBuBzyAhAbpA`F~eAzz#dgLzNjoBzIxu#hJfm#`UncApT~p#dc#fbAjsG|eKhlCdgEp[xj#~iCjyEziCxsEz[bf#||#~iAjeDhlEfTpZn_#rn#f_#zx#jmH`uQlM|\\\\|Xn~#zW~iAj`#`lBjXppA|z#bzDbk#jvBhs#v{B|tBnxFzmA~eDbOr`#ds#djBlPvb#fz#~~Bgi#e|A\",\"duration\":1556.0,\"distance\":48366.54,\"weight\":66578.0,\"weight_name\":\"routability\",\"voiceLocale\":\"en-US\"}],\"waypoints\":[{\"name\":\"NO NAME, 1.4mi S of Hooksett\",\"location\":[-71.45688,43.07003]},{\"name\":\"NH-111, 3.1mi NE of Nashua\",\"location\":[-71.40803,42.77159]}],\"code\":\"Ok\",\"uuid\":\"cjqsavmw70crz3po391gqh3mp\"}";
DirectionsResponse directions = DirectionsResponse.fromJson(jsonRoute);
DirectionsRoute route = directions.routes().get(0);
ArrayList<Point> wpPoints = new ArrayList<Point>();
for(DirectionsWaypoint w : directions.waypoints())
wpPoints.add((w.location()));
RouteOptions newRO = RouteOptions.builder()
.profile(DirectionsCriteria.PROFILE_DRIVING)
.coordinates(wpPoints)
.user("mapbox")
.geometries(DirectionsCriteria.GEOMETRY_POLYLINE6)
.accessToken(accessToken)
.requestUuid(directions.uuid())
.baseUrl("https://api.mapbox.com")
.waypointNames("")
.continueStraight(true)
.annotations("distance")
.approaches("")
.bearings(";")
.alternatives(false)
.language("en")
.radiuses("")
.voiceInstructions(true)
.bannerInstructions(true)
.roundaboutExits(true)
.overview("full")
.steps(true)
.voiceUnits("imperial")
.exclude("")
.waypointTargets("")
.build();
route = route.toBuilder().routeOptions(newRO).build();
boolean simulateRoute = false;
// Create a NavigationLauncherOptions object to package everything together
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(route)
.shouldSimulateRoute(simulateRoute)
.build();
// Call this method with Context from within an Activity
NavigationLauncher.startNavigation(this, options);

#Troy Berg Let me take a quick second to explain how the route following code works internally when a fresh route is loaded.
Upon loading a new route, if the route json is valid, the MapboxNavigator will start in the INITIALIZED state. From there it will attempt to gain confidence that the GPS locations being passed in are actually the location where the user is. To establish this trust it needs to receive at least a few location updates and those must be consequtively coherent in both time and space. While it's in the process of establishing this trust it will report the INITIALIZED state.
Once trust of the users current stream of location updates has been established, the MapboxNavigator will attempt to measure the user's progress along the currently loaded route. If the user's location is found to be unreasonably far from the route itself, the state is flipped to the OFFROUTE state.
If the user's current location is within a reasonable distance from the currently loaded route but not close enough to be considered on-route (TRACKING) we will continue to return the INITIALIZED state and wait for the user to make their way to the route. We call this corraling. Corraling allows a user, in his/her driveway or a store's parking lot for example, to load up a route and not immediately get marked as OFFROUTE. While corraling, if the user continually makes progress away from the route they will eventually be marked OFFROUTE.

I went ahead and just set my own offRouteEngine. I kept the original, though, and reference that in mine. The code is:
MapboxNavigation mbn = navigationView.retrieveMapboxNavigation();
orEngine = (OffRouteDetector)mbn.getOffRouteEngine();
mbn.setOffRouteEngine(new OffRouteDetector() {
#Override
public boolean isUserOffRoute(Location location, RouteProgress routeProgress, MapboxNavigationOptions options) {
Boolean isOffRoute = orEngine.isUserOffRoute(location, routeProgress, options);
// User will never be off-route
return isOffRoute;
}
public boolean isUserOffRouteWith(NavigationStatus status) {
return orEngine.isUserOffRouteWith(status) || status.getRouteState() == RouteState.INITIALIZED;
}
});
In that code, I'm counting the "INITIALIZED" state as off route. As I do not reroute but, instead, show a message, I think this should work out ok.
Please let me know if you see any issues with this method and thanks for your help!

Related

My Roblox Studio script is sometimes having errors.. idk why

So.. I've been coding to make a GUI show the quantity of currency of a player, the datastore API works perfectly but the local script doesn't (it's local because else it would just update it each time a player's currency gets updated and would be a mess being the opposite of what I want to)
and well... sometimes it loads the currency into the GUI but other times it just stays on the original text: "Label" instead of my current currency (4600)
here's the proof
What normally happens and should always happen
What sometimes happens and shouldn't happen:
here's the script, I've tried putting waits on the start but the original code is inside the while true do..
wait(game.Players.LocalPlayer:WaitForChild("Data")
wait(game.Players.LocalPlayer.Data:WaitForChild("Bells"))
while true do
script.Parent.TextLabel.Text = game.Players.LocalPlayer:WaitForChild("Data"):WaitForChild("Bells").Value
wait() --wait is for not making the loop break and stop the whole script
end
well.. if you want to see if data is really in the player, here's the script, it requires a API (DataStore2)
--[Animal Crossing Roblox Edition Data Store]--
--Bryan99354--
--Module not mine--
--Made with a AlvinBlox tutorial--
--·.·.*[Get Data Store, do not erase]*.·.·--
local DataStore2 = require(1936396537)
--[Default Values]--
local DefaultValue_Bells = 300
local DefaultValue_CustomClothes = 0
--[Data Store Functions]--
game.Players.PlayerAdded:Connect(function(player)
--[Data stores]--
local BellsDataStore = DataStore2("Bells",player)
local Data = Instance.new("Folder",player)
Data.Name = "Data"
Bells = Instance.new("IntValue",Data)
Bells.Name = "Bells"
local CustomClothesDataStore = DataStore2("CustomClothes",player)
local CustomClothes = Instance.new("IntValue",Data)
CustomClothes.Name = "CustomClothes"
local function CustomClothesUpdate(UpdatedValue)
CustomClothes.Value = CustomClothesDataStore:Get(UpdatedValue)
end
local function BellsUpdate(UpdatedValue)
Bells.Value = BellsDataStore:Get(UpdatedValue)
end
BellsUpdate(DefaultValue_Bells)
CustomClothesUpdate(DefaultValue_CustomClothes)
BellsDataStore:OnUpdate(BellsUpdate)
CustomClothesDataStore:OnUpdate(CustomClothesUpdate)
end)
--[test and reference functions]--
workspace.TestDevPointGiver.ClickDetector.MouseClick:Connect(function(player)
local BellsDataStore = DataStore2("Bells",player)
BellsDataStore:Increment(50,DefaultValue_Bells)
end)
workspace.TestDevCustomClothesGiver.ClickDetector.MouseClick:Connect(function(player)
local CustomClothesDataStore = DataStore2("CustomClothes",player)
CustomClothesDataStore:Increment(50,DefaultValue_CustomClothes)
end)
the code that creates "Data" and "Bells" is located in the comment: Data Stores
the only script that gets the issue is the short one with no reason :<
I hope that you can help me :3
#Night94 I tryed your script but it also failed sometimes
The syntax in your LocalScript is a little off with the waits. With that fixed, it works every time. Also, I would use an event handler instead of updating the value with a loop:
game.Players.LocalPlayer:WaitForChild("Data"):WaitForChild("Bells").Changed:Connect(function(value)
script.Parent.TextLabel.Text = value
end)

Enabling Closed-Display Mode w/o Meeting Apple's Requirements

EDIT:
I have heavily edited this question after making some significant new discoveries and the question not having any answers yet.
Historically/AFAIK, keeping your Mac awake while in closed-display mode and not meeting Apple's requirements, has only been possible with a kernel extension (kext), or a command run as root. Recently however, I have discovered that there must be another way. I could really use some help figuring out how to get this working for use in a (100% free, no IAP) sandboxed Mac App Store (MAS) compatible app.
I have confirmed that some other MAS apps are able to do this, and it looks like they might be writing YES to a key named clamshellSleepDisabled. Or perhaps there's some other trickery involved that causes the key value to be set to YES? I found the function in IOPMrootDomain.cpp:
void IOPMrootDomain::setDisableClamShellSleep( bool val )
{
if (gIOPMWorkLoop->inGate() == false) {
gIOPMWorkLoop->runAction(
OSMemberFunctionCast(IOWorkLoop::Action, this, &IOPMrootDomain::setDisableClamShellSleep),
(OSObject *)this,
(void *)val);
return;
}
else {
DLOG("setDisableClamShellSleep(%x)\n", (uint32_t) val);
if ( clamshellSleepDisabled != val )
{
clamshellSleepDisabled = val;
// If clamshellSleepDisabled is reset to 0, reevaluate if
// system need to go to sleep due to clamshell state
if ( !clamshellSleepDisabled && clamshellClosed)
handlePowerNotification(kLocalEvalClamshellCommand);
}
}
}
I'd like to give this a try and see if that's all it takes, but I don't really have any idea about how to go about calling this function. It's certainly not a part of the IOPMrootDomain documentation, and I can't seem to find any helpful example code for functions that are in the IOPMrootDomain documentation, such as setAggressiveness or setPMAssertionLevel. Here's some evidence of what's going on behind the scenes according to Console:
I've had a tiny bit of experience working with IOMProotDomain via adapting some of ControlPlane's source for another project, but I'm at a loss for how to get started on this. Any help would be greatly appreciated. Thank you!
EDIT:
With #pmdj's contribution/answer, this has been solved!
Full example project:
https://github.com/x74353/CDMManager
This ended up being surprisingly simple/straightforward:
1. Import header:
#import <IOKit/pwr_mgt/IOPMLib.h>
2. Add this function in your implementation file:
IOReturn RootDomain_SetDisableClamShellSleep (io_connect_t root_domain_connection, bool disable)
{
uint32_t num_outputs = 0;
uint32_t input_count = 1;
uint64_t input[input_count];
input[0] = (uint64_t) { disable ? 1 : 0 };
return IOConnectCallScalarMethod(root_domain_connection, kPMSetClamshellSleepState, input, input_count, NULL, &num_outputs);
}
3. Use the following to call the above function from somewhere else in your implementation:
io_connect_t connection = IO_OBJECT_NULL;
io_service_t pmRootDomain = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPMrootDomain"));
IOServiceOpen (pmRootDomain, current_task(), 0, &connection);
// 'enable' is a bool you should assign a YES or NO value to prior to making this call
RootDomain_SetDisableClamShellSleep(connection, enable);
IOServiceClose(connection);
I have no personal experience with the PM root domain, but I do have extensive experience with IOKit, so here goes:
You want IOPMrootDomain::setDisableClamShellSleep() to be called.
A code search for sites calling setDisableClamShellSleep() quickly reveals a location in RootDomainUserClient::externalMethod(), in the file iokit/Kernel/RootDomainUserClient.cpp. This is certainly promising, as externalMethod() is what gets called in response to user space programs calling the IOConnectCall*() family of functions.
Let's dig in:
IOReturn RootDomainUserClient::externalMethod(
uint32_t selector,
IOExternalMethodArguments * arguments,
IOExternalMethodDispatch * dispatch __unused,
OSObject * target __unused,
void * reference __unused )
{
IOReturn ret = kIOReturnBadArgument;
switch (selector)
{
…
…
…
case kPMSetClamshellSleepState:
fOwner->setDisableClamShellSleep(arguments->scalarInput[0] ? true : false);
ret = kIOReturnSuccess;
break;
…
So, to invoke setDisableClamShellSleep() you'll need to:
Open a user client connection to IOPMrootDomain. This looks straightforward, because:
Upon inspection, IOPMrootDomain has an IOUserClientClass property of RootDomainUserClient, so IOServiceOpen() from user space will by default create an RootDomainUserClient instance.
IOPMrootDomain does not override the newUserClient member function, so there are no access controls there.
RootDomainUserClient::initWithTask() does not appear to place any restrictions (e.g. root user, code signing) on the connecting user space process.
So it should simply be a case of running this code in your program:
io_connect_t connection = IO_OBJECT_NULL;
IOReturn ret = IOServiceOpen(
root_domain_service,
current_task(),
0, // user client type, ignored
&connection);
Call the appropriate external method.
From the code excerpt earlier on, we know that the selector must be kPMSetClamshellSleepState.
arguments->scalarInput[0] being zero will call setDisableClamShellSleep(false), while a nonzero value will call setDisableClamShellSleep(true).
This amounts to:
IOReturn RootDomain_SetDisableClamShellSleep(io_connect_t root_domain_connection, bool disable)
{
uint32_t num_outputs = 0;
uint64_t inputs[] = { disable ? 1 : 0 };
return IOConnectCallScalarMethod(
root_domain_connection, kPMSetClamshellSleepState,
&inputs, 1, // 1 = length of array 'inputs'
NULL, &num_outputs);
}
When you're done with your io_connect_t handle, don't forget to IOServiceClose() it.
This should let you toggle clamshell sleep on or off. Note that there does not appear to be any provision for automatically resetting the value to its original state, so if your program crashes or exits without cleaning up after itself, whatever state was last set will remain. This might not be great from a user experience perspective, so perhaps try to defend against it somehow, for example in a crash handler.

SNMPv3 not in time window

I try to query a Cisco SMB (small business switch) to read its hostname.
My code returns "not in time window (1.3.6.1.6.3.15.1.1.2.0).
Net-Snmp works fine. The difference I found using wireshark is that net-snmp sets msgAuthorativeEngineTime after it receives not in time window error.
Discovery discovery = Messenger.GetNextDiscovery(SnmpType.GetRequestPdu);
ReportMessage report = discovery.GetResponse(60000, new IPEndPoint(IPAddress.Parse("10.105.9.10"), 161));
OctetString username = new OctetString("test");
var auth = new SHA1AuthenticationProvider(new OctetString("Testtest123!"));
var priv = new DESPrivacyProvider(new OctetString("Testtest123!"), auth);
// read switch hostname
GetRequestMessage request = new GetRequestMessage(VersionCode.V3, Messenger.NextMessageId, Messenger.NextRequestId, username, new List<Variable> { new Variable(new ObjectIdentifier("1.3.6.1.2.1.1.5.0")) }, priv, Messenger.MaxMessageSize, report);
ISnmpMessage reply = request.GetResponse(60000, router); (not in time window)
Please find a wireshark screenshot of sharp-snmp:
And net-snmp:
Thank you for your help!
According to the snmpget sample (updated link here), you have to call two times the GetRequestMessage method. Be aware that the code uses the report variable in the first call, then the reply one in the latter, otherwise it will not work (= not in time window message) (I lost half a day to get this!)

ContainerLaunchContext.setResource() missing of hadoop yarn

http://hadoop.apache.org/docs/r2.1.0-beta/hadoop-yarn/hadoop-yarn-site/WritingYarnApplications.html
I am try to make the example work well from the above link.but I can't compile the code below
Resource capability = Records.newRecord(Resource.class);
capability.setMemory(512);
amContainer.setResource(capability);
// Set the container launch content into the
// ApplicationSubmissionContext
appContext.setAMContainerSpec(amContainer);
amContainer is ContainerLaunchContext and my hadoop version is 2.1.0-beta.
I did some investigation. I found there's no method "setResource" in ContainerLaunchContext
I have 3 question about this
1) the method has been removed or something?
2) if the method has been removed, how can I do now?
3) is there any doc about yarn, because I found the doc in website is very easy, I hope I can get a manual or something. for example,
capability.setMemory(512);
I don't know it's 512k or 512M according comments in code.
This is actually proper solution to the question. Previous answer might cause incorrect execution !!!
#Dyin I couldn't fit it in the comment ;) Validated for 2.2.0 and 2.3.0
Driver setting up resources for AppMaster:
ApplicationSubmissionContext appContext = app.getApplicationSubmissionContext();
ApplicationId appId = appContext.getApplicationId();
appContext.setApplicationName(this.appName);
// Set up the container launch context for the application master
ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);
Resource capability = Records.newRecord(Resource.class);
capability.setMemory(amMemory);
appContext.setResource(capability);
appContext.setAMContainerSpec(amContainer);
Priority pri = Records.newRecord(Priority.class);
pri.setPriority(amPriority);
appContext.setPriority(pri);
appContext.setQueue(amQueue);
// Submit the application to the applications manager
yarnClient.submitApplication(appContext); // this.yarnClient = YarnClient.createYarnClient();
In ApplicationMaster this is how you should specify resources for containers (workers).
private AMRMClient.ContainerRequest setupContainerAskForRM() {
// setup requirements for hosts
// using * as any host will do for the distributed shell app
// set the priority for the request
Priority pri = Records.newRecord(Priority.class);
pri.setPriority(requestPriority);
// Set up resource type requirements
// For now, only memory is supported so we set memory requirements
Resource capability = Records.newRecord(Resource.class);
capability.setMemory(containerMemory);
AMRMClient.ContainerRequest request = new AMRMClient.ContainerRequest(capability, null, null,
pri);
return request;
}
Some run() or main() method in your AppMaster
AMRMClientAsync.CallbackHandler allocListener = new RMCallbackHandler();
resourceManager = AMRMClientAsync.createAMRMClientAsync(1000, allocListener);
resourceManager.init(conf);
resourceManager.start();
for (int i = 0; i < numTotalContainers; ++i) {
AMRMClient.ContainerRequest containerAsk = setupContainerAskForRM();
resourceManager.addContainerRequest(containerAsk); //
}
Launching containers
You can use the original answer solution (java cmd), but it's just a cherry on top. It should work anyway.
You can set memory available to ApplicationMaster via commend. As such:
// Set the necessary command to execute the application master
Vector<CharSequence> vargs = new Vector<CharSequence>(30);
...
vargs.add("-Xmx" + amMemory + "m"); // notice "m" indicating megabytes, you can use also -Xms combined with -Xmx
... // transform vargs to String commands
amContainer.setCommands(commands);
This should solve your problem. As for the 3 questions. Yarn is rapidly evolving software. My advice forget documentation, get source code and read it. This will answer a lot of your questions.

application working with smart card readers vs RDP and switching users

one windows application works with smart card readers. It has cycle like that:
do{
lErr = SCardListReaders( hContext, ... );
if ( lErr != SCARD_S_SUCCESS )
return 1;
//Show readers
}while(!stop)
i.e. it gets current list of readers, than shows it.
The problem is that this does not work correct with RDP connection. Let's suppose we have computer A (COMP_A) with smart card reader A (READER_A), computer B (COMP_B) with reader B (READER_B). The application is launched on COMP_A and shows READER_A in the list of readers. Then we connect from COMP_B to COMP_A via RDP. Correct result of this must be that there is READER_B in the list. But the application "crashes" because SCardListReaders returns SCARD_E_SERVICE_STOPPED.
Some goggling gave answer that we need to re-establish context. So new version of cycle:
do{
lErr = SCardListReaders( hContext, ... );
if ( lErr == SCARD_E_SERVICE_STOPPED )
{
SCardReleaseContext( hContext );
//Sleep(10000)
SCardEstablishContext( ..., &hContext );
lErr = SCardListReaders( hContext, ... );
}
if ( lErr != SCARD_S_SUCCESS )
return 1;
//Show readers
}while(!stop)
It does not work, SCardListReaders returns READER_A in the list. I suppose because new SCardEstablishContext ends before RDP connection is finally set. At least if Sleep is uncommented it works correct.
The similar situation with user switching, i.e. SCardListReaders returns SCARD_E_SERVICE_STOPPED when user chooses "switch user".
The question is how to make correct code? How to determine that this is RDP connection or user switching? How to re-establish scard context?
Actually i made some changes which use WTSQuerySessionInformation function with WTSClientProtocolType parameter. I wait when WTSClientProtocolType = 2 and then call SCardEstablishContext. But i am not sure this is correct and also it is not correct for switch user.

Resources