11package com.bugsnag.android
22
3+ import android.os.Build
4+ import android.os.SystemClock
35import androidx.annotation.VisibleForTesting
46import java.io.File
57import java.io.IOException
68import java.io.Reader
9+ import java.lang.Thread
10+ import java.util.concurrent.TimeUnit
11+ import kotlin.math.min
712
813/* *
914 * Attempts to detect whether the device is rooted. Root detection errs on the side of false
@@ -21,6 +26,9 @@ internal class RootDetector @JvmOverloads constructor(
2126) {
2227
2328 companion object {
29+ private const val PROCESS_TIMEOUT = 250L
30+ private const val PROCESS_POLL_DELAY = 50L
31+
2432 private val BUILD_PROP_FILE = File (" /system/build.prop" )
2533
2634 private val ROOT_INDICATORS = listOf (
@@ -120,7 +128,20 @@ internal class RootDetector @JvmOverloads constructor(
120128 var process: Process ? = null
121129 return try {
122130 process = processBuilder.start()
131+ val processComplete = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
132+ process.waitFor(PROCESS_TIMEOUT , TimeUnit .MILLISECONDS )
133+ } else {
134+ process.fallbackWaitFor(PROCESS_TIMEOUT )
135+ }
136+
137+ if (! processComplete) {
138+ return false
139+ }
140+
123141 process.inputStream.bufferedReader().use { it.isNotBlank() }
142+ } catch (ignored: InterruptedException ) {
143+ Thread .currentThread().interrupt() // restore the interrupted status
144+ false
124145 } catch (ignored: IOException ) {
125146 false
126147 } finally {
@@ -147,4 +168,19 @@ internal class RootDetector @JvmOverloads constructor(
147168 libraryLoaded -> performNativeRootChecks()
148169 else -> false
149170 }
171+
172+ private fun Process.fallbackWaitFor (timeout : Long ): Boolean {
173+ val endTime = SystemClock .elapsedRealtime() + timeout
174+ while (SystemClock .elapsedRealtime() < endTime) {
175+ try {
176+ exitValue()
177+ return true
178+ } catch (ex: IllegalThreadStateException ) {
179+ // Process is still running, wait a bit before checking again
180+ Thread .sleep(min(PROCESS_POLL_DELAY , endTime - SystemClock .elapsedRealtime()))
181+ }
182+ }
183+
184+ return false
185+ }
150186}
0 commit comments