OLD | NEW |
1 # coding=utf-8 | 1 # coding=utf-8 |
2 # Copyright 2015 Google Inc. All rights reserved. | 2 # Copyright 2015 Google Inc. All rights reserved. |
3 # | 3 # |
4 # Licensed under the Apache License, Version 2.0 (the "License"); | 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
5 # you may not use this file except in compliance with the License. | 5 # you may not use this file except in compliance with the License. |
6 # You may obtain a copy of the License at | 6 # You may obtain a copy of the License at |
7 # | 7 # |
8 # http://www.apache.org/licenses/LICENSE-2.0 | 8 # http://www.apache.org/licenses/LICENSE-2.0 |
9 # | 9 # |
10 # Unless required by applicable law or agreed to in writing, software | 10 # Unless required by applicable law or agreed to in writing, software |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 if not exit_code: | 824 if not exit_code: |
825 return True | 825 return True |
826 _LOG.info('%s: %s', cmd, out) | 826 _LOG.info('%s: %s', cmd, out) |
827 return False | 827 return False |
828 | 828 |
829 def GetApplicationPath(self, package): | 829 def GetApplicationPath(self, package): |
830 # TODO(maruel): Test. | 830 # TODO(maruel): Test. |
831 out, _ = self.Shell('pm path %s' % pipes.quote(package)) | 831 out, _ = self.Shell('pm path %s' % pipes.quote(package)) |
832 return out.strip().split(':', 1)[1] if out else out | 832 return out.strip().split(':', 1)[1] if out else out |
833 | 833 |
834 def IsFullyBooted(self): | 834 def IsFullyBooted(self, skip_sd_card=False): |
835 """Checks whether the device is fully booted. | 835 """Checks whether the device is fully booted. |
836 | 836 |
| 837 Args: |
| 838 - skip_sd_card: Skips checking if the external storage is ready if True. |
| 839 Some devices lack an internal sd card and permanently |
| 840 fail this check. |
837 Returns: | 841 Returns: |
838 tuple(booted, status) | 842 tuple(booted, status) |
839 - booted: True if device is fully booted, false otherwise. | 843 - booted: True if device is fully booted, false otherwise. |
840 - status: If not booted, string describing why. | 844 - status: If not booted, string describing why. |
841 """ | 845 """ |
842 if not self.cache.external_storage_path: | 846 if not skip_sd_card: |
843 return False, 'external storage not ready' | 847 if not self.cache.external_storage_path: |
844 if self.Stat(self.cache.external_storage_path)[0] is None: | 848 return False, 'external storage not ready' |
845 return False, 'external storage not ready' | 849 if self.Stat(self.cache.external_storage_path)[0] is None: |
| 850 return False, 'external storage not ready' |
846 | 851 |
847 # Check if the boot animation has stopped. | 852 # Check if the boot animation has stopped. |
848 prop = self.GetProp('init.svc.bootanim') | 853 prop = self.GetProp('init.svc.bootanim') |
849 if prop is None: | 854 if prop is None: |
850 return False, 'could not get init.svc.bootanim property' | 855 return False, 'could not get init.svc.bootanim property' |
851 elif prop != 'stopped': | 856 elif prop != 'stopped': |
852 return False, 'boot animation still running' | 857 return False, 'boot animation still running' |
853 | 858 |
854 # pm can be very slow at times. Use a longer timeout to prevent | 859 # pm can be very slow at times. Use a longer timeout to prevent |
855 # confusing a long-running command with an interrupted connection. | 860 # confusing a long-running command with an interrupted connection. |
856 out, exit_code = self.Shell('pm path', timeout_ms=30000) | 861 out, exit_code = self.Shell('pm path', timeout_ms=30000) |
857 if out != 'Error: no package specified\n': | 862 if out != 'Error: no package specified\n': |
858 # Accepts an empty string too, which has been observed only on Android 4.4 | 863 # Accepts an empty string too, which has been observed only on Android 4.4 |
859 # (Kitkat) but not on later versions. | 864 # (Kitkat) but not on later versions. |
860 if out not in ( | 865 if out not in ( |
861 'Error: Could not access the Package Manager. Is the system ' | 866 'Error: Could not access the Package Manager. Is the system ' |
862 'running?\n', | 867 'running?\n', |
863 ''): | 868 ''): |
864 logging.warning( | 869 logging.warning( |
865 'Unexpected reply from pm path (%d): %r', exit_code, out) | 870 'Unexpected reply from pm path (%d): %r', exit_code, out) |
866 return False, 'pm not ready' | 871 return False, 'pm not ready' |
867 | 872 |
868 # All checks passed. | 873 # All checks passed. |
869 return True, None | 874 return True, None |
870 | 875 |
871 def WaitUntilFullyBooted(self, timeout=300): | 876 def WaitUntilFullyBooted(self, timeout=300, **kwargs): |
872 """Waits for the device to be fully started up with network connectivity. | 877 """Waits for the device to be fully started up with network connectivity. |
873 | 878 |
874 Arguments: | 879 Arguments: |
875 - timeout: minimum amount of time to wait for for the device to come up | 880 - timeout: minimum amount of time to wait for for the device to come up |
876 online. It may extend to up to lock_timeout_ms more. | 881 online. It may extend to up to lock_timeout_ms more. |
877 """ | 882 """ |
878 start = time.time() | 883 start = time.time() |
879 while True: | 884 while True: |
880 is_booted, status = self.IsFullyBooted() | 885 is_booted, status = self.IsFullyBooted(**kwargs) |
881 if is_booted: | 886 if is_booted: |
882 return True | 887 return True |
883 if (time.time() - start) > timeout: | 888 if (time.time() - start) > timeout: |
884 _LOG.warning( | 889 _LOG.warning( |
885 '%s.WaitUntilFullyBooted() timed out due to %s', | 890 '%s.WaitUntilFullyBooted() timed out due to %s', |
886 self.port_path, status) | 891 self.port_path, status) |
887 return False | 892 return False |
888 time.sleep(1) | 893 time.sleep(1) |
889 | 894 |
890 def PushKeys(self): | 895 def PushKeys(self): |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 return out | 986 return out |
982 | 987 |
983 @classmethod | 988 @classmethod |
984 def _Connect(cls, constructor, **kwargs): | 989 def _Connect(cls, constructor, **kwargs): |
985 """Called by either ConnectDevice or Connect.""" | 990 """Called by either ConnectDevice or Connect.""" |
986 if not kwargs.get('rsa_keys'): | 991 if not kwargs.get('rsa_keys'): |
987 with _ADB_KEYS_LOCK: | 992 with _ADB_KEYS_LOCK: |
988 kwargs['rsa_keys'] = _ADB_KEYS[:] | 993 kwargs['rsa_keys'] = _ADB_KEYS[:] |
989 device = constructor(**kwargs) | 994 device = constructor(**kwargs) |
990 return HighDevice(device, _InitCache(device)) | 995 return HighDevice(device, _InitCache(device)) |
OLD | NEW |