-
-
Notifications
You must be signed in to change notification settings - Fork 169
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
Fix: Restart ADB server when devices go offline #443
Conversation
@imurchie @mykola-mokhnach this is the cause of the ADB CI flakiness:
The device goes offline when we retry as root and then fail to unroot. |
I'm going to try restarting ADB whenever |
This is what happens when it passes
Doesn't fail to unroot |
Changes pushed and CI passing (Azure at least). Any more comments will be addressed tomorrow. |
lib/tools/adb-commands.js
Outdated
@@ -1456,19 +1460,26 @@ methods.getDeviceProperty = async function getDeviceProperty (property) { | |||
return val; | |||
}; | |||
|
|||
/** | |||
* @typedef {object} setPropOpts | |||
* @property {boolean} privileged - Do we run setProp as a privileged command? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true by default
lib/tools/system-calls.js
Outdated
} catch (err) { | ||
log.warn(`Cannot run adbd as non-root. Original error: ${err.message}`); | ||
} | ||
log.info(`Call to '${cmd}' completed. Returning device to original unrooted state.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this log line seems redundant to me
// Do not show the warning for real devices, where root is locked | ||
log.warn(`Cannot run adbd as root. Original error: ${err.message}`); | ||
} | ||
log.info(`'adb shell ${cmd}' requires root access. Attempting to gain root access now.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.debug
lib/tools/system-calls.js
Outdated
return {isSuccessful: true, wasAlreadyRooted: isRoot}; | ||
} | ||
|
||
let wasAlreadyRooted = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
= isRoot
lib/tools/system-calls.js
Outdated
throw new Error(stdout.trim()); | ||
if (stdout) { | ||
if (stdout.includes('adbd cannot run as root')) { | ||
log.warn('Cannot run device as root'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can skip this log at all otherwise it will appear too often on real devices
// If it's already rooted, our job is done. No need to root it again. | ||
const isRoot = await this.isRoot(); | ||
if ((isRoot && isElevated) || (!isRoot && !isElevated)) { | ||
return {isSuccessful: true, wasAlreadyRooted: isRoot}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
lib/tools/system-calls.js
Outdated
// Check the output of the stdErr to see if there's any clues that show that the device went offline | ||
// and if it did go offline, restart ADB | ||
const s = stderr.toLowerCase(); | ||
if (s.includes('closed') || s.includes('device offline')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
['closed', 'device offline'].some((x) => stderr.toLowerCase().includes(x))
lib/tools/system-calls.js
Outdated
* @property {boolean} isSuccessful True if the call to root/unroot was successful | ||
* @property {boolean} wasAlreadyRooted True if the device was already rooted | ||
*/ | ||
|
||
/** | ||
* Switch adb server to root mode. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the description
lib/tools/adb-commands.js
Outdated
@@ -1301,7 +1304,8 @@ methods.killProcessByPID = async function killProcessByPID (pid) { | |||
} | |||
log.info(`Cannot kill PID ${pid} due to insufficient permissions. Retrying as root`); | |||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try block is now redundant, since root call is not going to throw an exception
lib/tools/system-calls.js
Outdated
} | ||
log.info(`Call to '${cmd}' completed. Returning device to original unrooted state.`); | ||
const {isSuccessful} = await this.unroot(); | ||
log.info(isSuccessful ? 'Returned device to unrooted state' : 'Could not return device to unrooted state'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.debug
lib/tools/system-calls.js
Outdated
// Stop and re-start the device | ||
await this.shell(['stop']); | ||
await B.delay(2000); // let the emu finish stopping; | ||
await this.setDeviceProperty('sys.boot_completed', 0, {privileged: false}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a comment about why privileged is set to false would be useful here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments. Otherwise looks good
This addresses two problems:
adb root/unroot
1. works intermittently, 2. sometimes cases the device to go offline.The fix is:
root/unroot
instead of calling it just oncerestartAdbIfDevicesOffline ()
This PR also: