Use self.is_adb_detectable() to prevent build_info from None even it is not in bootloader. (#923)

diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
index 20c5762..866f50b 100644
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -844,7 +844,7 @@
 
   @property
   def is_rootable(self):
-    return not self.is_bootloader and self.build_info['debuggable'] == '1'
+    return self.is_adb_detectable() and self.build_info['debuggable'] == '1'
 
   @functools.cached_property
   def model(self):
diff --git a/tests/lib/mock_android_device.py b/tests/lib/mock_android_device.py
index c383c18..923c8c8 100755
--- a/tests/lib/mock_android_device.py
+++ b/tests/lib/mock_android_device.py
@@ -87,6 +87,7 @@
       mock_properties=None,
       installed_packages=None,
       instrumented_packages=None,
+      adb_detectable=True,
   ):
     self.serial = serial
     self.fail_br = fail_br
@@ -101,6 +102,7 @@
     self.installed_packages = installed_packages
     if instrumented_packages is None:
       instrumented_packages = []
+    self.adb_detectable = adb_detectable
     self.installed_packages = installed_packages
     self.instrumented_packages = instrumented_packages
 
@@ -154,6 +156,12 @@
     if expected not in args:
       raise Error('"Expected "%s", got "%s"' % (expected, args))
 
+  def devices(self):
+    out = b'xxxx\tdevice\nyyyy\tdevice'
+    if self.adb_detectable:
+      out += f'\n{self.serial}\tdevice'.encode()
+    return out
+
   def __getattr__(self, name):
     """All calls to the none-existent functions in adb proxy would
     simply return the adb command string.
diff --git a/tests/mobly/controllers/android_device_lib/services/logcat_test.py b/tests/mobly/controllers/android_device_lib/services/logcat_test.py
index 3f10cad..ebf4919 100755
--- a/tests/mobly/controllers/android_device_lib/services/logcat_test.py
+++ b/tests/mobly/controllers/android_device_lib/services/logcat_test.py
@@ -149,7 +149,7 @@
 
   @mock.patch(
       'mobly.controllers.android_device_lib.adb.AdbProxy',
-      return_value=mock_android_device.MockAdbProxy('1'),
+      return_value=mock_android_device.MockAdbProxy('1', adb_detectable=False),
   )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
@@ -457,6 +457,7 @@
   def test__enable_logpersist_with_logpersist(self, MockFastboot, MockAdbProxy):
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
+    mock_adb_proxy.devices.return_value = f'{mock_serial}\tdevice'.encode()
     mock_adb_proxy.getprops.return_value = {
         'ro.build.id': 'AB42',
         'ro.build.type': 'userdebug',
@@ -489,6 +490,7 @@
   ):
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
+    mock_adb_proxy.devices.return_value = f'{mock_serial}\tdevice'.encode()
     mock_adb_proxy.getprops.return_value = {
         'ro.build.id': 'AB42',
         'ro.build.type': 'user',
@@ -524,6 +526,7 @@
 
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
+    mock_adb_proxy.devices.return_value = f'{mock_serial}\tdevice'.encode()
     mock_adb_proxy.getprops.return_value = {
         'ro.build.id': 'AB42',
         'ro.build.type': 'userdebug',
@@ -558,6 +561,7 @@
 
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
+    mock_adb_proxy.devices.return_value = f'{mock_serial}\tdevice'.encode()
     mock_adb_proxy.getprops.return_value = {
         'ro.build.id': 'AB42',
         'ro.build.type': 'userdebug',
@@ -596,6 +600,7 @@
 
     mock_serial = '1'
     mock_adb_proxy = MockAdbProxy.return_value
+    mock_adb_proxy.devices.return_value = f'{mock_serial}\tdevice'.encode()
     mock_adb_proxy.getprops.return_value = {
         'ro.build.id': 'AB42',
         'ro.build.type': 'userdebug',
@@ -611,7 +616,10 @@
     logcat_service._enable_logpersist()
     mock_adb_proxy.shell.assert_not_called()
 
-  @mock.patch('mobly.controllers.android_device_lib.adb.AdbProxy')
+  @mock.patch(
+      'mobly.controllers.android_device_lib.adb.AdbProxy',
+      return_value=mock_android_device.MockAdbProxy('1'),
+  )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',
       return_value=mock_android_device.MockFastbootProxy('1'),
diff --git a/tests/mobly/controllers/android_device_test.py b/tests/mobly/controllers/android_device_test.py
index 81c2965..68fcfe4 100755
--- a/tests/mobly/controllers/android_device_test.py
+++ b/tests/mobly/controllers/android_device_test.py
@@ -717,7 +717,7 @@
 
   @mock.patch(
       'mobly.controllers.android_device_lib.adb.AdbProxy',
-      return_value=mock_android_device.MockAdbProxy('1'),
+      return_value=mock_android_device.MockAdbProxy('1', adb_detectable=False),
   )
   @mock.patch(
       'mobly.controllers.android_device_lib.fastboot.FastbootProxy',