From ab99e77ef3c1a58f19597b0c34c93bd6dc56a1f3 Mon Sep 17 00:00:00 2001 From: Jeff Irion Date: Fri, 18 Oct 2019 08:06:54 -0700 Subject: [PATCH] Add documentation, Makefile, and linting configuration Documentation and linting More linting and documentation usb_exceptions.py and the sign_*.py files pass linting checks More linting and documentation More linting and documentation pylint: ignore too-few-public-methods Spacing Linting Linting Documentation Linting Create .readthedocs.yml Create requirements.txt Add documentation link to README Update README.rst Update README.rst Update README.rst Update .gitignore Add call graphs pylint and flake8 pass Documentation Documentation fixes Add my Travis CI and Coveralls badges (#2) Add some tables of contents to the documentation Add linting to CI (#3) * Add linting to CI * Install flake8 and pylint Hide the original repo's badges (for now) (#4) Finish documentation skeletons for the sign_* files and usb_exceptions.py (#5) Finish documentation skeletons for fastboot.py and fastboot_debug.py (#6) Almost done with documentation skeletons Finish documentation skeletons Add contents to module docstrings Working on documentation contents Finish adding contents to module docstrings Replace sections with rubrics Document the sign_* modules and usb_exceptions.py Remove whitespace Fix typo Add tests for the signers Change 'ValueError' to more general 'Exception' Added tests for the 'GetPublicKey()' methods Add ADB keygen functionality (from @joeleong) Fix sign_* tests Add debugging code, work on documentation of filesync_protocol.py Working on documentation Remove debugging code Fill in some documentation Documentation and code formatting Add some documentation More documentation Put command onto one line Linting Linting Update documentation index.rst Remove CHECKLIST.md --- .flake8 | 2 + .gitignore | 19 +- .pylintrc | 582 +++++++++++++ .readthedocs.yml | 19 + .travis.yml | 4 +- Makefile | 23 + README.rst | 171 ++++ adb/adb_commands.py | 567 +++++++++---- adb/adb_debug.py | 194 +++-- adb/adb_keygen.py | 247 ++++++ adb/adb_protocol.py | 773 ++++++++++++++---- adb/common.py | 602 ++++++++++++-- adb/common_cli.py | 186 ++++- adb/debug.py | 23 + adb/fastboot.py | 614 ++++++++++---- adb/fastboot_debug.py | 84 +- adb/filesync_protocol.py | 338 +++++++- adb/sign_cryptography.py | 61 +- adb/sign_pycryptodome.py | 65 +- adb/sign_pythonrsa.py | 155 +++- adb/usb_exceptions.py | 100 ++- docs/Makefile | 20 + docs/make.bat | 36 + docs/requirements.txt | 1 + ...db.adb_commands.AdbCommands.CALL_GRAPH.svg | 28 + ...ommands.AdbCommands.Close.CALLER_GRAPH.svg | 32 + ..._commands.AdbCommands.Close.CALL_GRAPH.svg | 47 ++ ...s.AdbCommands.ConnectDevice.CALL_GRAPH.svg | 33 + ...mmands.AdbCommands.GetState.CALL_GRAPH.svg | 70 ++ ...mands.AdbCommands.Install.CALLER_GRAPH.svg | 33 + ...ommands.AdbCommands.Install.CALL_GRAPH.svg | 56 ++ ...dbCommands.InteractiveShell.CALL_GRAPH.svg | 33 + ...commands.AdbCommands.Logcat.CALL_GRAPH.svg | 33 + ...commands.AdbCommands.Push.CALLER_GRAPH.svg | 51 ++ ...b_commands.AdbCommands.Push.CALL_GRAPH.svg | 37 + ...mmands.AdbCommands.Reboot.CALLER_GRAPH.svg | 33 + ...dbCommands.RebootBootloader.CALL_GRAPH.svg | 33 + ...ommands.AdbCommands.Shell.CALLER_GRAPH.svg | 84 ++ ...commands.AdbCommands.Stat.CALLER_GRAPH.svg | 32 + ...dbCommands.StreamingShell.CALLER_GRAPH.svg | 33 + ...mands.AdbCommands.Uninstall.CALL_GRAPH.svg | 33 + ...ands.AdbCommands._Connect.CALLER_GRAPH.svg | 33 + ...ands.AdbCommands.__init__.CALLER_GRAPH.svg | 74 ++ ...mands.AdbCommands.__reset.CALLER_GRAPH.svg | 46 ++ ...ommands.AdbCommands.__reset.CALL_GRAPH.svg | 33 + ...s._get_service_connection.CALLER_GRAPH.svg | 33 + .../adb.adb_debug.Devices.CALLER_GRAPH.svg | 31 + .../_static/adb.adb_debug.main.CALL_GRAPH.svg | 31 + ...adb.adb_protocol.AdbMessage.CALL_GRAPH.svg | 28 + ...Message.CalculateChecksum.CALLER_GRAPH.svg | 140 ++++ ...protocol.AdbMessage.Command.CALL_GRAPH.svg | 87 ++ ...protocol.AdbMessage.Connect.CALL_GRAPH.svg | 60 ++ ...age.InteractiveShellCommand.CALL_GRAPH.svg | 33 + ..._protocol.AdbMessage.Open.CALLER_GRAPH.svg | 46 ++ ...db_protocol.AdbMessage.Open.CALL_GRAPH.svg | 59 ++ ..._protocol.AdbMessage.Pack.CALLER_GRAPH.svg | 31 + ...db_protocol.AdbMessage.Pack.CALL_GRAPH.svg | 45 + ..._protocol.AdbMessage.Read.CALLER_GRAPH.svg | 87 ++ ...db_protocol.AdbMessage.Read.CALL_GRAPH.svg | 46 ++ ...db_protocol.AdbMessage.Send.CALL_GRAPH.svg | 58 ++ ...bMessage.StreamingCommand.CALLER_GRAPH.svg | 33 + ...AdbMessage.StreamingCommand.CALL_GRAPH.svg | 73 ++ ...rotocol.AdbMessage.Unpack.CALLER_GRAPH.svg | 101 +++ ...tocol.AdbMessage.__init__.CALLER_GRAPH.svg | 33 + ...tocol.AdbMessage.checksum.CALLER_GRAPH.svg | 44 + ...rotocol.AdbMessage.checksum.CALL_GRAPH.svg | 32 + ...adb.adb_protocol.AuthSigner.CALL_GRAPH.svg | 28 + ...otocol.InterleavedDataError.CALL_GRAPH.svg | 29 + ...otocol.InvalidChecksumError.CALL_GRAPH.svg | 29 + ...rotocol.InvalidCommandError.CALL_GRAPH.svg | 29 + ...alidCommandError.__init__.CALLER_GRAPH.svg | 33 + ...otocol.InvalidResponseError.CALL_GRAPH.svg | 29 + ...adb_protocol._AdbConnection.CALL_GRAPH.svg | 28 + ...ocol._AdbConnection.Close.CALLER_GRAPH.svg | 32 + ...otocol._AdbConnection.Close.CALL_GRAPH.svg | 64 ++ ...tocol._AdbConnection.Okay.CALLER_GRAPH.svg | 87 ++ ...rotocol._AdbConnection.Okay.CALL_GRAPH.svg | 31 + ...._AdbConnection.ReadUntil.CALLER_GRAPH.svg | 74 ++ ...ol._AdbConnection.ReadUntil.CALL_GRAPH.svg | 45 + ...dbConnection.ReadUntilClose.CALL_GRAPH.svg | 64 ++ ...otocol._AdbConnection.Write.CALL_GRAPH.svg | 64 ++ ...ocol._AdbConnection._Send.CALLER_GRAPH.svg | 115 +++ ...l._AdbConnection.__init__.CALLER_GRAPH.svg | 33 + ...tocol.find_backspace_runs.CALLER_GRAPH.svg | 33 + .../adb.common.GetInterface.CALLER_GRAPH.svg | 31 + ...adb.common.InterfaceMatcher.CALL_GRAPH.svg | 31 + ...b.common.TcpHandle.BulkRead.CALL_GRAPH.svg | 58 ++ ....common.TcpHandle.BulkWrite.CALL_GRAPH.svg | 87 ++ .../adb.common.TcpHandle.CALL_GRAPH.svg | 28 + ....common.TcpHandle.Timeout.CALLER_GRAPH.svg | 73 ++ ....TcpHandle.TimeoutSeconds.CALLER_GRAPH.svg | 60 ++ ...on.TcpHandle.TimeoutSeconds.CALL_GRAPH.svg | 45 + ...common.TcpHandle.__init__.CALLER_GRAPH.svg | 33 + ...b.common.TcpHandle._connect.CALL_GRAPH.svg | 59 ++ ...n.TcpHandle.serial_number.CALLER_GRAPH.svg | 33 + ...common.UsbHandle.BulkRead.CALLER_GRAPH.svg | 32 + ...b.common.UsbHandle.BulkRead.CALL_GRAPH.svg | 58 ++ ....common.UsbHandle.BulkWrite.CALL_GRAPH.svg | 59 ++ .../adb.common.UsbHandle.CALL_GRAPH.svg | 28 + ...db.common.UsbHandle.Close.CALLER_GRAPH.svg | 31 + .../adb.common.UsbHandle.Close.CALL_GRAPH.svg | 45 + ...adb.common.UsbHandle.Find.CALLER_GRAPH.svg | 51 ++ .../adb.common.UsbHandle.Find.CALL_GRAPH.svg | 93 +++ ...mon.UsbHandle.FindAndOpen.CALLER_GRAPH.svg | 51 ++ ...ommon.UsbHandle.FindAndOpen.CALL_GRAPH.svg | 93 +++ ...mon.UsbHandle.FindDevices.CALLER_GRAPH.svg | 79 ++ ...ommon.UsbHandle.FindFirst.CALLER_GRAPH.svg | 65 ++ ....common.UsbHandle.FindFirst.CALL_GRAPH.svg | 33 + ...mmon.UsbHandle.FlushBuffers.CALL_GRAPH.svg | 72 ++ .../adb.common.UsbHandle.Open.CALL_GRAPH.svg | 172 ++++ ...UsbHandle.PortPathMatcher.CALLER_GRAPH.svg | 65 ++ ...n.UsbHandle.SerialMatcher.CALLER_GRAPH.svg | 51 ++ ...mon.UsbHandle.SerialMatcher.CALL_GRAPH.svg | 93 +++ ....common.UsbHandle.Timeout.CALLER_GRAPH.svg | 114 +++ ...common.UsbHandle.__init__.CALLER_GRAPH.svg | 33 + ...ommon.UsbHandle.port_path.CALLER_GRAPH.svg | 31 + ...n.UsbHandle.serial_number.CALLER_GRAPH.svg | 113 +++ ...common.UsbHandle.usb_info.CALLER_GRAPH.svg | 85 ++ ...b.common.UsbHandle.usb_info.CALL_GRAPH.svg | 32 + ...db.common_cli.MakeSubparser.CALL_GRAPH.svg | 31 + ...db.common_cli.PositionalArg.CALL_GRAPH.svg | 28 + .../adb.common_cli.StartCli.CALL_GRAPH.svg | 31 + ...adb.common_cli._DocToArgs.CALLER_GRAPH.svg | 31 + ....common_cli._PortPathAction.CALL_GRAPH.svg | 29 + ...adb.common_cli._RunMethod.CALLER_GRAPH.svg | 31 + ...b.fastboot.FastbootCommands.CALL_GRAPH.svg | 28 + ...t.FastbootCommands.Continue.CALL_GRAPH.svg | 80 ++ ...FastbootCommands.Download.CALLER_GRAPH.svg | 149 ++++ ...boot.FastbootCommands.Erase.CALL_GRAPH.svg | 80 ++ ...ot.FastbootCommands.Flash.CALLER_GRAPH.svg | 135 +++ ...boot.FastbootCommands.Flash.CALL_GRAPH.svg | 66 ++ ...ootCommands.FlashFromFile.CALLER_GRAPH.svg | 135 +++ ...tbootCommands.FlashFromFile.CALL_GRAPH.svg | 66 ++ ...oot.FastbootCommands.Getvar.CALL_GRAPH.svg | 80 ++ ...stboot.FastbootCommands.Oem.CALL_GRAPH.svg | 79 ++ ...oot.FastbootCommands.Reboot.CALL_GRAPH.svg | 80 ++ ...otCommands.RebootBootloader.CALL_GRAPH.svg | 80 ++ ...otCommands._SimpleCommand.CALLER_GRAPH.svg | 135 +++ ...bootCommands._SimpleCommand.CALL_GRAPH.svg | 66 ++ ...FastbootCommands.__init__.CALLER_GRAPH.svg | 33 + ...ot.FastbootCommands.__reset.CALL_GRAPH.svg | 131 +++ ...oot.FastbootInvalidResponse.CALL_GRAPH.svg | 51 ++ ...b.fastboot.FastbootProtocol.CALL_GRAPH.svg | 28 + ...rotocol.HandleDataSending.CALLER_GRAPH.svg | 47 ++ ...tProtocol.HandleDataSending.CALL_GRAPH.svg | 61 ++ ...col.HandleSimpleResponses.CALLER_GRAPH.svg | 33 + ...tocol.HandleSimpleResponses.CALL_GRAPH.svg | 80 ++ ...astbootProtocol.SendCommand.CALL_GRAPH.svg | 99 +++ ...Protocol._AcceptResponses.CALLER_GRAPH.svg | 66 ++ ...tProtocol._HandleProgress.CALLER_GRAPH.svg | 132 +++ ...t.FastbootProtocol._Write.CALLER_GRAPH.svg | 66 ++ ...oot.FastbootProtocol._Write.CALL_GRAPH.svg | 33 + ...FastbootProtocol.__init__.CALLER_GRAPH.svg | 33 + ...tboot.FastbootRemoteFailure.CALL_GRAPH.svg | 51 ++ ...tboot.FastbootStateMismatch.CALL_GRAPH.svg | 51 ++ ...tboot.FastbootTransferError.CALL_GRAPH.svg | 51 ++ ...db.fastboot_debug.Devices.CALLER_GRAPH.svg | 31 + .../adb.fastboot_debug.main.CALL_GRAPH.svg | 31 + ...protocol.FileSyncConnection.CALL_GRAPH.svg | 29 + ...l.FileSyncConnection.Read.CALLER_GRAPH.svg | 33 + ...col.FileSyncConnection.Read.CALL_GRAPH.svg | 47 ++ ...ileSyncConnection.ReadUntil.CALL_GRAPH.svg | 102 +++ ...col.FileSyncConnection.Send.CALL_GRAPH.svg | 47 ++ ...ction._CanAddToSendBuffer.CALLER_GRAPH.svg | 33 + ...FileSyncConnection._Flush.CALLER_GRAPH.svg | 61 ++ ...cConnection._ReadBuffered.CALLER_GRAPH.svg | 47 ++ ...c_protocol.FilesyncProtocol.CALL_GRAPH.svg | 29 + ...tocol.FilesyncProtocol.Pull.CALL_GRAPH.svg | 98 +++ ...col.FilesyncProtocol.Push.CALLER_GRAPH.svg | 52 ++ ...tocol.FilesyncProtocol.Push.CALL_GRAPH.svg | 52 ++ ...col.FilesyncProtocol.Stat.CALLER_GRAPH.svg | 33 + ...cProtocol._HandleProgress.CALLER_GRAPH.svg | 52 ++ ...yncProtocol._HandleProgress.CALL_GRAPH.svg | 52 ++ ...otocol.InterleavedDataError.CALL_GRAPH.svg | 29 + ...otocol.InvalidChecksumError.CALL_GRAPH.svg | 29 + ...nc_protocol.PullFailedError.CALL_GRAPH.svg | 29 + ...nc_protocol.PushFailedError.CALL_GRAPH.svg | 29 + ...tography.CryptographySigner.CALL_GRAPH.svg | 39 + ...dome.PycryptodomeAuthSigner.CALL_GRAPH.svg | 39 + ...n_pythonrsa.PythonRSASigner.CALL_GRAPH.svg | 39 + .../adb.sign_pythonrsa._Accum.CALL_GRAPH.svg | 29 + ....AdbCommandFailureException.CALL_GRAPH.svg | 29 + ...tions.AdbOperationException.CALL_GRAPH.svg | 29 + ...b_exceptions.CommonUsbError.CALL_GRAPH.svg | 29 + ..._exceptions.DeviceAuthError.CALL_GRAPH.svg | 51 ++ ...eptions.DeviceNotFoundError.CALL_GRAPH.svg | 51 ++ ...ssageWithArgumentsException.CALL_GRAPH.svg | 117 +++ ...eptions.LibusbWrappingError.CALL_GRAPH.svg | 62 ++ ..._exceptions.ReadFailedError.CALL_GRAPH.svg | 51 ++ ...eptions.TcpTimeoutException.CALL_GRAPH.svg | 51 ++ ...exceptions.WriteFailedError.CALL_GRAPH.svg | 51 ++ docs/source/adb.adb_commands.rst | 7 + docs/source/adb.adb_debug.rst | 7 + docs/source/adb.adb_keygen.rst | 7 + docs/source/adb.adb_protocol.rst | 7 + docs/source/adb.common.rst | 7 + docs/source/adb.common_cli.rst | 7 + docs/source/adb.debug.rst | 7 + docs/source/adb.fastboot.rst | 7 + docs/source/adb.fastboot_debug.rst | 7 + docs/source/adb.filesync_protocol.rst | 7 + docs/source/adb.rst | 30 + docs/source/adb.sign_cryptography.rst | 7 + docs/source/adb.sign_pycryptodome.rst | 7 + docs/source/adb.sign_pythonrsa.rst | 7 + docs/source/adb.usb_exceptions.rst | 7 + docs/source/conf.py | 182 +++++ docs/source/index.rst | 25 + docs/source/modules.rst | 7 + setup.py | 4 +- test/__init__.py | 4 + test/adb_keygen_stub.py | 29 + test/test_adb_protocol.py | 315 +++++++ test/test_sign_cryptography.py | 29 + test/test_sign_pycryptodome.py | 28 + test/test_sign_pythonrsa.py | 28 + tox.ini | 3 + 217 files changed, 13938 insertions(+), 810 deletions(-) create mode 100644 .flake8 create mode 100644 .pylintrc create mode 100644 .readthedocs.yml create mode 100644 Makefile create mode 100644 README.rst create mode 100644 adb/adb_keygen.py create mode 100644 adb/debug.py create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/requirements.txt create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Close.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Close.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.ConnectDevice.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.GetState.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Install.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Install.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.InteractiveShell.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Logcat.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Push.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Push.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Reboot.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.RebootBootloader.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Shell.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Stat.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.StreamingShell.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.Uninstall.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands._Connect.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_commands.AdbCommands._get_service_connection.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_debug.Devices.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_debug.main.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.CalculateChecksum.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Command.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Connect.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.InteractiveShellCommand.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Send.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.Unpack.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.AuthSigner.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.InterleavedDataError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.InvalidChecksumError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.InvalidCommandError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.InvalidCommandError.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.InvalidResponseError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntilClose.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.Write.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection._Send.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol._AdbConnection.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.adb_protocol.find_backspace_runs.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.GetInterface.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.InterfaceMatcher.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.BulkRead.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.BulkWrite.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.Timeout.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle._connect.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.TcpHandle.serial_number.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.BulkRead.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.BulkRead.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.BulkWrite.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.Close.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.Close.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.Find.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.Find.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.FindDevices.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.FindFirst.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.FindFirst.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.FlushBuffers.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.Open.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.PortPathMatcher.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.Timeout.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.port_path.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.serial_number.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.usb_info.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common.UsbHandle.usb_info.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common_cli.MakeSubparser.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common_cli.PositionalArg.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common_cli.StartCli.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common_cli._DocToArgs.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.common_cli._PortPathAction.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.common_cli._RunMethod.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Continue.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Download.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Erase.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Getvar.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Oem.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.Reboot.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.RebootBootloader.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootCommands.__reset.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootInvalidResponse.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.SendCommand.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol._AcceptResponses.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol._HandleProgress.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootProtocol.__init__.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootRemoteFailure.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootStateMismatch.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot.FastbootTransferError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot_debug.Devices.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.fastboot_debug.main.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection.ReadUntil.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection.Send.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection._CanAddToSendBuffer.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection._Flush.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FileSyncConnection._ReadBuffered.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Pull.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Stat.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALLER_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.InterleavedDataError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.InvalidChecksumError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.PullFailedError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.filesync_protocol.PushFailedError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.sign_cryptography.CryptographySigner.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.sign_pycryptodome.PycryptodomeAuthSigner.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.sign_pythonrsa.PythonRSASigner.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.sign_pythonrsa._Accum.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.AdbCommandFailureException.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.AdbOperationException.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.CommonUsbError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.DeviceAuthError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.DeviceNotFoundError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.FormatMessageWithArgumentsException.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.LibusbWrappingError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.ReadFailedError.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.TcpTimeoutException.CALL_GRAPH.svg create mode 100644 docs/source/_static/adb.usb_exceptions.WriteFailedError.CALL_GRAPH.svg create mode 100644 docs/source/adb.adb_commands.rst create mode 100644 docs/source/adb.adb_debug.rst create mode 100644 docs/source/adb.adb_keygen.rst create mode 100644 docs/source/adb.adb_protocol.rst create mode 100644 docs/source/adb.common.rst create mode 100644 docs/source/adb.common_cli.rst create mode 100644 docs/source/adb.debug.rst create mode 100644 docs/source/adb.fastboot.rst create mode 100644 docs/source/adb.fastboot_debug.rst create mode 100644 docs/source/adb.filesync_protocol.rst create mode 100644 docs/source/adb.rst create mode 100644 docs/source/adb.sign_cryptography.rst create mode 100644 docs/source/adb.sign_pycryptodome.rst create mode 100644 docs/source/adb.sign_pythonrsa.rst create mode 100644 docs/source/adb.usb_exceptions.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst create mode 100644 docs/source/modules.rst create mode 100644 test/__init__.py create mode 100644 test/adb_keygen_stub.py create mode 100755 test/test_adb_protocol.py create mode 100644 test/test_sign_cryptography.py create mode 100644 test/test_sign_pycryptodome.py create mode 100644 test/test_sign_pythonrsa.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..af375ad --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +ignore = E501,W504 diff --git a/.gitignore b/.gitignore index e92aa58..a3ddfb2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,20 @@ *.pyc +*.DS_Store* + .cache/ -.coverage -adb.egg-info/ +.eggs/ +.idea/ .tox/ +adb.egg-info/ +build/ +dist/ +htmlcov/ + +.coverage /adb.zip /fastboot.zip -.idea/ -*.DS_Store* \ No newline at end of file + +# Documentation +docs/build +docs/html +docs/source/_static/*.dot diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..df82692 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,582 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + deprecated-operator-function, + deprecated-urllib-function, + xreadlines-attribute, + deprecated-sys-function, + exception-escape, + comprehension-escape, + line-too-long, + duplicate-code, + fixme, + too-few-public-methods, + too-many-arguments, + too-many-branches, + too-many-instance-attributes, + too-many-locals, + too-many-statements, + invalid-name, + import-error, + useless-object-inheritance + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[LOGGING] + +# Format style used to check logging format string. `old` means using % +# formatting, while `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[STRING] + +# This flag controls whether the implicit-str-concat-in-sequence should +# generate a warning on implicit string concatenation in sequences defined over +# several lines. +check-str-concat-over-line-jumps=no + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package.. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement. +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "BaseException, Exception". +overgeneral-exceptions=BaseException, + Exception diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..b168698 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,19 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +formats: all + +# Optionally set the version of Python and requirements required to build your docs +python: + version: 3.7 + install: + - requirements: docs/requirements.txt diff --git a/.travis.yml b/.travis.yml index 2de6a3f..82c14e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,13 +18,13 @@ cache: - $HOME/.cache/pip install: - - pip install tox coveralls + - pip install tox coveralls flake8 pylint env: - TOXENV=py36 - TOXENV=py27 -script: tox +script: flake8 adb/ && pylint adb/ && tox after_success: - coveralls diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..727e9db --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +.PHONY: release +release: + rm -rf dist + python setup.py sdist bdist_wheel + twine upload dist/* + +.PHONY: docs +docs: + @cd docs/source && rm -f adb*.rst && mkdir -p _static + @cd docs && sphinx-apidoc -f -e -o source/ ../adb/ + @cd docs && make html && make html + +.PHONY: coverage +coverage: + coverage run --source adb setup.py test && coverage html && coverage report -m + +.PHONY: lint +lint: + flake8 adb/ && pylint adb/ + +.PHONY: alltests +alltests: + flake8 adb/ && pylint adb/ && coverage run --source adb setup.py test && coverage report -m diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..38005a2 --- /dev/null +++ b/README.rst @@ -0,0 +1,171 @@ +python-adb +========== + + +.. image:: https://coveralls.io/repos/github/google/python-adb/badge.svg?branch=master + :target: https://coveralls.io/github/google/python-adb?branch=master + :alt: Coverage Status + +.. image:: https://travis-ci.org/google/python-adb.svg?branch=master + :target: https://travis-ci.org/google/python-adb + :alt: Build Status + + +**Documentation:** https://python-adb.readthedocs.io/ + +Note: This is not an official Google project. It is maintained by ex-Google engineers. +For a better maintained option, look at `adb\_shell `_. + +This repository contains a pure-python implementation of the ADB and Fastboot +protocols, using libusb1 for USB communications. + +This is a complete replacement and rearchitecture of the Android project's +`ADB and fastboot code `_. + +This code is mainly targeted to users that need to communicate with Android +devices in an automated fashion, such as in automated testing. It does not have +a daemon between the client and the device, and therefore does not support +multiple simultaneous commands to the same device. It does support any number of +devices and *never* communicates with a device that it wasn't intended to, +unlike the Android project's ADB. + + +Using as standalone tool +------------------------ + +Install using pip: + +.. code-block:: bash + + pip install adb + + +Once installed, two new binaries should be available: ``pyadb`` and ``pyfastboot``. + +.. code-block:: bash + + pyadb devices + pyadb shell ls /sdcard + + +Running ``./make_tools.py`` creates two files: ``adb.zip`` and ``fastboot.zip``. They +can be run similar to native ``adb`` and ``fastboot`` via the python interpreter: + +.. code-block:: bash + + python adb.zip devices + python adb.zip shell ls /sdcard + + +Using as a Python Library +------------------------- + +A `presentation was made at PyCon 2016 `_, +and here's some demo code: + +.. code-block:: python + + import os.path as op + + from adb import adb_commands + from adb import sign_cryptography + + + # KitKat+ devices require authentication + signer = sign_cryptography.CryptographySigner( + op.expanduser('~/.android/adbkey')) + # Connect to the device + device = adb_commands.AdbCommands() + device.ConnectDevice( + rsa_keys=[signer]) + # Now we can use Shell, Pull, Push, etc! + for i in xrange(10): + print device.Shell('echo %d' % i) + + +Pros +---- + +* Simpler code due to use of libusb1 and Python. +* API can be used by other Python code easily. +* Errors are propagated with tracebacks, helping debug connectivity issues. +* No daemon outliving the command. +* Can be packaged as standalone zips that can be run independent of the CPU + architecture (e.g. x86 vs ARM). + + +Cons +---- + +* Technically slower due to Python, mitigated by no daemon. +* Only one command per device at a time. +* More dependencies than Android's ADB. + + +Dependencies +------------ + +* libusb1 (1.0.16+) +* python-libusb1 (1.2.0+) +* **adb.zip**: one of + + * py-cryptography + * python-rsa (3.2+) + +* **fastboot.zip** (optional) + + * python-progressbar (2.3+) + + +History +------- + +1.0.0 +***** + +* Initial version + + +1.1.0 +***** + +* Added TcpHandle (jameyhicks) +* Various timing and other changes (alusco) + + +1.2.0 +***** + +* Update to libusb1 1.6+ (bytearray output) +* Add support for Python 3.6 +* Create adb.zip and fastboot.zip as executable tools. +* Add Travis CI integration +* Support multiple crypto libraries (M2Crypto + python-rsa) +* Push directories + + +1.3.0 +***** + +Backwards Incompatible changes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``adb_commands.AdbCommands`` is now a normal class rather than a collection of staticmethods. Using the following example code to get started: + +.. code-block:: python + + device = adb_commands.AdbCommands() + device.ConnectDevice(rsa_keys=[signer]) + + +Other changes/fixes +^^^^^^^^^^^^^^^^^^^ + +Many changes since 1.2.0! + +* New entrypoints exposed by pip: pyadb and pyfastboot +* Lots of Python 2/3 compatibility fixes +* Windows compatibility fixes +* Transfer progress available (``Push``, ``Pull``, ``Install``) +* Handle some misbehaving devices (double CLSE bug) +* New options for ``Push`` and ``Install`` (``st_mode`` and ``grant_permissions``) diff --git a/adb/adb_commands.py b/adb/adb_commands.py index 734e31c..9a34102 100644 --- a/adb/adb_commands.py +++ b/adb/adb_commands.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """A libusb1-based ADB reimplementation. ADB was giving us trouble with its client/server architecture, which is great @@ -20,6 +21,36 @@ subprocess and a network socket. All timeouts are in milliseconds. + + +.. rubric:: Contents + +* :class:`AdbCommands` + + * :meth:`AdbCommands.__reset` + * :meth:`AdbCommands._Connect` + * :meth:`AdbCommands._get_service_connection` + * :meth:`AdbCommands.Close` + * :meth:`AdbCommands.ConnectDevice` + * :meth:`AdbCommands.Devices` + * :meth:`AdbCommands.DisableVerity` + * :meth:`AdbCommands.EnableVerity` + * :meth:`AdbCommands.GetState` + * :meth:`AdbCommands.Install` + * :meth:`AdbCommands.InteractiveShell` + * :meth:`AdbCommands.List` + * :meth:`AdbCommands.Logcat` + * :meth:`AdbCommands.Pull` + * :meth:`AdbCommands.Push` + * :meth:`AdbCommands.Reboot` + * :meth:`AdbCommands.RebootBootloader` + * :meth:`AdbCommands.Remount` + * :meth:`AdbCommands.Root` + * :meth:`AdbCommands.Shell` + * :meth:`AdbCommands.Stat` + * :meth:`AdbCommands.StreamingShell` + * :meth:`AdbCommands.Uninstall` + """ import io @@ -31,53 +62,90 @@ from adb import common from adb import filesync_protocol -# From adb.h +try: + file_types = (file, io.IOBase) +except NameError: + file_types = (io.IOBase,) + + +#: From adb.h CLASS = 0xFF + +#: From adb.h SUBCLASS = 0x42 + +#: From adb.h PROTOCOL = 0x01 -# pylint: disable=invalid-name -DeviceIsAvailable = common.InterfaceMatcher(CLASS, SUBCLASS, PROTOCOL) -try: - # Imported locally to keep compatibility with previous code. - from adb.sign_cryptography import CryptographySigner -except ImportError: - # Ignore this error when cryptography is not installed, there are other options. - pass +#: From adb.h +DeviceIsAvailable = common.InterfaceMatcher(CLASS, SUBCLASS, PROTOCOL) class AdbCommands(object): """Exposes adb-like methods for use. Some methods are more-pythonic and/or have more options. + + .. image:: _static/adb.adb_commands.AdbCommands.__init__.CALLER_GRAPH.svg + + Attributes + ---------- + build_props : TODO, None + TODO + filesync_handler : filesync_protocol.FilesyncProtocol + TODO + protocol_handler : adb_protocol.AdbMessage + TODO + _device_state : TODO, None + TODO + _handle : adb.common.TcpHandle, adb.common.UsbHandle, None + TODO + _service_connections : dict + [TODO] Connection table tracks each open AdbConnection objects per service type for program functions that + choose to persist an AdbConnection object for their functionality, using :func:`AdbCommands._get_service_connection` + """ protocol_handler = adb_protocol.AdbMessage filesync_handler = filesync_protocol.FilesyncProtocol def __init__(self): - - self.__reset() - - def __reset(self): self.build_props = None - self._handle = None self._device_state = None - - # Connection table tracks each open AdbConnection objects per service type for program functions - # that choose to persist an AdbConnection object for their functionality, using - # self._get_service_connection + self._handle = None self._service_connections = {} - def _get_service_connection(self, service, service_command=None, create=True, timeout_ms=None): - """ - Based on the service, get the AdbConnection for that service or create one if it doesnt exist + def __reset(self): + """TODO + + .. image:: _static/adb.adb_commands.AdbCommands.__reset.CALL_GRAPH.svg + + .. image:: _static/adb.adb_commands.AdbCommands.__reset.CALLER_GRAPH.svg - :param service: - :param service_command: Additional service parameters to append - :param create: If False, dont create a connection if it does not exist - :return: """ + self.__init__() + def _get_service_connection(self, service, service_command=None, create=True, timeout_ms=None): + """Based on the service, get the AdbConnection for that service or create one if it doesnt exist + + .. image:: _static/adb.adb_commands.AdbCommands._get_service_connection.CALLER_GRAPH.svg + + Parameters + ---------- + service : TODO + TODO + service_command : TODO, None + Additional service parameters to append + create : bool + If False, don't create a connection if it does not exist + timeout_ms : int, None + TODO + + Returns + ------- + connection : TODO + TODO + + """ connection = self._service_connections.get(service, None) if connection: @@ -91,40 +159,50 @@ def _get_service_connection(self, service, service_command=None, create=True, ti else: destination_str = service - connection = self.protocol_handler.Open( - self._handle, destination=destination_str, timeout_ms=timeout_ms) + connection = self.protocol_handler.Open(self._handle, destination=destination_str, timeout_ms=timeout_ms) self._service_connections.update({service: connection}) return connection def ConnectDevice(self, port_path=None, serial=None, default_timeout_ms=None, **kwargs): - """Convenience function to setup a transport handle for the adb device from - usb path or serial then connect to it. - - Args: - port_path: The filename of usb port to use. - serial: The serial number of the device to use. - default_timeout_ms: The default timeout in milliseconds to use. - kwargs: handle: Device handle to use (instance of common.TcpHandle or common.UsbHandle) - banner: Connection banner to pass to the remote device - rsa_keys: List of AuthSigner subclass instances to be used for - authentication. The device can either accept one of these via the Sign - method, or we will send the result of GetPublicKey from the first one - if the device doesn't accept any of them. - auth_timeout_ms: Timeout to wait for when sending a new public key. This - is only relevant when we send a new public key. The device shows a - dialog and this timeout is how long to wait for that dialog. If used - in automation, this should be low to catch such a case as a failure - quickly; while in interactive settings it should be high to allow - users to accept the dialog. We default to automation here, so it's low - by default. - - If serial specifies a TCP address:port, then a TCP connection is - used instead of a USB connection. - """ + """Convenience function to setup a transport handle for the adb device from usb path or serial then connect to + it. + + .. image:: _static/adb.adb_commands.AdbCommands.ConnectDevice.CALL_GRAPH.svg + + Parameters + ---------- + port_path : TODO, None + The filename of usb port to use. + serial : TODO, None + The serial number of the device to use. If serial specifies a TCP address:port, then a TCP connection is + used instead of a USB connection. + default_timeout_ms : TODO, None + The default timeout in milliseconds to use. + **kwargs + Keyword arguments + handle : common.TcpHandle, common.UsbHandle + Device handle to use + banner : TODO + Connection banner to pass to the remote device + rsa_keys : list[adb_protocol.AuthSigner] + List of AuthSigner subclass instances to be used for authentication. The device can either accept one + of these via the ``Sign`` method, or we will send the result of ``GetPublicKey`` from the first one if the + device doesn't accept any of them. + auth_timeout_ms : int + Timeout to wait for when sending a new public key. This is only relevant when we send a new public key. The + device shows a dialog and this timeout is how long to wait for that dialog. If used in automation, this + should be low to catch such a case as a failure quickly; while in interactive settings it should be high to + allow users to accept the dialog. We default to automation here, so it's low by default. + + Returns + ------- + self : AdbCommands + TODO - # If there isnt a handle override (used by tests), build one here + """ + # If there isn't a handle override (used by tests), build one here if 'handle' in kwargs: self._handle = kwargs.pop('handle') else: @@ -135,20 +213,25 @@ def ConnectDevice(self, port_path=None, serial=None, default_timeout_ms=None, ** if serial and ':' in serial: self._handle = common.TcpHandle(serial, timeout_ms=default_timeout_ms) else: - self._handle = common.UsbHandle.FindAndOpen( - DeviceIsAvailable, port_path=port_path, serial=serial, - timeout_ms=default_timeout_ms) + self._handle = common.UsbHandle.FindAndOpen(DeviceIsAvailable, port_path=port_path, serial=serial, timeout_ms=default_timeout_ms) self._Connect(**kwargs) return self def Close(self): + """TODO + + .. image:: _static/adb.adb_commands.AdbCommands.Close.CALL_GRAPH.svg + + .. image:: _static/adb.adb_commands.AdbCommands.Close.CALLER_GRAPH.svg + + """ for conn in list(self._service_connections.values()): if conn: try: conn.Close() - except: + except: # noqa pylint: disable=bare-except pass if self._handle: @@ -159,14 +242,22 @@ def Close(self): def _Connect(self, banner=None, **kwargs): """Connect to the device. - Args: - banner: See protocol_handler.Connect. - **kwargs: See protocol_handler.Connect and adb_commands.ConnectDevice for kwargs. - Includes handle, rsa_keys, and auth_timeout_ms. - Returns: - An instance of this class if the device connected successfully. - """ + .. image:: _static/adb.adb_commands.AdbCommands._Connect.CALLER_GRAPH.svg + + Parameters + ---------- + banner : bytes, None + A string to send as a host identifier. (See :meth:`adb.adb_protocol.AdbMessage.Connect`.) + **kwargs : TODO + See :meth:`adb.adb_protocol.AdbMessage.Connect` and :meth:`AdbCommands.ConnectDevice` for kwargs. Includes ``handle``, ``rsa_keys``, and + ``auth_timeout_ms``. + Returns + ------- + bool + ``True`` + + """ if not banner: banner = socket.gethostname().encode() @@ -183,10 +274,27 @@ def _Connect(self, banner=None, **kwargs): @classmethod def Devices(cls): - """Get a generator of UsbHandle for devices available.""" + """Get a generator of :py:class:`~adb.common.UsbHandle` for devices available. + + Returns + ------- + TODO + TODO + + """ return common.UsbHandle.FindDevices(DeviceIsAvailable) def GetState(self): + """TODO + + .. image:: _static/adb.adb_commands.AdbCommands.GetState.CALL_GRAPH.svg + + Returns + ------- + self._device_state : TODO + TODO + + """ return self._device_state def Install(self, apk_path, destination_dir='', replace_existing=True, @@ -196,17 +304,30 @@ def Install(self, apk_path, destination_dir='', replace_existing=True, Doesn't support verifier file, instead allows destination directory to be overridden. - Args: - apk_path: Local path to apk to install. - destination_dir: Optional destination directory. Use /system/app/ for - persistent applications. - replace_existing: whether to replace existing application - grant_permissions: If True, grant all permissions to the app specified in its manifest - timeout_ms: Expected timeout for pushing and installing. - transfer_progress_callback: callback method that accepts filename, bytes_written and total_bytes of APK transfer - - Returns: - The pm install output. + .. image:: _static/adb.adb_commands.AdbCommands.Install.CALL_GRAPH.svg + + .. image:: _static/adb.adb_commands.AdbCommands.Install.CALLER_GRAPH.svg + + Parameters + ---------- + apk_path : TODO + Local path to apk to install. + destination_dir : str + Optional destination directory. Use ``/system/app/`` for persistent applications. + replace_existing : bool + Whether to replace existing application + grant_permissions : bool + If ``True``, grant all permissions to the app specified in its manifest + timeout_ms : int, None + Expected timeout for pushing and installing. + transfer_progress_callback : TODO, None + callback method that accepts ``filename``, ``bytes_written``, and ``total_bytes`` of APK transfer + + Returns + ------- + ret : TODO + The ``pm install`` output. + """ if not destination_dir: destination_dir = '/data/local/tmp/' @@ -225,20 +346,29 @@ def Install(self, apk_path, destination_dir='', replace_existing=True, # Remove the apk rm_cmd = ['rm', destination_path] - rmret = self.Shell(' '.join(rm_cmd), timeout_ms=timeout_ms) + self.Shell(' '.join(rm_cmd), timeout_ms=timeout_ms) return ret def Uninstall(self, package_name, keep_data=False, timeout_ms=None): """Removes a package from the device. - Args: - package_name: Package name of target package. - keep_data: whether to keep the data and cache directories - timeout_ms: Expected timeout for pushing and installing. + .. image:: _static/adb.adb_commands.AdbCommands.Uninstall.CALL_GRAPH.svg + + Parameters + ---------- + package_name : TODO + Package name of target package. + keep_data : bool + Whether to keep the data and cache directories + timeout_ms : int, None + Expected timeout for pushing and installing. + + Returns + ------- + TODO + The ``pm uninstall`` output. - Returns: - The pm uninstall output. """ cmd = ['pm uninstall'] if keep_data: @@ -250,57 +380,78 @@ def Uninstall(self, package_name, keep_data=False, timeout_ms=None): def Push(self, source_file, device_filename, mtime='0', timeout_ms=None, progress_callback=None, st_mode=None): """Push a file or directory to the device. - Args: - source_file: Either a filename, a directory or file-like object to push to - the device. - device_filename: Destination on the device to write to. - mtime: Optional, modification time to set on the file. - timeout_ms: Expected timeout for any part of the push. - st_mode: stat mode for filename - progress_callback: callback method that accepts filename, bytes_written and total_bytes, - total_bytes will be -1 for file-like objects - """ + .. image:: _static/adb.adb_commands.AdbCommands.Push.CALL_GRAPH.svg + + .. image:: _static/adb.adb_commands.AdbCommands.Push.CALLER_GRAPH.svg + + Parameters + ---------- + source_file : TODO + Either a filename, a directory or file-like object to push to the device. + device_filename : TODO + Destination on the device to write to. + mtime : str + Modification time to set on the file. + timeout_ms : int, None + Expected timeout for any part of the push. + progress_callback : TODO, None + Callback method that accepts filename, bytes_written and total_bytes, total_bytes will be -1 for file-like + objects + st_mode : TODO, None + Stat mode for filename + """ if isinstance(source_file, str): if os.path.isdir(source_file): self.Shell("mkdir " + device_filename) for f in os.listdir(source_file): - self.Push(os.path.join(source_file, f), device_filename + '/' + f, - progress_callback=progress_callback) + self.Push(os.path.join(source_file, f), device_filename + '/' + f, progress_callback=progress_callback) return + source_file = open(source_file, "rb") with source_file: - connection = self.protocol_handler.Open( - self._handle, destination=b'sync:', timeout_ms=timeout_ms) - kwargs={} + connection = self.protocol_handler.Open(self._handle, destination=b'sync:', timeout_ms=timeout_ms) + kwargs = {} if st_mode is not None: kwargs['st_mode'] = st_mode - self.filesync_handler.Push(connection, source_file, device_filename, - mtime=int(mtime), progress_callback=progress_callback, **kwargs) + self.filesync_handler.Push(connection, source_file, device_filename, mtime=int(mtime), progress_callback=progress_callback, **kwargs) connection.Close() def Pull(self, device_filename, dest_file=None, timeout_ms=None, progress_callback=None): """Pull a file from the device. - Args: - device_filename: Filename on the device to pull. - dest_file: If set, a filename or writable file-like object. - timeout_ms: Expected timeout for any part of the pull. - progress_callback: callback method that accepts filename, bytes_written and total_bytes, - total_bytes will be -1 for file-like objects + Parameters + ---------- + device_filename : TODO + Filename on the device to pull. + dest_file : str, file, io.IOBase, None + If set, a filename or writable file-like object. + timeout_ms : int, None + Expected timeout for any part of the pull. + progress_callback : TODO, None + Callback method that accepts filename, bytes_written and total_bytes, total_bytes will be -1 for file-like + objects + + Returns + ------- + TODO + The file data if ``dest_file`` is not set. Otherwise, ``True`` if the destination file exists + + Raises + ------ + ValueError + If ``dest_file`` is of unknown type. - Returns: - The file data if dest_file is not set. Otherwise, True if the destination file exists """ if not dest_file: dest_file = io.BytesIO() elif isinstance(dest_file, str): dest_file = open(dest_file, 'wb') - elif isinstance(dest_file, file): + elif isinstance(dest_file, file_types): pass else: - raise ValueError("destfile is of unknown type") + raise ValueError("dest_file is of unknown type") conn = self.protocol_handler.Open( self._handle, destination=b'sync:', timeout_ms=timeout_ms) @@ -310,26 +461,52 @@ def Pull(self, device_filename, dest_file=None, timeout_ms=None, progress_callba conn.Close() if isinstance(dest_file, io.BytesIO): return dest_file.getvalue() - else: - dest_file.close() - if hasattr(dest_file, 'name'): - return os.path.exists(dest_file.name) - # We don't know what the path is, so we just assume it exists. - return True + + dest_file.close() + if hasattr(dest_file, 'name'): + return os.path.exists(dest_file.name) + + # We don't know what the path is, so we just assume it exists. + return True def Stat(self, device_filename): - """Get a file's stat() information.""" + """Get a file's ``stat()`` information. + + .. image:: _static/adb.adb_commands.AdbCommands.Stat.CALLER_GRAPH.svg + + Parameters + ---------- + device_filename : TODO + TODO + + Returns + ------- + mode : TODO + TODO + size : TODO + TODO + mtime : TODO + TODO + + """ connection = self.protocol_handler.Open(self._handle, destination=b'sync:') - mode, size, mtime = self.filesync_handler.Stat( - connection, device_filename) + mode, size, mtime = self.filesync_handler.Stat(connection, device_filename) connection.Close() return mode, size, mtime def List(self, device_path): """Return a directory listing of the given path. - Args: - device_path: Directory to list. + Parameters + ---------- + device_path : TODO + Directory to list. + + Returns + ------- + listing : TODO + TODO + """ connection = self.protocol_handler.Open(self._handle, destination=b'sync:') listing = self.filesync_handler.List(connection, device_path) @@ -339,81 +516,151 @@ def List(self, device_path): def Reboot(self, destination=b''): """Reboot the device. - Args: - destination: Specify 'bootloader' for fastboot. + .. image:: _static/adb.adb_commands.AdbCommands.Reboot.CALLER_GRAPH.svg + + Parameters + ---------- + destination : bytes + Specify ``'bootloader'`` for fastboot. + """ self.protocol_handler.Open(self._handle, b'reboot:%s' % destination) def RebootBootloader(self): - """Reboot device into fastboot.""" + """Reboot device into fastboot. + + .. image:: _static/adb.adb_commands.AdbCommands.RebootBootloader.CALL_GRAPH.svg + + """ self.Reboot(b'bootloader') def Remount(self): - """Remount / as read-write.""" + """Remount / as read-write. + + Returns + ------- + TODO + TODO + + """ return self.protocol_handler.Command(self._handle, service=b'remount') def Root(self): - """Restart adbd as root on the device.""" + """Restart ``adbd`` as root on the device. + + Returns + ------- + TODO + TODO + + """ return self.protocol_handler.Command(self._handle, service=b'root') def EnableVerity(self): - """Re-enable dm-verity checking on userdebug builds""" + """Re-enable dm-verity checking on userdebug builds. + + Returns + ------- + TODO + TODO + + """ return self.protocol_handler.Command(self._handle, service=b'enable-verity') def DisableVerity(self): - """Disable dm-verity checking on userdebug builds""" + """Disable dm-verity checking on userdebug builds. + + Returns + ------- + TODO + TODO + + """ return self.protocol_handler.Command(self._handle, service=b'disable-verity') def Shell(self, command, timeout_ms=None): """Run command on the device, returning the output. - Args: - command: Shell command to run - timeout_ms: Maximum time to allow the command to run. + .. image:: _static/adb.adb_commands.AdbCommands.Shell.CALLER_GRAPH.svg + + Parameters + ---------- + command : TODO + Shell command to run + timeout_ms : int, None + Maximum time to allow the command to run. + + Returns + ------- + TODO + TODO + """ - return self.protocol_handler.Command( - self._handle, service=b'shell', command=command, - timeout_ms=timeout_ms) + return self.protocol_handler.Command(self._handle, service=b'shell', command=command, timeout_ms=timeout_ms) def StreamingShell(self, command, timeout_ms=None): """Run command on the device, yielding each line of output. - Args: - command: Command to run on the target. - timeout_ms: Maximum time to allow the command to run. + .. image:: _static/adb.adb_commands.AdbCommands.StreamingShell.CALLER_GRAPH.svg + + Parameters + ---------- + command : bytes + Command to run on the target. + timeout_ms : int, None + Maximum time to allow the command to run. + + Returns + ------- + generator + The responses from the shell command. - Yields: - The responses from the shell command. """ - return self.protocol_handler.StreamingCommand( - self._handle, service=b'shell', command=command, - timeout_ms=timeout_ms) + return self.protocol_handler.StreamingCommand(self._handle, service=b'shell', command=command, timeout_ms=timeout_ms) def Logcat(self, options, timeout_ms=None): - """Run 'shell logcat' and stream the output to stdout. + """Run ``shell logcat`` and stream the output to stdout. + + .. image:: _static/adb.adb_commands.AdbCommands.Logcat.CALL_GRAPH.svg + + Parameters + ---------- + options : str + Arguments to pass to ``logcat`` + timeout_ms : int, None + Maximum time to allow the command to run. + + Returns + ------- + generator + The responses from the ``logcat`` command - Args: - options: Arguments to pass to 'logcat'. - timeout_ms: Maximum time to allow the command to run. """ return self.StreamingShell('logcat %s' % options, timeout_ms) def InteractiveShell(self, cmd=None, strip_cmd=True, delim=None, strip_delim=True): - """Get stdout from the currently open interactive shell and optionally run a command - on the device, returning all output. - - Args: - cmd: Optional. Command to run on the target. - strip_cmd: Optional (default True). Strip command name from stdout. - delim: Optional. Delimiter to look for in the output to know when to stop expecting more output - (usually the shell prompt) - strip_delim: Optional (default True): Strip the provided delimiter from the output - - Returns: - The stdout from the shell command. + """Get stdout from the currently open interactive shell and optionally run a command on the device, returning + all output. + + .. image:: _static/adb.adb_commands.AdbCommands.InteractiveShell.CALL_GRAPH.svg + + Parameters + ---------- + cmd : TODO, None + Command to run on the target. + strip_cmd : bool + Strip command name from stdout. + delim : TODO, None + Delimiter to look for in the output to know when to stop expecting more output (usually the shell prompt) + strip_delim : bool + Strip the provided delimiter from the output + + Returns + ------- + TODO + The stdout from the shell command. + """ conn = self._get_service_connection(b'shell:') - return self.protocol_handler.InteractiveShellCommand( - conn, cmd=cmd, strip_cmd=strip_cmd, - delim=delim, strip_delim=strip_delim) + return self.protocol_handler.InteractiveShellCommand(conn, cmd=cmd, strip_cmd=strip_cmd, delim=delim, strip_delim=strip_delim) diff --git a/adb/adb_debug.py b/adb/adb_debug.py index 6037269..94340b1 100644 --- a/adb/adb_debug.py +++ b/adb/adb_debug.py @@ -13,7 +13,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Daemon-less ADB client in python.""" +"""Daemon-less ADB client in python. + + +.. rubric:: Contents + +* :func:`Devices` +* :func:`List` +* :func:`Logcat` +* :func:`Shell` + +""" import argparse import functools @@ -47,14 +57,32 @@ def Devices(args): """Lists the available devices. - Mimics 'adb devices' output: + Mimics ``adb devices`` output: + + :: + List of devices attached 015DB7591102001A device 1,2 + + + .. seealso:: :meth:`adb.adb_commands.AdbCommands.Devices` + + .. image:: _static/adb.adb_debug.Devices.CALLER_GRAPH.svg + + Parameters + ---------- + args : argparse.ArgumentParser + CLI arguments; see :func:`adb.common_cli.GetDeviceArguments`. + + Returns + ------- + int + 0 + """ for d in adb_commands.AdbCommands.Devices(): if args.output_port_path: - print('%s\tdevice\t%s' % ( - d.serial_number, ','.join(str(p) for p in d.port_path))) + print('%s\tdevice\t%s' % (d.serial_number, ','.join(str(p) for p in d.port_path))) else: print('%s\tdevice' % d.serial_number) return 0 @@ -63,16 +91,27 @@ def Devices(args): def List(device, device_path): """Prints a directory listing. - Args: - device_path: Directory to list. + .. seealso:: :meth:`adb.adb_commands.AdbCommands.List` + + Parameters + ---------- + device : adb.adb_commands.AdbCommands + TODO + device_path : str, bytes + Directory to list. + + Yields + ------ + str + A formatted listing for a file in ``device_path`` + """ files = device.List(device_path) files.sort(key=lambda x: x.filename) maxname = max(len(f.filename) for f in files) maxsize = max(len(str(f.size)) for f in files) for f in files: - mode = ( - ('d' if stat.S_ISDIR(f.mode) else '-') + + mode = (('d' if stat.S_ISDIR(f.mode) else '-') + ('r' if f.mode & stat.S_IRUSR else '-') + ('w' if f.mode & stat.S_IWUSR else '-') + ('x' if f.mode & stat.S_IXUSR else '-') + @@ -83,6 +122,7 @@ def List(device, device_path): ('w' if f.mode & stat.S_IWOTH else '-') + ('x' if f.mode & stat.S_IXOTH else '-')) t = time.gmtime(f.mtime) + yield '%s %*d %04d-%02d-%02d %02d:%02d:%02d %-*s\n' % ( mode, maxsize, f.size, t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, @@ -91,85 +131,94 @@ def List(device, device_path): @functools.wraps(adb_commands.AdbCommands.Logcat) def Logcat(device, *options): - return device.Logcat( - device, ' '.join(options), timeout_ms=0) + """Run ``shell logcat`` and stream the output to stdout. + + .. seealso:: :meth:`adb.adb_commands.AdbCommands.Logcat` + + Parameters + ---------- + device : adb.adb_commands.AdbCommands + TODO + options : list[str] + Arguments to pass to ``logcat`` + + Returns + ------- + generator + The responses from the ``logcat`` command + + """ + return device.Logcat(device, ' '.join(options), timeout_ms=0) def Shell(device, *command): """Runs a command on the device and prints the stdout. - Args: - command: Command to run on the target. + .. seealso:: :meth:`adb.adb_commands.AdbCommands.StreamingShell`, :meth:`adb.adb_commands.AdbCommands.InteractiveShell` + + Parameters + ---------- + device : adb.adb_commands.AdbCommands + TODO + command : list[str] + Command to run on the target. + """ if command: return device.StreamingShell(' '.join(command)) - else: - # Retrieve the initial terminal prompt to use as a delimiter for future reads - terminal_prompt = device.InteractiveShell() - print(terminal_prompt.decode('utf-8')) - - # Accept user input in a loop and write that into the interactive shells stdin, then print output - while True: - cmd = input('> ') - if not cmd: - continue - elif cmd == 'exit': - break - else: - stdout = device.InteractiveShell(cmd, strip_cmd=True, delim=terminal_prompt, strip_delim=True) - if stdout: - if isinstance(stdout, bytes): - stdout = stdout.decode('utf-8') - print(stdout) - - device.Close() + + # Retrieve the initial terminal prompt to use as a delimiter for future reads + terminal_prompt = device.InteractiveShell() + print(terminal_prompt.decode('utf-8')) + + # Accept user input in a loop and write that into the interactive shells stdin, then print output + while True: + cmd = input('> ') + if not cmd: + continue + + if cmd == 'exit': + break + + stdout = device.InteractiveShell(cmd, strip_cmd=True, delim=terminal_prompt, strip_delim=True) + if stdout: + if isinstance(stdout, bytes): + stdout = stdout.decode('utf-8') + print(stdout) + + device.Close() def main(): + """TODO""" common = common_cli.GetCommonArguments() - common.add_argument( - '--rsa_key_path', action='append', default=[], - metavar='~/.android/adbkey', - help='RSA key(s) to use, use multiple times to load mulitple keys') - common.add_argument( - '--auth_timeout_s', default=60., metavar='60', type=int, - help='Seconds to wait for the dialog to be accepted when using ' - 'authenticated ADB.') + common.add_argument('--rsa_key_path', action='append', default=[], metavar='~/.android/adbkey', + help='RSA key(s) to use, use multiple times to load mulitple keys') + common.add_argument('--auth_timeout_s', default=60., metavar='60', type=int, + help='Seconds to wait for the dialog to be accepted when using authenticated ADB.') + device = common_cli.GetDeviceArguments() parents = [common, device] - parser = argparse.ArgumentParser( - description=sys.modules[__name__].__doc__, parents=[common]) + parser = argparse.ArgumentParser(description=sys.modules[__name__].__doc__, parents=[common]) subparsers = parser.add_subparsers(title='Commands', dest='command_name') - subparser = subparsers.add_parser( - name='help', help='Prints the commands available') - subparser = subparsers.add_parser( - name='devices', help='Lists the available devices', parents=[common]) - subparser.add_argument( - '--output_port_path', action='store_true', - help='Outputs the port_path alongside the serial') + subparser = subparsers.add_parser(name='help', help='Prints the commands available') + subparser = subparsers.add_parser(name='devices', help='Lists the available devices', parents=[common]) + + subparser.add_argument('--output_port_path', action='store_true', help='Outputs the port_path alongside the serial') - common_cli.MakeSubparser( - subparsers, parents, adb_commands.AdbCommands.Install) + common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Install) common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Uninstall) common_cli.MakeSubparser(subparsers, parents, List) common_cli.MakeSubparser(subparsers, parents, Logcat) - common_cli.MakeSubparser( - subparsers, parents, adb_commands.AdbCommands.Push, - {'source_file': 'Filename or directory to push to the device.'}) - common_cli.MakeSubparser( - subparsers, parents, adb_commands.AdbCommands.Pull, - { - 'dest_file': 'Filename to write to on the host, if not specified, ' - 'prints the content to stdout.', - }) - common_cli.MakeSubparser( - subparsers, parents, adb_commands.AdbCommands.Reboot) - common_cli.MakeSubparser( - subparsers, parents, adb_commands.AdbCommands.RebootBootloader) - common_cli.MakeSubparser( - subparsers, parents, adb_commands.AdbCommands.Remount) + common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Push, + {'source_file': 'Filename or directory to push to the device.'}) + common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Pull, + {'dest_file': 'Filename to write to on the host, if not specified, prints the content to stdout.'}) + common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Reboot) + common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.RebootBootloader) + common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Remount) common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.Root) common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.EnableVerity) common_cli.MakeSubparser(subparsers, parents, adb_commands.AdbCommands.DisableVerity) @@ -182,29 +231,32 @@ def main(): args = parser.parse_args() if args.verbose: logging.basicConfig(level=logging.DEBUG) + if not args.rsa_key_path: default = os.path.expanduser('~/.android/adbkey') if os.path.isfile(default): args.rsa_key_path = [default] + if args.rsa_key_path and not rsa_signer: parser.error('Please install either cryptography, python-rsa, or PycryptoDome') # Hacks so that the generated doc is nicer. if args.command_name == 'devices': return Devices(args) + if args.command_name == 'help': parser.print_help() return 0 + if args.command_name == 'logcat': args.positional = args.options elif args.command_name == 'shell': args.positional = args.command - return common_cli.StartCli( - args, - adb_commands.AdbCommands, - auth_timeout_ms=int(args.auth_timeout_s * 1000), - rsa_keys=[rsa_signer(path) for path in args.rsa_key_path]) + return common_cli.StartCli(args, + adb_commands.AdbCommands, + auth_timeout_ms=int(args.auth_timeout_s * 1000), + rsa_keys=[rsa_signer(path) for path in args.rsa_key_path]) if __name__ == '__main__': diff --git a/adb/adb_keygen.py b/adb/adb_keygen.py new file mode 100644 index 0000000..c524940 --- /dev/null +++ b/adb/adb_keygen.py @@ -0,0 +1,247 @@ +"""This file implements encoding and decoding logic for Android's custom RSA +public key binary format. Public keys are stored as a sequence of +little-endian 32 bit words. Note that Android only supports little-endian +processors, so we don't do any byte order conversions when parsing the binary +struct. + +Structure from: +https://github.com/aosp-mirror/platform_system_core/blob/c55fab4a59cfa461857c6a61d8a0f1ae4591900c/libcrypto_utils/android_pubkey.c + +.. code-block:: c + + typedef struct RSAPublicKey { + // Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE_WORDS + uint32_t modulus_size_words; + + // Precomputed montgomery parameter: -1 / n[0] mod 2^32 + uint32_t n0inv; + + // RSA modulus as a little-endian array + uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE]; + + // Montgomery parameter R^2 as a little-endian array of little-endian words + uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE]; + + // RSA modulus: 3 or 65537 + uint32_t exponent; + } RSAPublicKey; + + +.. rubric:: Contents + +* :func:`_to_bytes` +* :func:`decode_pubkey` +* :func:`decode_pubkey_file` +* :func:`encode_pubkey` +* :func:`get_user_info` +* :func:`keygen` +* :func:`write_public_keyfile` + +""" + + +from __future__ import print_function + +import os +import base64 +import socket +import struct +import sys + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa + + +if sys.version_info[0] == 2: + FileNotFoundError = IOError # pylint: disable=redefined-builtin + + +#: Size of an RSA modulus such as an encrypted block or a signature. +ANDROID_PUBKEY_MODULUS_SIZE = (2048 // 8) + +#: Python representation of "struct RSAPublicKey" +ANDROID_RSAPUBLICKEY_STRUCT = ( + '<' # Little-endian + 'L' # uint32_t modulus_size_words; + 'L' # uint32_t n0inv; + '{modulus_size}s' # uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE]; + '{modulus_size}s' # uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE]; + 'L' # uint32_t exponent; +).format(modulus_size=ANDROID_PUBKEY_MODULUS_SIZE) + + +#: Size of the RSA modulus in words. +ANDROID_PUBKEY_MODULUS_SIZE_WORDS = (ANDROID_PUBKEY_MODULUS_SIZE // 4) + + +def _to_bytes(n, length, endianess='big'): + """Partial python2 compatibility with int.to_bytes + + https://stackoverflow.com/a/20793663 + + Parameters + ---------- + n : TODO + TODO + length : TODO + TODO + endianess : str, TODO + TODO + + Returns + ------- + TODO + TODO + + """ + if not hasattr(n, 'to_bytes'): + h = '{:x}'.format(n) + s = ('0' * (len(h) % 2) + h).zfill(length * 2).decode('hex') + return s if endianess == 'big' else s[::-1] + return n.to_bytes(length, endianess) + + +def decode_pubkey(public_key): + """Decode a public RSA key stored in Android's custom binary format. + + Parameters + ---------- + public_key : TODO + TODO + + """ + binary_key_data = base64.b64decode(public_key) + modulus_size_words, n0inv, modulus_bytes, rr_bytes, exponent = struct.unpack(ANDROID_RSAPUBLICKEY_STRUCT, binary_key_data) + assert modulus_size_words == ANDROID_PUBKEY_MODULUS_SIZE_WORDS + modulus = reversed(modulus_bytes) + rr = reversed(rr_bytes) + print('modulus_size_words:', hex(modulus_size_words)) + print('n0inv:', hex(n0inv)) + print('modulus: ', end='') + print(*map(hex, modulus), sep=':') + print('rr: ', end='') + print(*map(hex, rr), sep=':') + print('exponent:', hex(exponent)) + + +def decode_pubkey_file(public_key_path): + """TODO + + Parameters + ---------- + public_key_path : str + TODO + + """ + with open(public_key_path, 'rb') as fd: + decode_pubkey(fd.read()) + + +def encode_pubkey(private_key_path): + """Encodes a public RSA key into Android's custom binary format. + + Parameters + ---------- + private_key_path : str + TODO + + Returns + ------- + TODO + TODO + + """ + with open(private_key_path, 'rb') as key_file: + key = serialization.load_pem_private_key(key_file.read(), password=None, backend=default_backend()).private_numbers().public_numbers + + # Compute and store n0inv = -1 / N[0] mod 2^32. + # BN_set_bit(r32, 32) + r32 = 1 << 32 + # BN_mod(n0inv, key->n, r32, ctx) + n0inv = key.n % r32 + # BN_mod_inverse(n0inv, n0inv, r32, ctx) + n0inv = rsa._modinv(n0inv, r32) # pylint: disable=protected-access + # BN_sub(n0inv, r32, n0inv) + n0inv = r32 - n0inv + + # Compute and store rr = (2^(rsa_size)) ^ 2 mod N. + # BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) + rr = 1 << (ANDROID_PUBKEY_MODULUS_SIZE * 8) + # BN_mod_sqr(rr, rr, key->n, ctx) + rr = (rr ** 2) % key.n + + return struct.pack( + ANDROID_RSAPUBLICKEY_STRUCT, + ANDROID_PUBKEY_MODULUS_SIZE_WORDS, + n0inv, + _to_bytes(key.n, ANDROID_PUBKEY_MODULUS_SIZE, 'little'), + _to_bytes(rr, ANDROID_PUBKEY_MODULUS_SIZE, 'little'), + key.e + ) + + +def get_user_info(): + """TODO + + Returns + ------- + str + ``' @`` + + """ + try: + username = os.getlogin() + except (FileNotFoundError, OSError): + username = 'unknown' + + if not username: + username = 'unknown' + + hostname = socket.gethostname() + if not hostname: + hostname = 'unknown' + + return ' ' + username + '@' + hostname + + +def write_public_keyfile(private_key_path, public_key_path): + """Write a public keyfile to ``public_key_path`` in Android's custom + RSA public key format given a path to a private keyfile. + + Parameters + ---------- + private_key_path : TODO + TODO + public_key_path : TODO + TODO + + """ + public_key = encode_pubkey(private_key_path) + assert len(public_key) == struct.calcsize(ANDROID_RSAPUBLICKEY_STRUCT) + + with open(public_key_path, 'wb') as public_key_file: + public_key_file.write(base64.b64encode(public_key)) + public_key_file.write(get_user_info().encode()) + + +def keygen(filepath): + """Generate an ADB public/private key pair. + + * The private key is stored in ``filepath``. + * The public key is stored in ``filepath + '.pub'`` + + (Existing files will be overwritten.) + + Parameters + ---------- + filepath : str + File path to write the private/public keypair + + """ + private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend()) + + with open(filepath, 'wb') as private_key_file: + private_key_file.write(private_key.private_bytes(encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption())) + + write_public_keyfile(filepath, filepath + '.pub') diff --git a/adb/adb_protocol.py b/adb/adb_protocol.py index 4ff28c7..e05c88a 100644 --- a/adb/adb_protocol.py +++ b/adb/adb_protocol.py @@ -11,10 +11,50 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """ADB protocol implementation. Implements the ADB protocol as seen in android's adb/adbd binaries, but only the host side. + + +.. rubric:: Contents + +* :class:`_AdbConnection` + + * :meth:`_AdbConnection._Send` + * :meth:`_AdbConnection.Close` + * :meth:`_AdbConnection.Okay` + * :meth:`_AdbConnection.ReadUntil` + * :meth:`_AdbConnection.ReadUntilClose` + * :meth:`_AdbConnection.Write` + +* :class:`AdbMessage` + + * :meth:`AdbMessage.CalculateChecksum` + * :meth:`AdbMessage.checksum` + * :meth:`AdbMessage.Command` + * :meth:`AdbMessage.Connect` + * :meth:`AdbMessage.InteractiveShellCommand` + * :meth:`AdbMessage.Open` + * :meth:`AdbMessage.Pack` + * :meth:`AdbMessage.Read` + * :meth:`AdbMessage.Send` + * :meth:`AdbMessage.StreamingCommand` + * :meth:`AdbMessage.Unpack` + +* :class:`AuthSigner` + + * :meth:`AuthSigner.GetPublicKey` + * :meth:`AuthSigner.Sign` + +* :func:`find_backspace_runs` +* :class:`InterleavedDataError` +* :class:`InvalidChecksumError` +* :class:`InvalidCommandError` +* :class:`InvalidResponseError` +* :func:`MakeWireIDs` + """ import struct @@ -22,18 +62,81 @@ from io import BytesIO from adb import usb_exceptions -# Maximum amount of data in an ADB packet. + +#: Maximum amount of data in an ADB packet. MAX_ADB_DATA = 4096 -# ADB protocol version. + +#: ADB protocol version. VERSION = 0x01000000 -# AUTH constants for arg0. +#: AUTH constants for arg0. AUTH_TOKEN = 1 + +#: AUTH constants for arg0. AUTH_SIGNATURE = 2 + +#: AUTH constants for arg0. AUTH_RSAPUBLICKEY = 3 +class InvalidCommandError(Exception): + """Got an invalid command over USB. + + .. image:: _static/adb.adb_protocol.InvalidCommandError.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol.InvalidCommandError.__init__.CALLER_GRAPH.svg + + """ + def __init__(self, message, response_header, response_data): + if response_header == b'FAIL': + message = 'Command failed, device said so. (%s)' % message + super(InvalidCommandError, self).__init__(message, response_header, response_data) + + +class InvalidResponseError(Exception): + """Got an invalid response to our command. + + .. image:: _static/adb.adb_protocol.InvalidResponseError.CALL_GRAPH.svg + + """ + + +class InvalidChecksumError(Exception): + """Checksum of data didn't match expected checksum. + + .. image:: _static/adb.adb_protocol.InvalidChecksumError.CALL_GRAPH.svg + + """ + + +class InterleavedDataError(Exception): + """We only support command sent serially. + + .. image:: _static/adb.adb_protocol.InterleavedDataError.CALL_GRAPH.svg + + """ + + def find_backspace_runs(stdout_bytes, start_pos): + """TODO + + .. image:: _static/adb.adb_protocol.find_backspace_runs.CALLER_GRAPH.svg + + Parameters + ---------- + stdout_bytes : TODO + TODO + start_pos : TODO + TODO + + Returns + ------- + int + The index/position of the first backspace. + num_backspaces : int + TODO + + """ first_backspace_pos = stdout_bytes[start_pos:].find(b'\x08') if first_backspace_pos == -1: return -1, 0 @@ -50,33 +153,23 @@ def find_backspace_runs(stdout_bytes, start_pos): return (start_pos + first_backspace_pos), num_backspaces -class InvalidCommandError(Exception): - """Got an invalid command over USB.""" - - def __init__(self, message, response_header, response_data): - if response_header == b'FAIL': - message = 'Command failed, device said so. (%s)' % message - super(InvalidCommandError, self).__init__( - message, response_header, response_data) - - -class InvalidResponseError(Exception): - """Got an invalid response to our command.""" - - -class InvalidChecksumError(Exception): - """Checksum of data didn't match expected checksum.""" - +def MakeWireIDs(ids): + """TODO -class InterleavedDataError(Exception): - """We only support command sent serially.""" + Parameters + ---------- + ids : list[bytes] + TODO + Returns + ------- + id_to_wire : dict + TODO + wire_to_id : dict + TODO -def MakeWireIDs(ids): - id_to_wire = { - cmd_id: sum(c << (i * 8) for i, c in enumerate(bytearray(cmd_id))) - for cmd_id in ids - } + """ + id_to_wire = {cmd_id: sum(c << (i * 8) for i, c in enumerate(bytearray(cmd_id))) for cmd_id in ids} wire_to_id = {wire: cmd_id for cmd_id, wire in id_to_wire.items()} return id_to_wire, wire_to_id @@ -85,17 +178,61 @@ class AuthSigner(object): """Signer for use with authenticated ADB, introduced in 4.4.x/KitKat.""" def Sign(self, data): - """Signs given data using a private key.""" + """Signs given data using a private key. + + Parameters + ---------- + data : bytes + The data to be signed + + Raises + ------ + NotImplementedError + This method is implemented in subclasses. + + """ raise NotImplementedError() def GetPublicKey(self): - """Returns the public key in PEM format without headers or newlines.""" + """Returns the public key in PEM format without headers or newlines. + + Raises + ------ + NotImplementedError + This method is implemented in subclasses. + + """ raise NotImplementedError() class _AdbConnection(object): - """ADB Connection.""" + """ADB Connection. + + .. image:: _static/adb.adb_protocol._AdbConnection.__init__.CALLER_GRAPH.svg + + Parameters + ---------- + usb : adb.common.UsbHandle + TODO + local_id : TODO + TODO + remote_id : TODO + TODO + timeout_ms : int + Timeout in milliseconds for USB packets. + + Attributes + ---------- + local_id : TODO + The ID for the sender + remote_id : TODO + The ID for the recipient + timeout_ms : int + Timeout in milliseconds for USB packets. + usb : adb.common.UsbHandle + TODO + """ def __init__(self, usb, local_id, remote_id, timeout_ms): self.usb = usb self.local_id = local_id @@ -103,80 +240,204 @@ def __init__(self, usb, local_id, remote_id, timeout_ms): self.timeout_ms = timeout_ms def _Send(self, command, arg0, arg1, data=b''): + """TODO + + .. image:: _static/adb.adb_protocol._AdbConnection._Send.CALLER_GRAPH.svg + + Parameters + ---------- + command : TODO + TODO + arg0 : TODO + TODO + arg1 : TODO + TODO + data : bytes + TODO + + """ message = AdbMessage(command, arg0, arg1, data) message.Send(self.usb, self.timeout_ms) def Write(self, data): - """Write a packet and expect an Ack.""" + """Write a packet and expect an Ack. + + .. image:: _static/adb.adb_protocol._AdbConnection.Write.CALL_GRAPH.svg + + Parameters + ---------- + data : TODO + TODO + + Returns + ------- + int + ``len(data)`` + + Raises + ------ + usb_exceptions.AdbCommandFailureException + The command failed. + adb.adb_protocol.InvalidCommandError + Expected an OKAY in response to a WRITE, got something else. + + """ self._Send(b'WRTE', arg0=self.local_id, arg1=self.remote_id, data=data) + # Expect an ack in response. cmd, okay_data = self.ReadUntil(b'OKAY') if cmd != b'OKAY': if cmd == b'FAIL': - raise usb_exceptions.AdbCommandFailureException( - 'Command failed.', okay_data) - raise InvalidCommandError( - 'Expected an OKAY in response to a WRITE, got %s (%s)', - cmd, okay_data) + raise usb_exceptions.AdbCommandFailureException('Command failed.', okay_data) + + raise InvalidCommandError('Expected an OKAY in response to a WRITE, got {0} ({1})'.format(cmd, okay_data), cmd, okay_data) + return len(data) def Okay(self): + """TODO + + .. image:: _static/adb.adb_protocol._AdbConnection.Okay.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol._AdbConnection.Okay.CALLER_GRAPH.svg + + """ self._Send(b'OKAY', arg0=self.local_id, arg1=self.remote_id) def ReadUntil(self, *expected_cmds): - """Read a packet, Ack any write packets.""" - cmd, remote_id, local_id, data = AdbMessage.Read( - self.usb, expected_cmds, self.timeout_ms) - if local_id != 0 and self.local_id != local_id: + """Read a packet, Ack any write packets. + + .. image:: _static/adb.adb_protocol._AdbConnection.ReadUntil.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol._AdbConnection.ReadUntil.CALLER_GRAPH.svg + + Parameters + ---------- + *expected_cmds : TODO + TODO + + Returns + ------- + cmd : TODO + TODO + data : TODO + TODO + + Raises + ------ + adb.adb_protocol.InterleavedDataError + We don't support multiple streams... + adb.adb_protocol.InvalidResponseError + Incorrect remote id. + + """ + cmd, remote_id, local_id, data = AdbMessage.Read(self.usb, expected_cmds, self.timeout_ms) + + if local_id not in (0, self.local_id): raise InterleavedDataError("We don't support multiple streams...") - if remote_id != 0 and self.remote_id != remote_id: - raise InvalidResponseError( - 'Incorrect remote id, expected %s got %s' % ( - self.remote_id, remote_id)) + + if remote_id not in (0, self.remote_id): + raise InvalidResponseError('Incorrect remote id, expected {0} got {1}'.format(self.remote_id, remote_id)) + # Ack write packets. if cmd == b'WRTE': self.Okay() + return cmd, data def ReadUntilClose(self): - """Yield packets until a Close packet is received.""" + """Yield packets until a ``b'CLSE'`` packet is received. + + .. image:: _static/adb.adb_protocol._AdbConnection.ReadUntilClose.CALL_GRAPH.svg + + Yields + ------ + data : TODO + TODO + + """ while True: cmd, data = self.ReadUntil(b'CLSE', b'WRTE') + if cmd == b'CLSE': self._Send(b'CLSE', arg0=self.local_id, arg1=self.remote_id) break + if cmd != b'WRTE': if cmd == b'FAIL': - raise usb_exceptions.AdbCommandFailureException( - 'Command failed.', data) - raise InvalidCommandError('Expected a WRITE or a CLOSE, got %s (%s)', - cmd, data) + raise usb_exceptions.AdbCommandFailureException('Command failed.', data) + + raise InvalidCommandError('Expected a WRITE or a CLOSE, got {0} ({1})'.format(cmd, data), cmd, data) + yield data def Close(self): + """TODO + + .. image:: _static/adb.adb_protocol._AdbConnection.Close.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol._AdbConnection.Close.CALLER_GRAPH.svg + + Raises + ------ + usb_exceptions.AdbCommandFailureException + Command failed. + adb.adb_protocol.InvalidCommandError + Expected a ``CLSE`` response but received something else. + + """ self._Send(b'CLSE', arg0=self.local_id, arg1=self.remote_id) cmd, data = self.ReadUntil(b'CLSE') if cmd != b'CLSE': if cmd == b'FAIL': raise usb_exceptions.AdbCommandFailureException('Command failed.', data) - raise InvalidCommandError('Expected a CLSE response, got %s (%s)', - cmd, data) + raise InvalidCommandError('Expected a CLSE response, got {0} ({1})'.format(cmd, data), cmd, data) class AdbMessage(object): """ADB Protocol and message class. - Protocol Notes + .. rubric:: local_id/remote_id - local_id/remote_id: - Turns out the documentation is host/device ambidextrous, so local_id is the - id for 'the sender' and remote_id is for 'the recipient'. So since we're - only on the host, we'll re-document with host_id and device_id: + Turns out the documentation is host/device ambidextrous, so ``local_id`` is the id for 'the sender' and + ``remote_id`` is for 'the recipient'. So since we're only on the host, we'll re-document with host_id and device_id: + + :: OPEN(host_id, 0, 'shell:XXX') READY/OKAY(device_id, host_id, '') WRITE(0, host_id, 'data') CLOSE(device_id, host_id, '') + + + .. image:: _static/adb.adb_protocol.AdbMessage.__init__.CALLER_GRAPH.svg + + Parameters + ---------- + command : bytes, None + One of: ``[b'SYNC', b'CNXN', b'AUTH', b'OPEN', b'OKAY', b'CLSE', b'WRTE']`` + arg0 : TODO, None + TODO + arg1 : TODO, None + TODO + data : bytes + TODO + + Attributes + ---------- + command : int + The value in :const:`AdbMessage.commands` that corresponds to the ``command`` parameter + commands : dict + A dictionary with keys ``[b'SYNC', b'CNXN', b'AUTH', b'OPEN', b'OKAY', b'CLSE', b'WRTE']``. + connections : int + TODO + constants : dict + A dictionary with values ``[b'SYNC', b'CNXN', b'AUTH', b'OPEN', b'OKAY', b'CLSE', b'WRTE']``. + format : bytes + The format for unpacking the ADB message. + ids : list[bytes] + ``[b'SYNC', b'CNXN', b'AUTH', b'OPEN', b'OKAY', b'CLSE', b'WRTE']`` + """ ids = [b'SYNC', b'CNXN', b'AUTH', b'OPEN', b'OKAY', b'CLSE', b'WRTE'] @@ -195,10 +456,32 @@ def __init__(self, command=None, arg0=None, arg1=None, data=b''): @property def checksum(self): + """TODO + + .. image:: _static/adb.adb_protocol.AdbMessage.checksum.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol.AdbMessage.checksum.CALLER_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ return self.CalculateChecksum(self.data) @staticmethod def CalculateChecksum(data): + """TODO + + .. image:: _static/adb.adb_protocol.AdbMessage.CalculateChecksum.CALLER_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ # The checksum is just a sum of all the bytes. I swear. if isinstance(data, bytearray): total = sum(data) @@ -215,198 +498,313 @@ def CalculateChecksum(data): return total & 0xFFFFFFFF def Pack(self): - """Returns this message in an over-the-wire format.""" - return struct.pack(self.format, self.command, self.arg0, self.arg1, - len(self.data), self.checksum, self.magic) + """Returns this message in an over-the-wire format. + + .. image:: _static/adb.adb_protocol.AdbMessage.Pack.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol.AdbMessage.Pack.CALLER_GRAPH.svg + + Returns + ------- + bytes + TODO + + """ + return struct.pack(self.format, self.command, self.arg0, self.arg1, len(self.data), self.checksum, self.magic) @classmethod def Unpack(cls, message): + """TODO + + .. image:: _static/adb.adb_protocol.AdbMessage.Unpack.CALLER_GRAPH.svg + + Parameters + ---------- + message : TODO + TODO + + Returns + ------- + cmd : TODO + TODO + arg0 : TODO + TODO + arg1 : TODO + TODO + data_length : TODO + TODO + data_checksum : TODO + TODO + unused_magic : TODO + TODO + + Raises + ------ + ValueError + Unable to unpack the ADB command. + + """ try: - cmd, arg0, arg1, data_length, data_checksum, unused_magic = struct.unpack( - cls.format, message) + cmd, arg0, arg1, data_length, data_checksum, unused_magic = struct.unpack(cls.format, message) except struct.error as e: raise ValueError('Unable to unpack ADB command.', cls.format, message, e) + return cmd, arg0, arg1, data_length, data_checksum def Send(self, usb, timeout_ms=None): - """Send this message over USB.""" + """Send this message over USB. + + .. image:: _static/adb.adb_protocol.AdbMessage.Send.CALL_GRAPH.svg + + Parameters + ---------- + usb : adb.common.TcpHandle, adb.common.UsbHandle + TODO + timeout_ms : int, None + Timeout in milliseconds for USB packets. + + """ usb.BulkWrite(self.Pack(), timeout_ms) usb.BulkWrite(self.data, timeout_ms) @classmethod def Read(cls, usb, expected_cmds, timeout_ms=None, total_timeout_ms=None): - """Receive a response from the device.""" + """Receive a response from the device. + + .. image:: _static/adb.adb_protocol.AdbMessage.Read.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol.AdbMessage.Read.CALLER_GRAPH.svg + + Parameters + ---------- + usb : adb.common.TcpHandle, adb.common.UsbHandle + TODO + expected_cmds : TODO + Read until we receive a header ID that is in ``expected_cmds`` + timeout_ms : int, None + Timeout in milliseconds for USB packets. + total_timeout_ms : int, None + The total time to wait for a command in ``expected_cmds`` + + Returns + ------- + command : TODO + TODO + arg0 : TODO + TODO + arg1 : TODO + TODO + bytes + TODO + + Raises + ------ + adb.adb_protocol.InvalidCommandError + Unknown command *or* never got one of the expected responses. + adb.adb_protocol.InvalidChecksumError + Received checksum does not match the expected checksum. + + """ total_timeout_ms = usb.Timeout(total_timeout_ms) start = time.time() + while True: msg = usb.BulkRead(24, timeout_ms) cmd, arg0, arg1, data_length, data_checksum = cls.Unpack(msg) command = cls.constants.get(cmd) if not command: - raise InvalidCommandError( - 'Unknown command: %x' % cmd, cmd, (arg0, arg1)) + raise InvalidCommandError('Unknown command: %x' % cmd, cmd, (arg0, arg1)) + if command in expected_cmds: break if time.time() - start > total_timeout_ms: - raise InvalidCommandError( - 'Never got one of the expected responses (%s)' % expected_cmds, - cmd, (timeout_ms, total_timeout_ms)) + raise InvalidCommandError('Never got one of the expected responses (%s)' % expected_cmds, cmd, (timeout_ms, total_timeout_ms)) if data_length > 0: data = bytearray() while data_length > 0: temp = usb.BulkRead(data_length, timeout_ms) if len(temp) != data_length: - print( - "Data_length {} does not match actual number of bytes read: {}".format(data_length, len(temp))) + print("Data_length {} does not match actual number of bytes read: {}".format(data_length, len(temp))) data += temp data_length -= len(temp) actual_checksum = cls.CalculateChecksum(data) if actual_checksum != data_checksum: - raise InvalidChecksumError( - 'Received checksum %s != %s', (actual_checksum, data_checksum)) + raise InvalidChecksumError('Received checksum {0} != {1}'.format(actual_checksum, data_checksum)) else: data = b'' + return command, arg0, arg1, bytes(data) @classmethod def Connect(cls, usb, banner=b'notadb', rsa_keys=None, auth_timeout_ms=100): """Establish a new connection to the device. - Args: - usb: A USBHandle with BulkRead and BulkWrite methods. - banner: A string to send as a host identifier. - rsa_keys: List of AuthSigner subclass instances to be used for - authentication. The device can either accept one of these via the Sign - method, or we will send the result of GetPublicKey from the first one - if the device doesn't accept any of them. - auth_timeout_ms: Timeout to wait for when sending a new public key. This - is only relevant when we send a new public key. The device shows a - dialog and this timeout is how long to wait for that dialog. If used - in automation, this should be low to catch such a case as a failure - quickly; while in interactive settings it should be high to allow - users to accept the dialog. We default to automation here, so it's low - by default. - - Returns: - The device's reported banner. Always starts with the state (device, - recovery, or sideload), sometimes includes information after a : with - various product information. - - Raises: - usb_exceptions.DeviceAuthError: When the device expects authentication, - but we weren't given any valid keys. - InvalidResponseError: When the device does authentication in an - unexpected way. + .. image:: _static/adb.adb_protocol.AdbMessage.Connect.CALL_GRAPH.svg + + Parameters + ---------- + usb : adb.common.TcpHandle, adb.common.UsbHandle + A :class:`adb.common.TcpHandle` or :class:`adb.common.UsbHandle` instance with ``BulkRead`` and ``BulkWrite`` methods. + banner : str + A string to send as a host identifier. + rsa_keys : list[adb_protocol.AuthSigner] + List of :class:`AuthSigner` subclass instances to be used for authentication. The device can either accept one of + these via the ``Sign`` method, or we will send the result of ``GetPublicKey`` from the first one if the + device doesn't accept any of them. + auth_timeout_ms : int + Timeout to wait for when sending a new public key. This + is only relevant when we send a new public key. The device shows a + dialog and this timeout is how long to wait for that dialog. If used + in automation, this should be low to catch such a case as a failure + quickly; while in interactive settings it should be high to allow + users to accept the dialog. We default to automation here, so it's low + by default. + + Returns + ------- + banner : TODO + The device's reported banner. Always starts with the state (device, recovery, or sideload), sometimes + includes information after a : with various product information. + + Raises + ------ + adb.usb_exceptions.DeviceAuthError + When the device expects authentication, but we weren't given any valid keys. + adb.adb_protocol.InvalidResponseError + When the device does authentication in an unexpected way. + usb_exceptions.ReadFailedError + TODO + """ # In py3, convert unicode to bytes. In py2, convert str to bytes. # It's later joined into a byte string, so in py2, this ends up kind of being a no-op. if isinstance(banner, str): banner = bytearray(banner, 'utf-8') - msg = cls( - command=b'CNXN', arg0=VERSION, arg1=MAX_ADB_DATA, - data=b'host::%s\0' % banner) + msg = cls(command=b'CNXN', arg0=VERSION, arg1=MAX_ADB_DATA, data=b'host::%s\0' % banner) msg.Send(usb) cmd, arg0, arg1, banner = cls.Read(usb, [b'CNXN', b'AUTH']) if cmd == b'AUTH': if not rsa_keys: - raise usb_exceptions.DeviceAuthError( - 'Device authentication required, no keys available.') + raise usb_exceptions.DeviceAuthError('Device authentication required, no keys available.') + # Loop through our keys, signing the last 'banner' or token. for rsa_key in rsa_keys: if arg0 != AUTH_TOKEN: - raise InvalidResponseError( - 'Unknown AUTH response: %s %s %s' % (arg0, arg1, banner)) + raise InvalidResponseError('Unknown AUTH response: %s %s %s' % (arg0, arg1, banner)) # Do not mangle the banner property here by converting it to a string signed_token = rsa_key.Sign(banner) - msg = cls( - command=b'AUTH', arg0=AUTH_SIGNATURE, arg1=0, data=signed_token) + msg = cls(command=b'AUTH', arg0=AUTH_SIGNATURE, arg1=0, data=signed_token) msg.Send(usb) cmd, arg0, unused_arg1, banner = cls.Read(usb, [b'CNXN', b'AUTH']) if cmd == b'CNXN': return banner + # None of the keys worked, so send a public key. - msg = cls( - command=b'AUTH', arg0=AUTH_RSAPUBLICKEY, arg1=0, - data=rsa_keys[0].GetPublicKey() + b'\0') + msg = cls(command=b'AUTH', arg0=AUTH_RSAPUBLICKEY, arg1=0, data=rsa_keys[0].GetPublicKey() + b'\0') msg.Send(usb) try: - cmd, arg0, unused_arg1, banner = cls.Read( - usb, [b'CNXN'], timeout_ms=auth_timeout_ms) + cmd, arg0, unused_arg1, banner = cls.Read(usb, [b'CNXN'], timeout_ms=auth_timeout_ms) except usb_exceptions.ReadFailedError as e: if e.usb_error.value == -7: # Timeout. - raise usb_exceptions.DeviceAuthError( - 'Accept auth key on device, then retry.') + raise usb_exceptions.DeviceAuthError('Accept auth key on device, then retry.') + raise + # This didn't time-out, so we got a CNXN response. return banner return banner @classmethod def Open(cls, usb, destination, timeout_ms=None): - """Opens a new connection to the device via an OPEN message. + """Opens a new connection to the device via an ``OPEN`` message. + + Not the same as the posix ``open`` or any other google3 Open methods. + + .. image:: _static/adb.adb_protocol.AdbMessage.Open.CALL_GRAPH.svg - Not the same as the posix 'open' or any other google3 Open methods. + .. image:: _static/adb.adb_protocol.AdbMessage.Open.CALLER_GRAPH.svg - Args: - usb: USB device handle with BulkRead and BulkWrite methods. - destination: The service:command string. - timeout_ms: Timeout in milliseconds for USB packets. + Parameters + ---------- + usb : adb.common.TcpHandle, adb.common.UsbHandle + A :class:`adb.common.TcpHandle` or :class:`adb.common.UsbHandle` instance with ``BulkRead`` and ``BulkWrite`` methods. + destination : TODO + The service:command string. + timeout_ms : int, None + Timeout in milliseconds for USB packets. - Raises: - InvalidResponseError: Wrong local_id sent to us. - InvalidCommandError: Didn't get a ready response. + Returns + ------- + _AdbConnection, None + The local connection id. + + Raises + ------ + adb.adb_protocol.InvalidResponseError + Wrong local_id sent to us. + adb.adb_protocol.InvalidCommandError + Didn't get a ready response. - Returns: - The local connection id. """ local_id = 1 - msg = cls( - command=b'OPEN', arg0=local_id, arg1=0, - data=destination + b'\0') + msg = cls(command=b'OPEN', arg0=local_id, arg1=0, data=destination + b'\0') msg.Send(usb, timeout_ms) - cmd, remote_id, their_local_id, _ = cls.Read(usb, [b'CLSE', b'OKAY'], - timeout_ms=timeout_ms) + cmd, remote_id, their_local_id, _ = cls.Read(usb, [b'CLSE', b'OKAY'], timeout_ms=timeout_ms) + if local_id != their_local_id: - raise InvalidResponseError( - 'Expected the local_id to be {}, got {}'.format(local_id, their_local_id)) + raise InvalidResponseError('Expected the local_id to be {}, got {}'.format(local_id, their_local_id)) + if cmd == b'CLSE': # Some devices seem to be sending CLSE once more after a request, this *should* handle it - cmd, remote_id, their_local_id, _ = cls.Read(usb, [b'CLSE', b'OKAY'], - timeout_ms=timeout_ms) + cmd, remote_id, their_local_id, _ = cls.Read(usb, [b'CLSE', b'OKAY'], timeout_ms=timeout_ms) # Device doesn't support this service. if cmd == b'CLSE': return None + if cmd != b'OKAY': - raise InvalidCommandError('Expected a ready response, got {}'.format(cmd), - cmd, (remote_id, their_local_id)) + raise InvalidCommandError('Expected a ready response, got {}'.format(cmd), cmd, (remote_id, their_local_id)) + return _AdbConnection(usb, local_id, remote_id, timeout_ms) @classmethod def Command(cls, usb, service, command='', timeout_ms=None): """One complete set of USB packets for a single command. - Sends service:command in a new connection, reading the data for the + Sends ``service:command`` in a new connection, reading the data for the response. All the data is held in memory, large responses will be slow and can fill up memory. - Args: - usb: USB device handle with BulkRead and BulkWrite methods. - service: The service on the device to talk to. - command: The command to send to the service. - timeout_ms: Timeout for USB packets, in milliseconds. + .. image:: _static/adb.adb_protocol.AdbMessage.Command.CALL_GRAPH.svg + + Parameters + ---------- + usb : adb.common.TcpHandle, adb.common.UsbHandle + A :class:`adb.common.TcpHandle` or :class:`adb.common.UsbHandle` instance with ``BulkRead`` and ``BulkWrite`` methods. + service : TODO + The service on the device to talk to. + command : str + The command to send to the service. + timeout_ms : int, None + Timeout in milliseconds for USB packets. + + Returns + ------- + str + The response from the service. + + Raises + ------ + adb.adb_protocol.InterleavedDataError + Multiple streams running over usb. + adb.adb_protocol.InvalidCommandError + Got an unexpected response command. - Raises: - InterleavedDataError: Multiple streams running over usb. - InvalidCommandError: Got an unexpected response command. - - Returns: - The response from the service. """ return ''.join(cls.StreamingCommand(usb, service, command, timeout_ms)) @@ -414,28 +812,42 @@ def Command(cls, usb, service, command='', timeout_ms=None): def StreamingCommand(cls, usb, service, command='', timeout_ms=None): """One complete set of USB packets for a single command. - Sends service:command in a new connection, reading the data for the + Sends ``service:command`` in a new connection, reading the data for the response. All the data is held in memory, large responses will be slow and can fill up memory. - Args: - usb: USB device handle with BulkRead and BulkWrite methods. - service: The service on the device to talk to. - command: The command to send to the service. - timeout_ms: Timeout for USB packets, in milliseconds. - - Raises: - InterleavedDataError: Multiple streams running over usb. - InvalidCommandError: Got an unexpected response command. + .. image:: _static/adb.adb_protocol.AdbMessage.StreamingCommand.CALL_GRAPH.svg + + .. image:: _static/adb.adb_protocol.AdbMessage.StreamingCommand.CALLER_GRAPH.svg + + Parameters + ---------- + usb : adb.common.TcpHandle, adb.common.UsbHandle + A :class:`adb.common.TcpHandle` or :class:`adb.common.UsbHandle` instance with ``BulkRead`` and ``BulkWrite`` methods. + service : TODO + The service on the device to talk to. + command : str + The command to send to the service. + timeout_ms : int, None + Timeout in milliseconds for USB packets. + + Yields + ------ + str + The responses from the service. + + Raises + ------ + adb.adb_protocol.InterleavedDataError + Multiple streams running over usb. + adb.adb_protocol.InvalidCommandError + Got an unexpected response command. - Yields: - The responses from the service. """ if not isinstance(command, bytes): command = command.encode('utf8') - connection = cls.Open( - usb, destination=b'%s:%s' % (service, command), - timeout_ms=timeout_ms) + + connection = cls.Open(usb, destination=b'%s:%s' % (service, command), timeout_ms=timeout_ms) for data in connection.ReadUntilClose(): yield data.decode('utf8') @@ -444,18 +856,29 @@ def InteractiveShellCommand(cls, conn, cmd=None, strip_cmd=True, delim=None, str """Retrieves stdout of the current InteractiveShell and sends a shell command if provided TODO: Should we turn this into a yield based function so we can stream all output? - Args: - conn: Instance of AdbConnection - cmd: Optional. Command to run on the target. - strip_cmd: Optional (default True). Strip command name from stdout. - delim: Optional. Delimiter to look for in the output to know when to stop expecting more output - (usually the shell prompt) - strip_delim: Optional (default True): Strip the provided delimiter from the output - clean_stdout: Cleanup the stdout stream of any backspaces and the characters that were deleted by the backspace - Returns: - The stdout from the shell command. - """ + .. image:: _static/adb.adb_protocol.AdbMessage.InteractiveShellCommand.CALL_GRAPH.svg + + Parameters + ---------- + conn : AdbConnection + Instance of AdbConnection + cmd : str, None + Command to run on the target. + strip_cmd : bool + Strip command name from stdout. + delim : TODO + Delimiter to look for in the output to know when to stop expecting more output (usually the shell prompt) + strip_delim : bool + Strip the provided delimiter from the output + clean_stdout : bool + Cleanup the stdout stream of any backspaces and the characters that were deleted by the backspace + + Returns + ------- + stdout : TODO + The stdout from the shell command. + """ if delim is not None and not isinstance(delim, bytes): delim = delim.encode('utf-8') @@ -484,7 +907,7 @@ def InteractiveShellCommand(cls, conn, cmd=None, strip_cmd=True, delim=None, str cmd = cmd.encode('utf8') # Send the cmd raw - bytes_written = conn.Write(cmd) + conn.Write(cmd) if delim: # Expect multiple WRTE cmds until the delim (usually terminal prompt) is detected @@ -557,7 +980,7 @@ def InteractiveShellCommand(cls, conn, cmd=None, strip_cmd=True, delim=None, str stdout = stdout.rstrip() - except Exception as e: + except Exception as e: # pylint: disable=broad-except print("InteractiveShell exception (most likely timeout): {}".format(e)) return stdout diff --git a/adb/common.py b/adb/common.py index 0c78728..51a9f84 100644 --- a/adb/common.py +++ b/adb/common.py @@ -11,40 +11,125 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """Common code for ADB and Fastboot. -Common usb browsing, and usb communication. +Common usb browsing and usb communication. + + +.. rubric:: Contents + +* :func:`GetInterface` +* :func:`InterfaceMatcher` +* :class:`TcpHandle` + + * :meth:`TcpHandle._connect` + * :meth:`TcpHandle.BulkRead` + * :meth:`TcpHandle.BulkWrite` + * :meth:`TcpHandle.Close` + * :meth:`TcpHandle.serial_number` + * :meth:`TcpHandle.Timeout` + * :meth:`TcpHandle.TimeoutSeconds` + +* :class:`UsbHandle` + + * :meth:`UsbHandle.BulkRead` + * :meth:`UsbHandle.BulkReadAsync` + * :meth:`UsbHandle.BulkWrite` + * :meth:`UsbHandle.Close` + * :meth:`UsbHandle.Find` + * :meth:`UsbHandle.FindAndOpen` + * :meth:`UsbHandle.FindDevices` + * :meth:`UsbHandle.FindFirst` + * :meth:`UsbHandle.FlushBuffers` + * :meth:`UsbHandle.Open` + * :meth:`UsbHandle.port_path` + * :meth:`UsbHandle.PortPathMatcher` + * :meth:`UsbHandle.serial_number` + * :meth:`UsbHandle.SerialMatcher` + * :meth:`UsbHandle.Timeout` + * :meth:`UsbHandle.usb_info` + """ + import logging import platform +import re +import select import socket import threading import weakref -import select import libusb1 import usb1 +try: + from libusb1 import LIBUSB_ERROR_NOT_FOUND, LIBUSB_ERROR_TIMEOUT # pylint: disable=ungrouped-imports +except ImportError: # pragma: no cover + LIBUSB_ERROR_NOT_FOUND = 'LIBUSB_ERROR_NOT_FOUND' + LIBUSB_ERROR_TIMEOUT = 'LIBUSB_ERROR_TIMEOUT' + from adb import usb_exceptions + +#: Default timeout DEFAULT_TIMEOUT_MS = 10000 +SYSFS_PORT_SPLIT_RE = re.compile("[,/:.-]") + _LOG = logging.getLogger('android_usb') def GetInterface(setting): - """Get the class, subclass, and protocol for the given USB setting.""" + """Get the class, subclass, and protocol for the given USB setting. + + .. image:: _static/adb.common.GetInterface.CALLER_GRAPH.svg + + Parameters + ---------- + setting : TODO + TODO + + Returns + ------- + TODO + TODO + TODO + TODO + TODO + TODO + + """ return (setting.getClass(), setting.getSubClass(), setting.getProtocol()) def InterfaceMatcher(clazz, subclass, protocol): - """Returns a matcher that returns the setting with the given interface.""" + """Returns a matcher that returns the setting with the given interface. + + .. image:: _static/adb.common.InterfaceMatcher.CALL_GRAPH.svg + + Parameters + ---------- + clazz : TODO + TODO + subclass : TODO + TODO + protocol : TODO + TODO + + Returns + ------- + Matcher : function + TODO + + """ interface = (clazz, subclass, protocol) def Matcher(device): for setting in device.iterSettings(): if GetInterface(setting) == interface: return setting + return None return Matcher @@ -56,33 +141,76 @@ class UsbHandle(object): and interface claiming. Important methods: - FlushBuffers() - BulkRead(int length) - BulkWrite(bytes data) - """ + * `UsbHandle.FlushBuffers` + * `UsbHandle.BulkRead` + * `UsbHandle.BulkWrite(bytes data)` + + .. image:: _static/adb.common.UsbHandle.__init__.CALLER_GRAPH.svg + + Parameters + ---------- + device : TODO + libusb_device to connect to. + setting : TODO + libusb setting with the correct endpoints to communicate with. + usb_info : TODO, None + String describing the usb path/serial/device, for debugging. + timeout_ms : TODO, None + Timeout in milliseconds for all I/O. + + Attributes + ---------- + _device : TODO + libusb_device to connect to. + _handle : TODO + TODO + _interface_number : TODO + TODO + _max_read_packet_len : TODO + TODO + _read_endpoint : TODO + TODO + _setting : TODO + libusb setting with the correct endpoints to communicate with. + _timeout_ms : TODO, None + Timeout in milliseconds for all I/O. + _usb_info : TODO + String describing the usb path/serial/device, for debugging. + _write_endpoint : TODO, None + TODO + """ _HANDLE_CACHE = weakref.WeakValueDictionary() _HANDLE_CACHE_LOCK = threading.Lock() def __init__(self, device, setting, usb_info=None, timeout_ms=None): - """Initialize USB Handle. - - Arguments: - device: libusb_device to connect to. - setting: libusb setting with the correct endpoints to communicate with. - usb_info: String describing the usb path/serial/device, for debugging. - timeout_ms: Timeout in milliseconds for all I/O. - """ + """Initialize USB Handle.""" self._setting = setting self._device = device self._handle = None + self._interface_number = None + self._read_endpoint = None + self._write_endpoint = None + self._usb_info = usb_info or '' self._timeout_ms = timeout_ms if timeout_ms else DEFAULT_TIMEOUT_MS self._max_read_packet_len = 0 @property def usb_info(self): + """TODO + + .. image:: _static/adb.common.UsbHandle.usb_info.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.usb_info.CALLER_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ try: sn = self.serial_number except libusb1.USBError: @@ -92,7 +220,11 @@ def usb_info(self): return self._usb_info def Open(self): - """Opens the USB device for this setting, and claims the interface.""" + """Opens the USB device for this setting, and claims the interface. + + .. image:: _static/adb.common.UsbHandle.Open.CALL_GRAPH.svg + + """ # Make sure we close any previous handle open to this usb device. port_path = tuple(self.port_path) with self._HANDLE_CACHE_LOCK: @@ -117,11 +249,10 @@ def Open(self): handle = self._device.open() iface_number = self._setting.getNumber() try: - if (platform.system() != 'Windows' - and handle.kernelDriverActive(iface_number)): + if (platform.system() != 'Windows' and handle.kernelDriverActive(iface_number)): handle.detachKernelDriver(iface_number) except libusb1.USBError as e: - if e.value == libusb1.LIBUSB_ERROR_NOT_FOUND: + if e.value == LIBUSB_ERROR_NOT_FOUND: _LOG.warning('Kernel driver not found for interface: %s.', iface_number) else: raise @@ -136,13 +267,40 @@ def Open(self): @property def serial_number(self): + """TODO + + .. image:: _static/adb.common.UsbHandle.serial_number.CALLER_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ return self._device.getSerialNumber() @property def port_path(self): + """TODO + + .. image:: _static/adb.common.UsbHandle.port_path.CALLER_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ return [self._device.getBusNumber()] + self._device.getPortNumberList() def Close(self): + """TODO + + .. image:: _static/adb.common.UsbHandle.Close.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.Close.CALLER_GRAPH.svg + + """ if self._handle is None: return try: @@ -155,53 +313,144 @@ def Close(self): self._handle = None def Timeout(self, timeout_ms): + """TODO + + .. image:: _static/adb.common.UsbHandle.Timeout.CALLER_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ return timeout_ms if timeout_ms is not None else self._timeout_ms def FlushBuffers(self): + """TODO + + .. image:: _static/adb.common.UsbHandle.FlushBuffers.CALL_GRAPH.svg + + Raises + ------ + adb.usb_exceptions.ReadFailedError + TODO + + """ while True: try: self.BulkRead(self._max_read_packet_len, timeout_ms=10) except usb_exceptions.ReadFailedError as e: - if e.usb_error.value == libusb1.LIBUSB_ERROR_TIMEOUT: + if e.usb_error.value == LIBUSB_ERROR_TIMEOUT: break raise def BulkWrite(self, data, timeout_ms=None): + """TODO + + .. image:: _static/adb.common.UsbHandle.BulkWrite.CALL_GRAPH.svg + + Parameters + ---------- + data : bytes + TODO + timeout_ms : TODO, None + TODO + + Returns + ------- + TODO + TODO + + Raises + ------ + adb.usb_exceptions.WriteFailedError + This handle has been closed, probably due to another being opened + adb.usb_exceptions.WriteFailedError + Could not send data + + """ if self._handle is None: - raise usb_exceptions.WriteFailedError( - 'This handle has been closed, probably due to another being opened.', - None) + raise usb_exceptions.WriteFailedError('This handle has been closed, probably due to another being opened.', None) + try: - return self._handle.bulkWrite( - self._write_endpoint, data, timeout=self.Timeout(timeout_ms)) + return self._handle.bulkWrite(self._write_endpoint, data, timeout=self.Timeout(timeout_ms)) + except libusb1.USBError as e: - raise usb_exceptions.WriteFailedError( - 'Could not send data to %s (timeout %sms)' % ( - self.usb_info, self.Timeout(timeout_ms)), e) + raise usb_exceptions.WriteFailedError('Could not send data to %s (timeout %sms)' % (self.usb_info, self.Timeout(timeout_ms)), e) def BulkRead(self, length, timeout_ms=None): + """TODO + + .. image:: _static/adb.common.UsbHandle.BulkRead.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.BulkRead.CALLER_GRAPH.svg + + Parameters + ---------- + length : int + TODO + timeout_ms : TODO, None + TODO + + Returns + ------- + bytearray + TODO + + Raises + ------ + usb_exceptions.ReadFailedError + Could not receive data + + """ if self._handle is None: - raise usb_exceptions.ReadFailedError( - 'This handle has been closed, probably due to another being opened.', - None) + raise usb_exceptions.ReadFailedError('This handle has been closed, probably due to another being opened.', None) try: # python-libusb1 > 1.6 exposes bytearray()s now instead of bytes/str. # To support older and newer versions, we ensure everything's bytearray() # from here on out. - return bytearray(self._handle.bulkRead( - self._read_endpoint, length, timeout=self.Timeout(timeout_ms))) + return bytearray(self._handle.bulkRead(self._read_endpoint, length, timeout=self.Timeout(timeout_ms))) except libusb1.USBError as e: - raise usb_exceptions.ReadFailedError( - 'Could not receive data from %s (timeout %sms)' % ( - self.usb_info, self.Timeout(timeout_ms)), e) + raise usb_exceptions.ReadFailedError('Could not receive data from %s (timeout %sms)' % (self.usb_info, self.Timeout(timeout_ms)), e) def BulkReadAsync(self, length, timeout_ms=None): + """TODO + + Parameters + ---------- + length : int + TODO + timeout_ms : TODO, None + TODO + + Raises + ------ + NotImplementedError + This is always raised because this method is not implemented. + + """ # See: https://pypi.python.org/pypi/libusb1 "Asynchronous I/O" section - return + raise NotImplementedError @classmethod def PortPathMatcher(cls, port_path): - """Returns a device matcher for the given port path.""" + """Returns a device matcher for the given port path. + + .. image:: _static/adb.common.UsbHandle.SerialMatcher.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.PortPathMatcher.CALLER_GRAPH.svg + + Parameters + ---------- + port_path : TODO + TODO + + Returns + ------- + function + TODO + + """ if isinstance(port_path, str): # Convert from sysfs path to port_path. port_path = [int(part) for part in SYSFS_PORT_SPLIT_RE.split(port_path)] @@ -209,22 +458,78 @@ def PortPathMatcher(cls, port_path): @classmethod def SerialMatcher(cls, serial): - """Returns a device matcher for the given serial.""" + """Returns a device matcher for the given serial. + + .. image:: _static/adb.common.UsbHandle.SerialMatcher.CALLER_GRAPH.svg + + Parameters + ---------- + serial : TODO + TODO + + Returns + ------- + function + TODO + + """ return lambda device: device.serial_number == serial @classmethod - def FindAndOpen(cls, setting_matcher, - port_path=None, serial=None, timeout_ms=None): - dev = cls.Find( - setting_matcher, port_path=port_path, serial=serial, - timeout_ms=timeout_ms) + def FindAndOpen(cls, setting_matcher, port_path=None, serial=None, timeout_ms=None): + """TODO + + .. image:: _static/adb.common.UsbHandle.FindAndOpen.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.FindAndOpen.CALLER_GRAPH.svg + + Parameters + ---------- + setting_matcher : TODO + TODO + port_path : TODO, None + TODO + serial : TODO, None + TODO + timeout_ms : TODO, None + TODO + + Returns + ------- + dev : TODO + TODO + + """ + dev = cls.Find(setting_matcher, port_path=port_path, serial=serial, timeout_ms=timeout_ms) dev.Open() dev.FlushBuffers() return dev @classmethod def Find(cls, setting_matcher, port_path=None, serial=None, timeout_ms=None): - """Gets the first device that matches according to the keyword args.""" + """Gets the first device that matches according to the keyword args. + + .. image:: _static/adb.common.UsbHandle.Find.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.Find.CALLER_GRAPH.svg + + Parameters + ---------- + setting_matcher : TODO + TODO + port_path : TODO, None + TODO + serial : TODO, None + TODO + timeout_ms : TODO, None + TODO + + Returns + ------- + TODO + TODO + + """ if port_path: device_matcher = cls.PortPathMatcher(port_path) usb_info = port_path @@ -234,46 +539,66 @@ def Find(cls, setting_matcher, port_path=None, serial=None, timeout_ms=None): else: device_matcher = None usb_info = 'first' - return cls.FindFirst(setting_matcher, device_matcher, - usb_info=usb_info, timeout_ms=timeout_ms) + return cls.FindFirst(setting_matcher, device_matcher, usb_info=usb_info, timeout_ms=timeout_ms) @classmethod def FindFirst(cls, setting_matcher, device_matcher=None, **kwargs): """Find and return the first matching device. - Args: - setting_matcher: See cls.FindDevices. - device_matcher: See cls.FindDevices. - **kwargs: See cls.FindDevices. + .. image:: _static/adb.common.UsbHandle.FindFirst.CALL_GRAPH.svg + + .. image:: _static/adb.common.UsbHandle.FindFirst.CALLER_GRAPH.svg + + Parameters + ---------- + setting_matcher : TODO + See :meth:`UsbHandle.FindDevices`. + device_matcher : TODO + See :meth:`UsbHandle.FindDevices`. + **kwargs : TODO + See :meth:`UsbHandle.FindDevices`. - Returns: - An instance of UsbHandle. + Returns + ------- + TODO + An instance of UsbHandle. + + Raises + ------ + adb.usb_exceptions.DeviceNotFoundError + Raised if the device is not available. - Raises: - DeviceNotFoundError: Raised if the device is not available. """ try: - return next(cls.FindDevices( - setting_matcher, device_matcher=device_matcher, **kwargs)) + return next(cls.FindDevices(setting_matcher, device_matcher=device_matcher, **kwargs)) except StopIteration: - raise usb_exceptions.DeviceNotFoundError( - 'No device available, or it is in the wrong configuration.') + raise usb_exceptions.DeviceNotFoundError('No device available, or it is in the wrong configuration.') @classmethod def FindDevices(cls, setting_matcher, device_matcher=None, usb_info='', timeout_ms=None): """Find and yield the devices that match. - Args: - setting_matcher: Function that returns the setting to use given a - usb1.USBDevice, or None if the device doesn't have a valid setting. - device_matcher: Function that returns True if the given UsbHandle is - valid. None to match any device. - usb_info: Info string describing device(s). - timeout_ms: Default timeout of commands in milliseconds. + .. image:: _static/adb.common.UsbHandle.FindDevices.CALLER_GRAPH.svg + + Parameters + ---------- + setting_matcher : TODO + Function that returns the setting to use given a ``usb1.USBDevice``, or ``None`` + if the device doesn't have a valid setting. + device_matcher : TODO, None + Function that returns ``True`` if the given ``UsbHandle`` is + valid. ``None`` to match any device. + usb_info : str + Info string describing device(s). + timeout_ms : TODO, None + Default timeout of commands in milliseconds. + + Yields + ------ + TODO + UsbHandle instances - Yields: - UsbHandle instances """ ctx = usb1.USBContext() for device in ctx.getDeviceList(skip_on_error=True): @@ -289,15 +614,32 @@ def FindDevices(cls, setting_matcher, device_matcher=None, class TcpHandle(object): """TCP connection object. - Provides same interface as UsbHandle. """ + Provides same interface as `UsbHandle`. + + .. image:: _static/adb.common.TcpHandle.__init__.CALLER_GRAPH.svg + + Parameters + ---------- + serial : str, bytes, bytearray + Android device serial of the form "host" or "host:port". (Host may be an IP address or a host name.) + timeout_ms : TODO, None + TODO + + Attributes + ---------- + _connection : TODO, None + TODO + _serial_number : str + ``:`` + _timeout_ms : float, None + TODO + host : str, TODO + TODO + port : str, int, TODO + TODO + """ def __init__(self, serial, timeout_ms=None): - """Initialize the TCP Handle. - Arguments: - serial: Android device serial of the form host or host:port. - - Host may be an IP address or a host name. - """ # if necessary, convert serial to a unicode string if isinstance(serial, (bytes, bytearray)): serial = serial.decode('utf-8') @@ -315,40 +657,136 @@ def __init__(self, serial, timeout_ms=None): self._connect() def _connect(self): + """TODO + + .. image:: _static/adb.common.TcpHandle._connect.CALL_GRAPH.svg + + """ timeout = self.TimeoutSeconds(self._timeout_ms) - self._connection = socket.create_connection((self.host, self.port), - timeout=timeout) + self._connection = socket.create_connection((self.host, self.port), timeout=timeout) if timeout: self._connection.setblocking(0) @property def serial_number(self): + """TODO + + .. image:: _static/adb.common.TcpHandle.serial_number.CALLER_GRAPH.svg + + Returns + ------- + self._serial_number : str + The ``_serial_number`` attribute (``:``) + + """ return self._serial_number def BulkWrite(self, data, timeout=None): + """TODO + + .. image:: _static/adb.common.TcpHandle.BulkWrite.CALL_GRAPH.svg + + Parameters + ---------- + data : TODO + TODO + timeout : TODO, None + TODO + + Returns + ------- + TODO + TODO + + Raises + ------ + adb.usb_exceptions.TcpTimeoutException + Sending data timed out. No data was sent. + + """ t = self.TimeoutSeconds(timeout) _, writeable, _ = select.select([], [self._connection], [], t) if writeable: return self._connection.send(data) - msg = 'Sending data to {} timed out after {}s. No data was sent.'.format( - self.serial_number, t) + msg = 'Sending data to {} timed out after {}s. No data was sent.'.format(self.serial_number, t) raise usb_exceptions.TcpTimeoutException(msg) def BulkRead(self, numbytes, timeout=None): + """TODO + + .. image:: _static/adb.common.TcpHandle.BulkRead.CALL_GRAPH.svg + + Parameters + ---------- + numbytes : int + TODO + timeout_ms : TODO, None + TODO + + Returns + ------- + TODO + TODO + + Raises + ------ + adb.usb_exceptions.TcpTimeoutException + Reading timed out. + + """ t = self.TimeoutSeconds(timeout) readable, _, _ = select.select([self._connection], [], [], t) if readable: return self._connection.recv(numbytes) - msg = 'Reading from {} timed out (Timeout {}s)'.format( - self._serial_number, t) + msg = 'Reading from {} timed out (Timeout {}s)'.format(self._serial_number, t) raise usb_exceptions.TcpTimeoutException(msg) def Timeout(self, timeout_ms): + """TODO + + .. image:: _static/adb.common.TcpHandle.Timeout.CALLER_GRAPH.svg + + Parameters + ---------- + timeout_ms : TODO + TODO + + Returns + ------- + float + TODO + + """ return float(timeout_ms) if timeout_ms is not None else self._timeout_ms def TimeoutSeconds(self, timeout_ms): + """TODO + + .. image:: _static/adb.common.TcpHandle.TimeoutSeconds.CALL_GRAPH.svg + + .. image:: _static/adb.common.TcpHandle.TimeoutSeconds.CALLER_GRAPH.svg + + Parameters + ---------- + timeout_ms : TODO + TODO + + Returns + ------- + float + TODO + + """ timeout = self.Timeout(timeout_ms) return timeout / 1000.0 if timeout is not None else timeout def Close(self): + """TODO + + Returns + ------- + TODO + TODO + + """ return self._connection.close() diff --git a/adb/common_cli.py b/adb/common_cli.py index b4ab5e8..83f972f 100644 --- a/adb/common_cli.py +++ b/adb/common_cli.py @@ -11,12 +11,26 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """Common code for ADB and Fastboot CLI. Usage introspects the given class for methods, args, and docs to show the user. -StartCli handles connecting to a device, calling the expected method, and +:func:`StartCli` handles connecting to a device, calling the expected method, and outputting the results. + + +.. rubric:: Contents + +* :func:`_DocToArgs` +* :class:`_PortPathAction` +* :func:`_RunMethod` +* :func:`GetCommonArguments` +* :func:`GetDeviceArguments` +* :func:`MakeSubparser` +* :class:`PositionalArg` +* :func:`StartCli` + """ from __future__ import print_function @@ -32,68 +46,130 @@ class _PortPathAction(argparse.Action): + """TODO + + .. image:: _static/adb.common_cli._PortPathAction.CALL_GRAPH.svg + + """ def __call__(self, parser, namespace, values, option_string=None): - setattr( - namespace, self.dest, - [int(i) for i in values.replace('/', ',').split(',')]) + setattr(namespace, self.dest, [int(i) for i in values.replace('/', ',').split(',')]) class PositionalArg(argparse.Action): + """A positional CLI argument. + + .. image:: _static/adb.common_cli.PositionalArg.CALL_GRAPH.svg + + """ def __call__(self, parser, namespace, values, option_string=None): namespace.positional.append(values) def GetDeviceArguments(): + """Return a parser for device-related CLI commands. + + Returns + ------- + group : argparse.ArgumentParser + A parser for device-related CLI commands. + + """ group = argparse.ArgumentParser('Device', add_help=False) - group.add_argument( - '--timeout_ms', default=10000, type=int, metavar='10000', - help='Timeout in milliseconds.') - group.add_argument( - '--port_path', action=_PortPathAction, - help='USB port path integers (eg 1,2 or 2,1,1)') - group.add_argument( - '-s', '--serial', - help='Device serial to look for (host:port or USB serial)') + group.add_argument('--timeout_ms', default=10000, type=int, metavar='10000', help='Timeout in milliseconds.') + group.add_argument('--port_path', action=_PortPathAction, help='USB port path integers (eg 1,2 or 2,1,1)') + group.add_argument('-s', '--serial', help='Device serial to look for (host:port or USB serial)') + return group def GetCommonArguments(): + """Return a parser for common CLI commands. + + Returns + ------- + group : argparse.ArgumentParser + A parser for common CLI commands. + + """ group = argparse.ArgumentParser('Common', add_help=False) group.add_argument('--verbose', action='store_true', help='Enable logging') return group def _DocToArgs(doc): - """Converts a docstring documenting arguments into a dict.""" - m = None + """Converts a docstring documenting arguments into a dict. + + .. image:: _static/adb.common_cli._DocToArgs.CALLER_GRAPH.svg + + Parameters + ---------- + doc : str + The docstring for a method; see `MakeSubparser`. + + Returns + ------- + out : dict + A dictionary of arguments and their descriptions from the docstring ``doc``. + + """ offset = None - in_arg = False + param = None out = {} + for l in doc.splitlines(): - if l.strip() == 'Args:': - in_arg = True - elif in_arg: - if not l.strip(): + if l.strip() == 'Parameters': + offset = len(l.rstrip()) - len(l.strip()) + + elif offset: + # The "----------" line + if l.strip() == '-' * len('Parameters'): + continue + + if l.strip() in ['Returns', 'Yields', 'Raises']: break - if offset is None: - offset = len(l) - len(l.lstrip()) - l = l[offset:] - if l[0] == ' ' and m: - out[m.group(1)] += ' ' + l.lstrip() - else: - m = re.match(r'^([a-z_]+): (.+)$', l.strip()) - out[m.group(1)] = m.group(2) + + # start of a parameter + if len(l.rstrip()) - len(l.strip()) == offset: + param = l.strip().split()[0] + out[param] = '' + + # add to a parameter + elif l.strip(): + if out[param]: + out[param] += ' ' + l.strip() + else: + out[param] = l.strip() + return out def MakeSubparser(subparsers, parents, method, arguments=None): - """Returns an argparse subparser to create a 'subcommand' to adb.""" + """Returns an argparse subparser to create a 'subcommand' to adb. + + .. image:: _static/adb.common_cli.MakeSubparser.CALL_GRAPH.svg + + Parameters + ---------- + subparsers : TODO + TODO + parents : TODO + TODO + method : TODO + TODO + arguments : TODO, None + TODO + + Returns + ------- + subparser : TODO + TODO + + """ name = ('-'.join(re.split(r'([A-Z][a-z]+)', method.__name__)[1:-1:2])).lower() - help = method.__doc__.splitlines()[0] - subparser = subparsers.add_parser( - name=name, description=help, help=help.rstrip('.'), parents=parents) + help = method.__doc__.splitlines()[0] # pylint: disable=redefined-builtin + subparser = subparsers.add_parser(name=name, description=help, help=help.rstrip('.'), parents=parents) subparser.set_defaults(method=method, positional=[]) - argspec = inspect.getargspec(method) + argspec = inspect.getfullargspec(method) # Figure out positionals and default argument, if any. Explicitly includes # arguments that default to '' but excludes arguments that default to None. @@ -122,7 +198,25 @@ def MakeSubparser(subparsers, parents, method, arguments=None): def _RunMethod(dev, args, extra): - """Runs a method registered via MakeSubparser.""" + """Runs a method registered via :func:`MakeSubparser`. + + .. image:: _static/adb.common_cli._RunMethod.CALLER_GRAPH.svg + + Parameters + ---------- + dev : TODO + TODO + args : TODO + TODO + extra : TODO + TODO + + Returns + ------- + int + 0 + + """ logging.info('%s(%s)', args.method.__name__, ', '.join(args.positional)) result = args.method(dev, *args.positional, **extra) if result is not None: @@ -144,7 +238,29 @@ def _RunMethod(dev, args, extra): def StartCli(args, adb_commands, extra=None, **device_kwargs): - """Starts a common CLI interface for this usb path and protocol.""" + """Starts a common CLI interface for this usb path and protocol. + + Handles connecting to a device, calling the expected method, and outputting the results. + + .. image:: _static/adb.common_cli.StartCli.CALL_GRAPH.svg + + Parameters + ---------- + args : TODO + TODO + adb_commands : TODO + TODO + extra : TODO, None + TODO + **device_kwargs : TODO + TODO + + Returns + ------- + TODO + TODO + + """ try: dev = adb_commands() dev.ConnectDevice(port_path=args.port_path, serial=args.serial, default_timeout_ms=args.timeout_ms, diff --git a/adb/debug.py b/adb/debug.py new file mode 100644 index 0000000..80372d8 --- /dev/null +++ b/adb/debug.py @@ -0,0 +1,23 @@ +"""TEMPORARY. + +""" + + +TRUE = True # pragma: no cover +FALSE = False # pragma: no cover +PRINTABLE_TYPES = (int, float, str, bool, bytes, bytearray, type(None)) # pragma: no cover + + +def debug_print(name, var): # pragma: no cover + """Print debugging info.""" + if isinstance(var, PRINTABLE_TYPES): + print("type({}) = {}, value = {}".format(name, type(var).__name__, var)) + elif isinstance(var, (tuple, list)): + if not var: + print("type({}) = {}, value = {}".format(name, type(var).__name__, var)) + elif isinstance(var[0], PRINTABLE_TYPES): + print("type({}) = {}[{}], value = {}".format(name, type(var).__name__, type(var[0]).__name__, var)) + else: + print("type({}) = {}[{}]".format(name, type(var).__name__, type(var[0]).__name__)) + else: + print("type({}) = {}".format(name, type(var).__name__)) diff --git a/adb/fastboot.py b/adb/fastboot.py index 1507494..f05d107 100644 --- a/adb/fastboot.py +++ b/adb/fastboot.py @@ -11,7 +11,46 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""A libusb1-based fastboot implementation.""" + +"""A libusb1-based fastboot implementation. + + +.. rubric:: Contents + +* :class:`FastbootCommands` + + * :meth:`FastbootCommands.__reset` + * :meth:`FastbootCommands._SimpleCommand` + * :meth:`FastbootCommands.Close` + * :meth:`FastbootCommands.ConnectDevice` + * :meth:`FastbootCommands.Continue` + * :meth:`FastbootCommands.Devices` + * :meth:`FastbootCommands.Download` + * :meth:`FastbootCommands.Erase` + * :meth:`FastbootCommands.Flash` + * :meth:`FastbootCommands.FlashFromFile` + * :meth:`FastbootCommands.Getvar` + * :meth:`FastbootCommands.Oem` + * :meth:`FastbootCommands.Reboot` + * :meth:`FastbootCommands.RebootBootloader` + * :meth:`FastbootCommands.usb_handle` + +* :class:`FastbootInvalidResponse` +* :class:`FastbootProtocol` + + * :meth:`FastbootProtocol._AcceptResponses` + * :meth:`FastbootProtocol._HandleProgress` + * :meth:`FastbootProtocol._Write` + * :meth:`FastbootProtocol.HandleDataSending` + * :meth:`FastbootProtocol.HandleSimpleResponses` + * :meth:`FastbootProtocol.SendCommand` + * :meth:`FastbootProtocol.usb_handle` + +* :class:`FastbootRemoteFailure` +* :class:`FastbootStateMismatch` +* :class:`FastbootTransferError` + +""" import binascii import collections @@ -25,63 +64,113 @@ _LOG = logging.getLogger('fastboot') -DEFAULT_MESSAGE_CALLBACK = lambda m: logging.info('Got %s from device', m) -FastbootMessage = collections.namedtuple( # pylint: disable=invalid-name - 'FastbootMessage', ['message', 'header']) +#: TODO +DEFAULT_MESSAGE_CALLBACK = lambda m: logging.info('Got %s from device', m) # noqa: E731 -# From fastboot.c +#: FastbootMessage +FastbootMessage = collections.namedtuple('FastbootMessage', ['message', 'header']) # pylint: disable=invalid-name + +#: From fastboot.c VENDORS = {0x18D1, 0x0451, 0x0502, 0x0FCE, 0x05C6, 0x22B8, 0x0955, 0x413C, 0x2314, 0x0BB4, 0x8087} + +#: From fastboot.c CLASS = 0xFF + +#: From fastboot.c SUBCLASS = 0x42 + +#: From fastboot.c PROTOCOL = 0x03 -# pylint: disable=invalid-name -DeviceIsAvailable = common.InterfaceMatcher(CLASS, SUBCLASS, PROTOCOL) + +#: TODO +DeviceIsAvailable = common.InterfaceMatcher(CLASS, SUBCLASS, PROTOCOL) # pylint: disable=invalid-name # pylint doesn't understand cross-module exception baseclasses. -# pylint: disable=nonstandard-exception +# pylint: disable=bad-option-value class FastbootTransferError(usb_exceptions.FormatMessageWithArgumentsException): - """Transfer error.""" + """Transfer error. + + .. image:: _static/adb.fastboot.FastbootTransferError.CALL_GRAPH.svg + + """ class FastbootRemoteFailure(usb_exceptions.FormatMessageWithArgumentsException): - """Remote error.""" + """Remote error. + + .. image:: _static/adb.fastboot.FastbootRemoteFailure.CALL_GRAPH.svg + + """ class FastbootStateMismatch(usb_exceptions.FormatMessageWithArgumentsException): - """Fastboot and uboot's state machines are arguing. You Lose.""" + """Fastboot and uboot's state machines are arguing. You Lose. + .. image:: _static/adb.fastboot.FastbootStateMismatch.CALL_GRAPH.svg -class FastbootInvalidResponse( - usb_exceptions.FormatMessageWithArgumentsException): - """Fastboot responded with a header we didn't expect.""" + """ + + +class FastbootInvalidResponse(usb_exceptions.FormatMessageWithArgumentsException): + """Fastboot responded with a header we didn't expect. + + .. image:: _static/adb.fastboot.FastbootInvalidResponse.CALL_GRAPH.svg + + """ class FastbootProtocol(object): - """Encapsulates the fastboot protocol.""" + """Encapsulates the fastboot protocol. + + .. image:: _static/adb.fastboot.FastbootProtocol.__init__.CALLER_GRAPH.svg + + Parameters + ---------- + usb : adb.common.UsbHandle + :class:`adb.common.UsbHandle` instance. + chunk_kb : int + Packet size. For older devices, 4 may be required. + + Attributes + ---------- + chunk_kb : int + Packet size. For older devices, 4 may be required. + usb : adb.common.UsbHandle + :class:`adb.common.UsbHandle` instance. + + """ FINAL_HEADERS = {b'OKAY', b'DATA'} def __init__(self, usb, chunk_kb=1024): - """Constructs a FastbootProtocol instance. - - Args: - usb: UsbHandle instance. - chunk_kb: Packet size. For older devices, 4 may be required. - """ self.usb = usb self.chunk_kb = chunk_kb @property def usb_handle(self): + """TODO + + Returns + ------- + self.usb : adb.common.UsbHandle + :class:`adb.common.UsbHandle` instance. + + """ return self.usb def SendCommand(self, command, arg=None): """Sends a command to the device. - Args: - command: The command to send. - arg: Optional argument to the command. + .. image:: _static/adb.fastboot.FastbootProtocol.SendCommand.CALL_GRAPH.svg + + Parameters + ---------- + command : str + The command to send. + arg : str + Optional argument to the command. + """ if arg is not None: if not isinstance(arg, bytes): @@ -90,16 +179,25 @@ def SendCommand(self, command, arg=None): self._Write(io.BytesIO(command), len(command)) - def HandleSimpleResponses( - self, timeout_ms=None, info_cb=DEFAULT_MESSAGE_CALLBACK): + def HandleSimpleResponses(self, timeout_ms=None, info_cb=DEFAULT_MESSAGE_CALLBACK): """Accepts normal responses from the device. - Args: - timeout_ms: Timeout in milliseconds to wait for each response. - info_cb: Optional callback for text sent from the bootloader. + .. image:: _static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALL_GRAPH.svg + + .. image:: _static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALLER_GRAPH.svg + + Parameters + ---------- + timeout_ms : TODO, None + Timeout in milliseconds to wait for each response. + info_cb : TODO + Optional callback for text sent from the bootloader. + + Returns + ------- + TODO + OKAY packet's message. - Returns: - OKAY packet's message. """ return self._AcceptResponses(b'OKAY', info_cb, timeout_ms=timeout_ms) @@ -108,50 +206,79 @@ def HandleDataSending(self, source_file, source_len, progress_callback=None, timeout_ms=None): """Handles the protocol for sending data to the device. - Args: - source_file: File-object to read from for the device. - source_len: Amount of data, in bytes, to send to the device. - info_cb: Optional callback for text sent from the bootloader. - progress_callback: Callback that takes the current and the total progress - of the current file. - timeout_ms: Timeout in milliseconds to wait for each response. - - Raises: - FastbootTransferError: When fastboot can't handle this amount of data. - FastbootStateMismatch: Fastboot responded with the wrong packet type. - FastbootRemoteFailure: Fastboot reported failure. - FastbootInvalidResponse: Fastboot responded with an unknown packet type. - - Returns: - OKAY packet's message. + .. image:: _static/adb.fastboot.FastbootProtocol.HandleDataSending.CALL_GRAPH.svg + + .. image:: _static/adb.fastboot.FastbootProtocol.HandleDataSending.CALLER_GRAPH.svg + + Parameters + ---------- + source_file : TODO + File-object to read from for the device. + source_len : TODO + Amount of data, in bytes, to send to the device. + info_cb : TODO + Optional callback for text sent from the bootloader. + progress_callback : TODO, None + Callback that takes the current and the total progress of the current file. + timeout_ms : TODO, None + Timeout in milliseconds to wait for each response. + + Returns + ------- + TODO + OKAY packet's message. + + Raises + ------ + adb.fastboot.FastbootTransferError + When fastboot can't handle this amount of data. + adb.fastboot.FastbootStateMismatch + Fastboot responded with the wrong packet type. + adb.fastboot.FastbootRemoteFailure + Fastboot reported failure. + adb.fastboot.FastbootInvalidResponse + Fastboot responded with an unknown packet type. + """ - accepted_size = self._AcceptResponses( - b'DATA', info_cb, timeout_ms=timeout_ms) + accepted_size = self._AcceptResponses(b'DATA', info_cb, timeout_ms=timeout_ms) accepted_size = binascii.unhexlify(accepted_size[:8]) accepted_size, = struct.unpack(b'>I', accepted_size) if accepted_size != source_len: - raise FastbootTransferError( - 'Device refused to download %s bytes of data (accepts %s bytes)', - source_len, accepted_size) + raise FastbootTransferError('Device refused to download {0} bytes of data (accepts {1} bytes)'.format(source_len, accepted_size)) + self._Write(source_file, accepted_size, progress_callback) + return self._AcceptResponses(b'OKAY', info_cb, timeout_ms=timeout_ms) def _AcceptResponses(self, expected_header, info_cb, timeout_ms=None): """Accepts responses until the expected header or a FAIL. - Args: - expected_header: OKAY or DATA - info_cb: Optional callback for text sent from the bootloader. - timeout_ms: Timeout in milliseconds to wait for each response. + .. image:: _static/adb.fastboot.FastbootProtocol._AcceptResponses.CALLER_GRAPH.svg + + Parameters + ---------- + expected_header : TODO + ``OKAY`` or ``DATA`` + info_cb : TODO + Optional callback for text sent from the bootloader. + timeout_ms : TODO + Timeout in milliseconds to wait for each response. + + Returns + ------- + TODO + OKAY packet's message. + + Raises + ------ + adb.fastboot.FastbootStateMismatch + Fastboot responded with the wrong packet type. + adb.fastboot.FastbootRemoteFailure + Fastboot reported failure. + adb.fastboot.FastbootInvalidResponse + Fastboot responded with an unknown packet type. - Raises: - FastbootStateMismatch: Fastboot responded with the wrong packet type. - FastbootRemoteFailure: Fastboot reported failure. - FastbootInvalidResponse: Fastboot responded with an unknown packet type. - - Returns: - OKAY packet's message. """ while True: response = self.usb.BulkRead(64, timeout_ms=timeout_ms) @@ -162,32 +289,56 @@ def _AcceptResponses(self, expected_header, info_cb, timeout_ms=None): info_cb(FastbootMessage(remaining, header)) elif header in self.FINAL_HEADERS: if header != expected_header: - raise FastbootStateMismatch( - 'Expected %s, got %s', expected_header, header) + raise FastbootStateMismatch('Expected {0}, got {1}'.format(expected_header, header)) if header == b'OKAY': info_cb(FastbootMessage(remaining, header)) return remaining elif header == b'FAIL': info_cb(FastbootMessage(remaining, header)) - raise FastbootRemoteFailure('FAIL: %s', remaining) + raise FastbootRemoteFailure('FAIL: {0}'.format(remaining)) else: - raise FastbootInvalidResponse( - 'Got unknown header %s and response %s', header, remaining) + raise FastbootInvalidResponse('Got unknown header {0} and response {1}'.format(header, remaining)) + + @staticmethod + def _HandleProgress(total, progress_callback): + """Calls the callback with the current progress and total. + + .. image:: _static/adb.fastboot.FastbootProtocol._HandleProgress.CALLER_GRAPH.svg - def _HandleProgress(self, total, progress_callback): - """Calls the callback with the current progress and total .""" + Parameters + ---------- + total : TODO + TODO + progress_callback : TODO + TODO + + """ current = 0 while True: current += yield try: progress_callback(current, total) except Exception: # pylint: disable=broad-except - _LOG.exception('Progress callback raised an exception. %s', - progress_callback) + _LOG.exception('Progress callback raised an exception. %s', progress_callback) continue def _Write(self, data, length, progress_callback=None): - """Sends the data to the device, tracking progress with the callback.""" + """Sends the data to the device, tracking progress with the callback. + + .. image:: _static/adb.fastboot.FastbootProtocol._Write.CALL_GRAPH.svg + + .. image:: _static/adb.fastboot.FastbootProtocol._Write.CALLER_GRAPH.svg + + Parameters + ---------- + data : TODO + TODO + length : TODO + TODO + progress_callback : TODO, None + TODO + + """ if progress_callback: progress = self._HandleProgress(length, progress_callback) next(progress) @@ -201,60 +352,88 @@ def _Write(self, data, length, progress_callback=None): class FastbootCommands(object): - """Encapsulates the fastboot commands.""" + """Encapsulates the fastboot commands. - def __init__(self): - """Constructs a FastbootCommands instance. + .. image:: _static/adb.fastboot.FastbootCommands.__init__.CALLER_GRAPH.svg - Args: - usb: UsbHandle instance. - """ - self.__reset() + Attributes + ---------- + _handle : TODO, None + TODO + _protocol : TODO, None + TODO - def __reset(self): + """ + def __init__(self): self._handle = None self._protocol = None + def __reset(self): + """TODO + + .. image:: _static/adb.fastboot.FastbootCommands.__reset.CALL_GRAPH.svg + + """ + self.__init__() + @property def usb_handle(self): + """TODO + + Returns + ------- + self._handle : TODO + TODO + + """ return self._handle def Close(self): + """TODO""" self._handle.Close() def ConnectDevice(self, port_path=None, serial=None, default_timeout_ms=None, chunk_kb=1024, **kwargs): """Convenience function to get an adb device from usb path or serial. - Args: - port_path: The filename of usb port to use. - serial: The serial number of the device to use. - default_timeout_ms: The default timeout in milliseconds to use. - chunk_kb: Amount of data, in kilobytes, to break fastboot packets up into - kwargs: handle: Device handle to use (instance of common.TcpHandle or common.UsbHandle) - banner: Connection banner to pass to the remote device - rsa_keys: List of AuthSigner subclass instances to be used for - authentication. The device can either accept one of these via the Sign - method, or we will send the result of GetPublicKey from the first one - if the device doesn't accept any of them. - auth_timeout_ms: Timeout to wait for when sending a new public key. This - is only relevant when we send a new public key. The device shows a - dialog and this timeout is how long to wait for that dialog. If used - in automation, this should be low to catch such a case as a failure - quickly; while in interactive settings it should be high to allow - users to accept the dialog. We default to automation here, so it's low - by default. - - If serial specifies a TCP address:port, then a TCP connection is - used instead of a USB connection. + Parameters + ---------- + port_path : TODO, None + The filename of usb port to use. + serial : TODO, None + The serial number of the device to use. If serial specifies a TCP address:port, then a TCP connection is + used instead of a USB connection. + default_timeout_ms : TODO, None + The default timeout in milliseconds to use. + chunk_kb : int + Amount of data, in kilobytes, to break fastboot packets up into + **kwargs : dict + Keyword arguments + handle : adb.common.TcpHandle, adb.common.UsbHandle + Device handle to use + banner : TODO + Connection banner to pass to the remote device + rsa_keys : list[adb_protocol.AuthSigner] + List of AuthSigner subclass instances to be used for authentication. The device can either accept one of + these via the ``Sign`` method, or we will send the result of ``GetPublicKey`` from the first one if the + device doesn't accept any of them. + auth_timeout_ms : TODO + Timeout to wait for when sending a new public key. This is only relevant when we send a new public key. The + device shows a dialog and this timeout is how long to wait for that dialog. If used in automation, this + should be low to catch such a case as a failure quickly; while in interactive settings it should be high to + allow users to accept the dialog. We default to automation here, so it's low by default. + + Returns + ------- + self : FastbootCommands + TODO + """ if 'handle' in kwargs: self._handle = kwargs['handle'] else: - self._handle = common.UsbHandle.FindAndOpen( - DeviceIsAvailable, port_path=port_path, serial=serial, - timeout_ms=default_timeout_ms) + self._handle = common.UsbHandle.FindAndOpen(DeviceIsAvailable, port_path=port_path, serial=serial, timeout_ms=default_timeout_ms) self._protocol = FastbootProtocol(self._handle, chunk_kb) @@ -262,10 +441,40 @@ def ConnectDevice(self, port_path=None, serial=None, default_timeout_ms=None, ch @classmethod def Devices(cls): - """Get a generator of UsbHandle for devices available.""" + """Get a generator of UsbHandle for devices available. + + Returns + ------- + TODO + TODO + + """ return common.UsbHandle.FindDevices(DeviceIsAvailable) def _SimpleCommand(self, command, arg=None, **kwargs): + """TODO + + .. image:: _static/adb.fastboot.FastbootCommands._SimpleCommand.CALL_GRAPH.svg + + .. image:: _static/adb.fastboot.FastbootCommands._SimpleCommand.CALLER_GRAPH.svg + + Parameters + ---------- + command : TODO + TODO + arg : TODO, None + TODO + **kwargs : dict + Keyword arguments + TODO + TODO + + Returns + ------- + TODO + TODO + + """ self._protocol.SendCommand(command, arg) return self._protocol.HandleSimpleResponses(**kwargs) @@ -273,42 +482,61 @@ def FlashFromFile(self, partition, source_file, source_len=0, info_cb=DEFAULT_MESSAGE_CALLBACK, progress_callback=None): """Flashes a partition from the file on disk. - Args: - partition: Partition name to flash to. - source_file: Filename to download to the device. - source_len: Optional length of source_file, uses os.stat if not provided. - info_cb: See Download. - progress_callback: See Download. + .. image:: _static/adb.fastboot.FastbootCommands.FlashFromFile.CALL_GRAPH.svg + + .. image:: _static/adb.fastboot.FastbootCommands.FlashFromFile.CALLER_GRAPH.svg + + Parameters + ---------- + partition : TODO + Partition name to flash to. + source_file : TODO + Filename to download to the device. + source_len : int + Optional length of source_file, uses os.stat if not provided. + info_cb : TODO + See Download. + progress_callback : TODO + See Download. + + Returns + ------- + TODO + Download and flash responses, normally nothing. - Returns: - Download and flash responses, normally nothing. """ if source_len == 0: # Fall back to stat. source_len = os.stat(source_file).st_size - download_response = self.Download( - source_file, source_len=source_len, info_cb=info_cb, - progress_callback=progress_callback) + download_response = self.Download(source_file, source_len=source_len, info_cb=info_cb, progress_callback=progress_callback) flash_response = self.Flash(partition, info_cb=info_cb) + return download_response + flash_response def Download(self, source_file, source_len=0, info_cb=DEFAULT_MESSAGE_CALLBACK, progress_callback=None): """Downloads a file to the device. - Args: - source_file: A filename or file-like object to download to the device. - source_len: Optional length of source_file. If source_file is a file-like - object and source_len is not provided, source_file is read into - memory. - info_cb: Optional callback accepting FastbootMessage for text sent from - the bootloader. - progress_callback: Optional callback called with the percent of the - source_file downloaded. Note, this doesn't include progress of the - actual flashing. - - Returns: - Response to a download request, normally nothing. + .. image:: _static/adb.fastboot.FastbootCommands.Download.CALLER_GRAPH.svg + + Parameters + ---------- + source_file : TODO + A filename or file-like object to download to the device. + source_len : int + Optional length of source_file. If ``source_file`` is a file-like object and ``source_len`` is not provided, + ``source_file`` is read into memory. + info_cb : TODO + Optional callback accepting FastbootMessage for text sent from the bootloader. + progress_callback : TODO, None + Optional callback called with the percent of the source_file downloaded. Note, this doesn't include progress + of the actual flashing. + + Returns + ------- + TODO + Response to a download request, normally nothing. + """ if isinstance(source_file, str): source_len = os.stat(source_file).st_size @@ -322,77 +550,137 @@ def Download(self, source_file, source_len=0, source_len = len(data) self._protocol.SendCommand(b'download', b'%08x' % source_len) - return self._protocol.HandleDataSending( - source_file, source_len, info_cb, progress_callback=progress_callback) + + return self._protocol.HandleDataSending(source_file, source_len, info_cb, progress_callback=progress_callback) def Flash(self, partition, timeout_ms=0, info_cb=DEFAULT_MESSAGE_CALLBACK): """Flashes the last downloaded file to the given partition. - Args: - partition: Partition to overwrite with the new image. - timeout_ms: Optional timeout in milliseconds to wait for it to finish. - info_cb: See Download. Usually no messages. + .. image:: _static/adb.fastboot.FastbootCommands.Flash.CALL_GRAPH.svg + + .. image:: _static/adb.fastboot.FastbootCommands.Flash.CALLER_GRAPH.svg - Returns: - Response to a download request, normally nothing. + Parameters + ---------- + partition : TODO + Partition to overwrite with the new image. + timeout_ms : int + Optional timeout in milliseconds to wait for it to finish. + info_cb : TODO + See :meth:`FastbootCommands.Download`. Usually no messages. + + Returns + ------- + TODO + Response to a download request, normally nothing. """ - return self._SimpleCommand(b'flash', arg=partition, info_cb=info_cb, - timeout_ms=timeout_ms) + return self._SimpleCommand(b'flash', arg=partition, info_cb=info_cb, timeout_ms=timeout_ms) def Erase(self, partition, timeout_ms=None): """Erases the given partition. - Args: - partition: Partition to clear. + .. image:: _static/adb.fastboot.FastbootCommands.Erase.CALL_GRAPH.svg + + Parameters + ---------- + partition : TODO + Partition to clear. + timeout_ms : TODO, None + TODO + """ self._SimpleCommand(b'erase', arg=partition, timeout_ms=timeout_ms) def Getvar(self, var, info_cb=DEFAULT_MESSAGE_CALLBACK): """Returns the given variable's definition. - Args: - var: A variable the bootloader tracks. Use 'all' to get them all. - info_cb: See Download. Usually no messages. + .. image:: _static/adb.fastboot.FastbootCommands.Getvar.CALL_GRAPH.svg + + Parameters + ---------- + var : TODO + A variable the bootloader tracks. Use 'all' to get them all. + info_cb : TODO + See :meth:`FastbootCommands.Download`. Usually no messages. + + Returns + ------- + TODO + Value of ``var`` according to the current bootloader. - Returns: - Value of var according to the current bootloader. """ return self._SimpleCommand(b'getvar', arg=var, info_cb=info_cb) def Oem(self, command, timeout_ms=None, info_cb=DEFAULT_MESSAGE_CALLBACK): """Executes an OEM command on the device. - Args: - command: Command to execute, such as 'poweroff' or 'bootconfig read'. - timeout_ms: Optional timeout in milliseconds to wait for a response. - info_cb: See Download. Messages vary based on command. + .. image:: _static/adb.fastboot.FastbootCommands.Oem.CALL_GRAPH.svg + + Parameters + ---------- + command : TODO + Command to execute, such as 'poweroff' or 'bootconfig read'. + timeout_ms : TODO, None + Optional timeout in milliseconds to wait for a response. + info_cb : TODO + See :meth:`FastbootCommands.Download`. Messages vary based on command. - Returns: + Returns + ------- The final response from the device. """ if not isinstance(command, bytes): command = command.encode('utf8') - return self._SimpleCommand( - b'oem %s' % command, timeout_ms=timeout_ms, info_cb=info_cb) + + return self._SimpleCommand(b'oem %s' % command, timeout_ms=timeout_ms, info_cb=info_cb) def Continue(self): - """Continues execution past fastboot into the system.""" + """Continues execution past fastboot into the system. + + .. image:: _static/adb.fastboot.FastbootCommands.Continue.CALL_GRAPH.svg + + Returns + ------- + TODO + TODO + + """ return self._SimpleCommand(b'continue') def Reboot(self, target_mode=b'', timeout_ms=None): """Reboots the device. - Args: - target_mode: Normal reboot when unspecified. Can specify other target - modes such as 'recovery' or 'bootloader'. - timeout_ms: Optional timeout in milliseconds to wait for a response. + .. image:: _static/adb.fastboot.FastbootCommands.Reboot.CALL_GRAPH.svg + + Parameters + ---------- + target_mode : bytes + Normal reboot when unspecified. Can specify other target modes such as 'recovery' or 'bootloader'. + timeout_ms : TODO, None + Optional timeout in milliseconds to wait for a response. - Returns: + Returns + ------- + TODO Usually the empty string. Depends on the bootloader and the target_mode. + """ - return self._SimpleCommand( - b'reboot', arg=target_mode or None, timeout_ms=timeout_ms) + return self._SimpleCommand(b'reboot', arg=target_mode or None, timeout_ms=timeout_ms) def RebootBootloader(self, timeout_ms=None): - """Reboots into the bootloader, usually equiv to Reboot('bootloader').""" + """Reboots into the bootloader, usually equiv to Reboot('bootloader'). + + .. image:: _static/adb.fastboot.FastbootCommands.RebootBootloader.CALL_GRAPH.svg + + Parameters + ---------- + timeout_ms : TODO, None + TODO + + Returns + ------- + TODO + TODO + + """ return self._SimpleCommand(b'reboot-bootloader', timeout_ms=timeout_ms) diff --git a/adb/fastboot_debug.py b/adb/fastboot_debug.py index e168f69..22d4394 100755 --- a/adb/fastboot_debug.py +++ b/adb/fastboot_debug.py @@ -15,8 +15,14 @@ """Fastboot in python. -Call it similar to how you call android's fastboot. Call it similar to how you -call android's fastboot, but this only accepts usb paths and no serials. +Call it similar to how you call android's fastboot, but this only accepts usb paths and no serials. + + +.. rubric:: Contents + +* :func:`_InfoCb` +* :func:`Devices` + """ import argparse @@ -34,11 +40,24 @@ progressbar = None -def Devices(args): +def Devices(): """Lists the available devices. - List of devices attached - 015DB7591102001A device + :: + + List of devices attached + 015DB7591102001A device + + + .. seealso:: :meth:`adb.fastboot.FastbootCommands.Devices` + + .. image:: _static/adb.fastboot_debug.Devices.CALLER_GRAPH.svg + + Returns + ------- + int + 0 + """ for device in fastboot.FastbootCommands.Devices(): print('%s\tdevice' % device.serial_number) @@ -46,6 +65,14 @@ def Devices(args): def _InfoCb(message): + """Print a message to stdout. + + Parameters + ---------- + message : adb.fastboot.FastbootMessage + A :class:`~adb.fastboot.FastbootMessage` with ``header`` and ``message`` attributes + + """ # Use an unbuffered version of stdout. if not message.message: return @@ -54,38 +81,26 @@ def _InfoCb(message): def main(): + """TODO""" common = common_cli.GetCommonArguments() device = common_cli.GetDeviceArguments() - device.add_argument( - '--chunk_kb', type=int, default=1024, metavar='1024', - help='Size of packets to write in Kb. For older devices, it may be ' - 'required to use 4.') + device.add_argument('--chunk_kb', type=int, default=1024, metavar='1024', + help='Size of packets to write in Kb. For older devices, it may be required to use 4.') parents = [common, device] - parser = argparse.ArgumentParser( - description=sys.modules[__name__].__doc__, parents=[common]) + parser = argparse.ArgumentParser(description=sys.modules[__name__].__doc__, parents=[common]) subparsers = parser.add_subparsers(title='Commands', dest='command_name') - subparser = subparsers.add_parser( - name='help', help='Prints the commands available') - subparser = subparsers.add_parser( - name='devices', help='Lists the available devices', parents=[common]) - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Continue) - - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Download, - {'source_file': 'Filename on the host to push'}) - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Erase) - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Flash) - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Getvar) - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Oem) - common_cli.MakeSubparser( - subparsers, parents, fastboot.FastbootCommands.Reboot) + subparser = subparsers.add_parser(name='help', help='Prints the commands available') # pylint: disable=unused-variable + subparser = subparsers.add_parser(name='devices', help='Lists the available devices', parents=[common]) # noqa: F841 + + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Continue) + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Download, {'source_file': 'Filename on the host to push'}) + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Erase) + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Flash) + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Getvar) + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Oem) + common_cli.MakeSubparser(subparsers, parents, fastboot.FastbootCommands.Reboot) if len(sys.argv) == 1: parser.print_help() @@ -95,18 +110,17 @@ def main(): if args.verbose: logging.basicConfig(level=logging.DEBUG) if args.command_name == 'devices': - return Devices(args) + return Devices() if args.command_name == 'help': parser.print_help() return 0 kwargs = {} - argspec = inspect.getargspec(args.method) + argspec = inspect.getfullargspec(args.method) if 'info_cb' in argspec.args: kwargs['info_cb'] = _InfoCb if 'progress_callback' in argspec.args and progressbar: - bar = progressbar.ProgessBar( - widgets=[progressbar.Bar(), progressbar.Percentage()]) + bar = progressbar.ProgessBar(widgets=[progressbar.Bar(), progressbar.Percentage()]) # pylint: disable=blacklisted-name bar.start() def SetProgress(current, total): diff --git a/adb/filesync_protocol.py b/adb/filesync_protocol.py index d0547f4..bc1c3de 100644 --- a/adb/filesync_protocol.py +++ b/adb/filesync_protocol.py @@ -11,13 +11,41 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """ADB protocol implementation. Implements the ADB protocol as seen in android's adb/adbd binaries, but only the host side. + + +.. rubric:: Contents + +* :class:`FileSyncConnection` + + * :meth:`FileSyncConnection.Read` + * :meth:`FileSyncConnection.ReadUntil` + * :meth:`FileSyncConnection.Send` + * :meth:`FileSyncConnection._CanAddToSendBuffer` + * :meth:`FileSyncConnection._Flush` + * :meth:`FileSyncConnection._ReadBuffered` + +* :class:`FilesyncProtocol` + + * :meth:`FilesyncProtocol._HandleProgress` + * :meth:`FilesyncProtocol.List` + * :meth:`FilesyncProtocol.Pull` + * :meth:`FilesyncProtocol.Push` + * :meth:`FilesyncProtocol.Stat` + +* :class:`InterleavedDataError` +* :class:`InvalidChecksumError` +* :class:`PullFailedError` +* :class:`PushFailedError` + """ import collections +import io import os import stat import struct @@ -28,30 +56,52 @@ from adb import adb_protocol from adb import usb_exceptions -# Default mode for pushed files. + +try: + file_types = (file, io.IOBase) +except NameError: + file_types = (io.IOBase,) + +#: Default mode for pushed files. DEFAULT_PUSH_MODE = stat.S_IFREG | stat.S_IRWXU | stat.S_IRWXG -# Maximum size of a filesync DATA packet. + +#: Maximum size of a filesync DATA packet. MAX_PUSH_DATA = 2 * 1024 class InvalidChecksumError(Exception): - """Checksum of data didn't match expected checksum.""" + """Checksum of data didn't match expected checksum. + + .. image:: _static/adb.filesync_protocol.InvalidChecksumError.CALL_GRAPH.svg + + """ class InterleavedDataError(Exception): - """We only support command sent serially.""" + """We only support command sent serially. + + .. image:: _static/adb.filesync_protocol.InterleavedDataError.CALL_GRAPH.svg + + """ class PushFailedError(Exception): - """Pushing a file failed for some reason.""" + """Pushing a file failed for some reason. + + .. image:: _static/adb.filesync_protocol.PushFailedError.CALL_GRAPH.svg + + """ class PullFailedError(Exception): - """Pulling a file failed for some reason.""" + """Pulling a file failed for some reason. + + .. image:: _static/adb.filesync_protocol.PullFailedError.CALL_GRAPH.svg + + """ -DeviceFile = collections.namedtuple('DeviceFile', [ - 'filename', 'mode', 'size', 'mtime']) +DeviceFile = collections.namedtuple('DeviceFile', ['filename', 'mode', 'size', 'mtime']) class FilesyncProtocol(object): @@ -59,30 +109,94 @@ class FilesyncProtocol(object): @staticmethod def Stat(connection, filename): + """Get file status (mode, size, and mtime). + + .. image:: _static/adb.filesync_protocol.FilesyncProtocol.Stat.CALLER_GRAPH.svg + + Parameters + ---------- + connection : adb.adb_protocol._AdbConnection + ADB connection + filename : str, bytes + The file for which we are getting info + + Returns + ------- + mode : int + The mode of the file + size : int + The size of the file + mtime : int + The time of last modification for the file + + Raises + ------ + adb.adb_protocol.InvalidResponseError + Expected STAT response to STAT, got something else + + """ cnxn = FileSyncConnection(connection, b'<4I') cnxn.Send(b'STAT', filename) command, (mode, size, mtime) = cnxn.Read((b'STAT',), read_data=False) if command != b'STAT': - raise adb_protocol.InvalidResponseError( - 'Expected STAT response to STAT, got %s' % command) + raise adb_protocol.InvalidResponseError('Expected STAT response to STAT, got %s' % command) + return mode, size, mtime @classmethod def List(cls, connection, path): + """Get a list of the files in ``path``. + + Parameters + ---------- + connection : adb.adb_protocol._AdbConnection + ADB connection + path : str, bytes + The path for which we are getting a list of files + + Returns + ------- + files : list[DeviceFile] + Information about the files in ``path`` + + """ cnxn = FileSyncConnection(connection, b'<5I') cnxn.Send(b'LIST', path) files = [] + for cmd_id, header, filename in cnxn.ReadUntil((b'DENT',), b'DONE'): if cmd_id == b'DONE': break + mode, size, mtime = header files.append(DeviceFile(filename, mode, size, mtime)) + return files @classmethod def Pull(cls, connection, filename, dest_file, progress_callback): - """Pull a file from the device into the file-like dest_file.""" + """Pull a file from the device into the file-like ``dest_file``. + + .. image:: _static/adb.filesync_protocol.FilesyncProtocol.Pull.CALL_GRAPH.svg + + Parameters + ---------- + connection : adb.adb_protocol._AdbConnection + ADB connection + filename : str + The file to be pulled + dest_file : _io.BytesIO + File-like object for writing to + progress_callback : function, None + Callback method that accepts ``filename``, ``bytes_written``, and ``total_bytes`` + + Raises + ------ + PullFailedError + Unable to pull file + + """ if progress_callback: total_bytes = cls.Stat(connection, filename)[1] progress = cls._HandleProgress(lambda current: progress_callback(filename, current, total_bytes)) @@ -94,9 +208,11 @@ def Pull(cls, connection, filename, dest_file, progress_callback): for cmd_id, _, data in cnxn.ReadUntil((b'DATA',), b'DONE'): if cmd_id == b'DONE': break + dest_file.write(data) if progress_callback: progress.send(len(data)) + except usb_exceptions.CommonUsbError as e: raise PullFailedError('Unable to pull file %s due to: %s' % (filename, e)) @@ -104,9 +220,16 @@ def Pull(cls, connection, filename, dest_file, progress_callback): def _HandleProgress(cls, progress_callback): """Calls the callback with the current progress and total bytes written/received. - Args: - progress_callback: callback method that accepts filename, bytes_written and total_bytes, - total_bytes will be -1 for file-like objects + .. image:: _static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALL_GRAPH.svg + + .. image:: _static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALLER_GRAPH.svg + + Parameters + ---------- + progress_callback : function + Callback method that accepts ``filename``, ``bytes_written``, and ``total_bytes``; total_bytes will be -1 for file-like + objects. + """ current = 0 while True: @@ -121,25 +244,38 @@ def Push(cls, connection, datafile, filename, st_mode=DEFAULT_PUSH_MODE, mtime=0, progress_callback=None): """Push a file-like object to the device. - Args: - connection: ADB connection - datafile: File-like object for reading from - filename: Filename to push to - st_mode: stat mode for filename - mtime: modification time - progress_callback: callback method that accepts filename, bytes_written and total_bytes + .. image:: _static/adb.filesync_protocol.FilesyncProtocol.Push.CALL_GRAPH.svg + + .. image:: _static/adb.filesync_protocol.FilesyncProtocol.Push.CALLER_GRAPH.svg + + Parameters + ---------- + connection : adb.adb_protocol._AdbConnection + ADB connection + datafile : _io.BytesIO + File-like object for reading from + filename : str + Filename to push to + st_mode : int + Stat mode for filename + mtime : int + Modification time + progress_callback : function, None + Callback method that accepts ``filename``, ``bytes_written``, and ``total_bytes`` + + Raises + ------ + PushFailedError + Raised on push failure. - Raises: - PushFailedError: Raised on push failure. """ - fileinfo = ('{},{}'.format(filename, int(st_mode))).encode('utf-8') cnxn = FileSyncConnection(connection, b'<2I') cnxn.Send(b'SEND', fileinfo) if progress_callback: - total_bytes = os.fstat(datafile.fileno()).st_size if isinstance(datafile, file) else -1 + total_bytes = os.fstat(datafile.fileno()).st_size if isinstance(datafile, file_types) else -1 progress = cls._HandleProgress(lambda current: progress_callback(filename, current, total_bytes)) next(progress) @@ -165,12 +301,35 @@ def Push(cls, connection, datafile, filename, class FileSyncConnection(object): - """Encapsulate a FileSync service connection.""" - - ids = [ - b'STAT', b'LIST', b'SEND', b'RECV', b'DENT', b'DONE', b'DATA', b'OKAY', - b'FAIL', b'QUIT', - ] + """Encapsulate a FileSync service connection. + + Parameters + ---------- + adb_connection : adb.adb_protocol._AdbConnection + ADB connection + recv_header_format : bytes + TODO + + Attributes + ---------- + adb : adb.adb_protocol._AdbConnection + ADB connection + send_buffer : byte_array + ``bytearray(adb_protocol.MAX_ADB_DATA)`` (see :const:`adb.adb_protocol.MAX_ADB_DATA`) + send_idx : int + TODO + send_header_len : int + ``struct.calcsize(b'<2I')`` + recv_buffer : bytearray + TODO + recv_header_format : bytes + TODO + recv_header_len : int + ``struct.calcsize(recv_header_format)`` + + """ + + ids = [b'STAT', b'LIST', b'SEND', b'RECV', b'DENT', b'DONE', b'DATA', b'OKAY', b'FAIL', b'QUIT'] id_to_wire, wire_to_id = adb_protocol.MakeWireIDs(ids) def __init__(self, adb_connection, recv_header_format): @@ -193,10 +352,17 @@ def Send(self, command_id, data=b'', size=0): Packets are buffered and only flushed when this connection is read from. All messages have a response from the device, so this will always get flushed. - Args: - command_id: Command to send. - data: Optional data to send, must set data or size. - size: Optionally override size from len(data). + .. image:: _static/adb.filesync_protocol.FileSyncConnection.Send.CALL_GRAPH.svg + + Parameters + ---------- + command_id : bytes + Command to send. + data : str, bytes + Optional data to send, must set data or size. + size : int + Optionally override size from len(data). + """ if data: if not isinstance(data, bytes): @@ -210,7 +376,36 @@ def Send(self, command_id, data=b'', size=0): self.send_idx += len(buf) def Read(self, expected_ids, read_data=True): - """Read ADB messages and return FileSync packets.""" + """Read ADB messages and return FileSync packets. + + .. image:: _static/adb.filesync_protocol.FileSyncConnection.Read.CALL_GRAPH.svg + + .. image:: _static/adb.filesync_protocol.FileSyncConnection.Read.CALLER_GRAPH.svg + + Parameters + ---------- + expected_ids : tuple[bytes] + If the received header ID is not in ``expected_ids``, an exception will be raised + read_data : bool + Whether to read the received data + + Returns + ------- + command_id : bytes + The received header ID + tuple + TODO + data : bytearray + The received data + + Raises + ------ + adb.usb_exceptions.AdbCommandFailureException + Command failed + adb.adb_protocol.InvalidResponseError + Received response was not in ``expected_ids`` + + """ if self.send_idx: self._Flush() @@ -225,9 +420,10 @@ def Read(self, expected_ids, read_data=True): reason = '' if self.recv_buffer: reason = self.recv_buffer.decode('utf-8', errors='ignore') + raise usb_exceptions.AdbCommandFailureException('Command failed: {}'.format(reason)) - raise adb_protocol.InvalidResponseError( - 'Expected one of %s, got %s' % (expected_ids, command_id)) + + raise adb_protocol.InvalidResponseError('Expected one of %s, got %s' % (expected_ids, command_id)) if not read_data: return command_id, header[1:] @@ -235,10 +431,31 @@ def Read(self, expected_ids, read_data=True): # Header is (ID, ..., size). size = header[-1] data = self._ReadBuffered(size) + return command_id, header[1:-1], data def ReadUntil(self, expected_ids, *finish_ids): - """Useful wrapper around Read.""" + """Useful wrapper around :meth:`FileSyncConnection.Read`. + + .. image:: _static/adb.filesync_protocol.FileSyncConnection.ReadUntil.CALL_GRAPH.svg + + Parameters + ---------- + expected_ids : tuple[bytes] + If the received header ID is not in ``expected_ids``, an exception will be raised + finish_ids : tuple[bytes] + We will read until we find a header ID that is in ``finish_ids`` + + Yields + ------ + cmd_id : bytes + The received header ID + header : tuple + TODO + data : bytearray + The received data + + """ while True: cmd_id, header, data = self.Read(expected_ids + finish_ids) yield cmd_id, header, data @@ -246,18 +463,57 @@ def ReadUntil(self, expected_ids, *finish_ids): break def _CanAddToSendBuffer(self, data_len): + """Determine whether ``data_len`` bytes of data can be added to the send buffer without exceeding :const:`adb.adb_protocol.MAX_ADB_DATA`. + + .. image:: _static/adb.filesync_protocol.FileSyncConnection._CanAddToSendBuffer.CALLER_GRAPH.svg + + Parameters + ---------- + data_len : int + The length of the data to be potentially added to the send buffer (not including the length of its header) + + Returns + ------- + bool + Whether ``data_len`` bytes of data can be added to the send buffer without exceeding :const:`adb.adb_protocol.MAX_ADB_DATA` + + """ added_len = self.send_header_len + data_len return self.send_idx + added_len < adb_protocol.MAX_ADB_DATA def _Flush(self): + """TODO + + .. image:: _static/adb.filesync_protocol.FileSyncConnection._Flush.CALLER_GRAPH.svg + + Raises + ------ + adb.usb_exceptions.WriteFailedError + Could not send data + + """ try: self.adb.Write(self.send_buffer[:self.send_idx]) except libusb1.USBError as e: - raise adb_protocol.SendFailedError( - 'Could not send data %s' % self.send_buffer, e) + raise usb_exceptions.WriteFailedError('Could not send data %s' % self.send_buffer, e) self.send_idx = 0 def _ReadBuffered(self, size): + """Read ``size`` bytes of data from ``self.recv_buffer``. + + .. image:: _static/adb.filesync_protocol.FileSyncConnection._ReadBuffered.CALLER_GRAPH.svg + + Parameters + ---------- + size : int + The amount of data to read + + Returns + ------- + result : bytearray + The read data + + """ # Ensure recv buffer has enough data. while len(self.recv_buffer) < size: _, data = self.adb.ReadUntil(b'WRTE') diff --git a/adb/sign_cryptography.py b/adb/sign_cryptography.py index b042642..9e873a5 100644 --- a/adb/sign_cryptography.py +++ b/adb/sign_cryptography.py @@ -12,7 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -from adb import adb_protocol +"""ADB authentication using the ``cryptography`` package. + + +.. rubric:: Contents + +* :class:`CryptographySigner` + + * :meth:`CryptographySigner.GetPublicKey` + * :meth:`CryptographySigner.Sign` + +""" from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes @@ -20,21 +30,60 @@ from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.asymmetric import utils +from adb import adb_protocol + +# pylint: disable=abstract-method class CryptographySigner(adb_protocol.AuthSigner): - """AuthSigner using cryptography.io.""" + """AuthSigner using cryptography.io. + + .. warning:: This is currently broken! + .. image:: _static/adb.sign_cryptography.CryptographySigner.CALL_GRAPH.svg + + Parameters + ---------- + rsa_key_path : str + The path to the private key. + + Attributes + ---------- + public_key : str + The contents of the public key file + rsa_key : cryptography.hazmat.backends.openssl.rsa._RSAPrivateKey + The loaded private key + + """ def __init__(self, rsa_key_path): with open(rsa_key_path + '.pub') as rsa_pub_file: self.public_key = rsa_pub_file.read() with open(rsa_key_path) as rsa_prv_file: - self.rsa_key = serialization.load_pem_private_key( - rsa_prv_file.read(), None, default_backend()) + self.rsa_key = serialization.load_pem_private_key(rsa_prv_file.read(), None, default_backend()) def Sign(self, data): - return self.rsa_key.sign( - data, padding.PKCS1v15(), utils.Prehashed(hashes.SHA1())) + """Signs given data using a private key. + + Parameters + ---------- + data : TODO + TODO + + Returns + ------- + TODO + The signed ``data`` + + """ + return self.rsa_key.sign(data, padding.PKCS1v15(), utils.Prehashed(hashes.SHA1())) def GetPublicKey(self): + """Returns the public key in PEM format without headers or newlines. + + Returns + ------- + self.public_key : str + The contents of the public key file + + """ return self.public_key diff --git a/adb/sign_pycryptodome.py b/adb/sign_pycryptodome.py index 6a61ce9..19a2185 100644 --- a/adb/sign_pycryptodome.py +++ b/adb/sign_pycryptodome.py @@ -1,12 +1,54 @@ -from adb import adb_protocol +# Copyright 2014 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""ADB authentication using ``pycryptodome``. + + +.. rubric:: Contents + +* :class:`PycryptodomeAuthSigner` + + * :meth:`PycryptodomeAuthSigner.GetPublicKey` + * :meth:`PycryptodomeAuthSigner.Sign` + +""" from Crypto.Hash import SHA256 from Crypto.PublicKey import RSA from Crypto.Signature import pkcs1_15 +from adb import adb_protocol + class PycryptodomeAuthSigner(adb_protocol.AuthSigner): + """TODO + .. image:: _static/adb.sign_pycryptodome.PycryptodomeAuthSigner.CALL_GRAPH.svg + + Parameters + ---------- + rsa_key_path : str, None + The path to the private key + + Attributes + ---------- + public_key : str + The contents of the public key file + rsa_key : Crypto.PublicKey.RSA.RsaKey + The contents of theprivate key + + """ def __init__(self, rsa_key_path=None): super(PycryptodomeAuthSigner, self).__init__() @@ -18,8 +60,29 @@ def __init__(self, rsa_key_path=None): self.rsa_key = RSA.import_key(rsa_priv_file.read()) def Sign(self, data): + """Signs given data using a private key. + + Parameters + ---------- + data : bytes, bytearray + The data to be signed + + Returns + ------- + bytes + The signed ``data`` + + """ h = SHA256.new(data) return pkcs1_15.new(self.rsa_key).sign(h) def GetPublicKey(self): + """Returns the public key in PEM format without headers or newlines. + + Returns + ------- + self.public_key : str + The contents of the public key file + + """ return self.public_key diff --git a/adb/sign_pythonrsa.py b/adb/sign_pythonrsa.py index a401a4c..3ee58b5 100644 --- a/adb/sign_pythonrsa.py +++ b/adb/sign_pythonrsa.py @@ -12,24 +12,72 @@ # See the License for the specific language governing permissions and # limitations under the License. -import rsa +"""ADB authentication using the ``rsa`` package. + + +.. rubric:: Contents + +* :class:`_Accum` + + * :meth:`_Accum.digest` + * :meth:`_Accum.update` + +* :func:`_load_rsa_private_key` +* :class:`PythonRSASigner` + + * :meth:`PythonRSASigner.FromRSAKeyPath` + * :meth:`PythonRSASigner.GetPublicKey` + * :meth:`PythonRSASigner.Sign` + +""" + from pyasn1.codec.der import decoder from pyasn1.type import univ +import rsa from rsa import pkcs1 +from adb import adb_protocol + -# python-rsa lib hashes all messages it signs. ADB does it already, we just -# need to slap a signature on top of already hashed message. Introduce "fake" -# hashing algo for this. class _Accum(object): + """A fake hashing algorithm. + + The Python ``rsa`` lib hashes all messages it signs. ADB does it already, we just + need to slap a signature on top of already hashed message. Introduce a "fake" + hashing algo for this. + + .. image:: _static/adb.sign_pythonrsa._Accum.CALL_GRAPH.svg + + Attributes + ---------- + _buf : bytes + A buffer for storing data before it is signed + + """ def __init__(self): self._buf = b'' def update(self, msg): + """Update this hash object's state with the provided ``msg``. + + Parameters + ---------- + msg : bytes + The message to be appended to ``self._buf`` + + """ self._buf += msg def digest(self): + """Return the digest value as a string of binary data. + + Returns + ------- + self._buf : bytes + ``self._buf`` + + """ return self._buf @@ -38,40 +86,111 @@ def digest(self): def _load_rsa_private_key(pem): - """PEM encoded PKCS#8 private key -> rsa.PrivateKey.""" - # ADB uses private RSA keys in pkcs#8 format. 'rsa' library doesn't support - # them natively. Do some ASN unwrapping to extract naked RSA key - # (in der-encoded form). See https://www.ietf.org/rfc/rfc2313.txt. - # Also http://superuser.com/a/606266. + """PEM encoded PKCS#8 private key -> ``rsa.PrivateKey``. + + ADB uses private RSA keys in pkcs#8 format. The ``rsa`` library doesn't + support them natively. Do some ASN unwrapping to extract naked RSA key + (in der-encoded form). + + See: + + * https://www.ietf.org/rfc/rfc2313.txt + * http://superuser.com/a/606266 + + Parameters + ---------- + pem : str + The private key to be loaded + + Returns + ------- + rsa.key.PrivateKey + The loaded private key + + """ try: der = rsa.pem.load_pem(pem, 'PRIVATE KEY') keyinfo, _ = decoder.decode(der) - if keyinfo[1][0] != univ.ObjectIdentifier( - '1.2.840.113549.1.1.1'): # pragma: no cover + + if keyinfo[1][0] != univ.ObjectIdentifier('1.2.840.113549.1.1.1'): raise ValueError('Not a DER-encoded OpenSSL private RSA key') + private_key_der = keyinfo[2].asOctets() - except IndexError: # pragma: no cover + + except IndexError: raise ValueError('Not a DER-encoded OpenSSL private RSA key') + return rsa.PrivateKey.load_pkcs1(private_key_der, format='DER') -class PythonRSASigner(object): - """Implements adb_protocol.AuthSigner using http://stuvel.eu/rsa.""" +class PythonRSASigner(adb_protocol.AuthSigner): + """Implements :class:`adb_protocol.AuthSigner` using http://stuvel.eu/rsa. + + .. image:: _static/adb.sign_pythonrsa.PythonRSASigner.CALL_GRAPH.svg + + Parameters + ---------- + pub : str, None + The contents of the public key file + priv : str, None + The path to the private key + + Attributes + ---------- + priv_key : rsa.key.PrivateKey + The loaded private key + pub_key : str, None + The contents of the public key file + + """ + def __init__(self, pub=None, priv=None): + self.priv_key = _load_rsa_private_key(priv) + self.pub_key = pub @classmethod def FromRSAKeyPath(cls, rsa_key_path): + """Create a :class:`PythonRSASigner` instance using the provided private key. + + Parameters + ---------- + rsa_key_path : str + The path to the private key; the public key must be ``rsa_key_path + '.pub'``. + + Returns + ------- + PythonRSASigner + A :class:`PythonRSASigner` with private key ``rsa_key_path`` and public key ``rsa_key_path + '.pub'`` + + """ with open(rsa_key_path + '.pub') as f: pub = f.read() with open(rsa_key_path) as f: priv = f.read() return cls(pub, priv) - def __init__(self, pub=None, priv=None): - self.priv_key = _load_rsa_private_key(priv) - self.pub_key = pub - def Sign(self, data): + """Signs given data using a private key. + + Parameters + ---------- + data : bytes + The data to be signed + + Returns + ------- + bytes + The signed ``data`` + + """ return rsa.sign(data, self.priv_key, 'SHA-1-PREHASHED') def GetPublicKey(self): + """Returns the public key in PEM format without headers or newlines. + + Returns + ------- + self.pub_key : str, None + The contents of the public key file, or ``None`` if a public key was not provided. + + """ return self.pub_key diff --git a/adb/usb_exceptions.py b/adb/usb_exceptions.py index 54f7e0b..a0096e6 100644 --- a/adb/usb_exceptions.py +++ b/adb/usb_exceptions.py @@ -11,11 +11,32 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Common exceptions for ADB and Fastboot.""" + +"""Common exceptions for ADB and Fastboot. + + +.. rubric:: Contents + +* :class:`AdbCommandFailureException` +* :class:`AdbOperationException` +* :class:`CommonUsbError` +* :class:`DeviceAuthError` +* :class:`DeviceNotFoundError` +* :class:`FormatMessageWithArgumentsException` +* :class:`LibusbWrappingError` +* :class:`ReadFailedError` +* :class:`TcpTimeoutException` +* :class:`WriteFailedError` + +""" class CommonUsbError(Exception): - """Base class for usb communication errors.""" + """Base class for usb communication errors. + + .. image:: _static/adb.usb_exceptions.CommonUsbError.CALL_GRAPH.svg + + """ class FormatMessageWithArgumentsException(CommonUsbError): @@ -25,52 +46,99 @@ class FormatMessageWithArgumentsException(CommonUsbError): This interpolates the message with the given arguments to make it human-readable, but keeps the arguments in case other code try-excepts it. - """ + .. image:: _static/adb.usb_exceptions.FormatMessageWithArgumentsException.CALL_GRAPH.svg + + Parameters + ---------- + message : str + The error message + args : str + Positional arguments for formatting ``message`` + + """ def __init__(self, message, *args): message %= args super(FormatMessageWithArgumentsException, self).__init__(message, *args) class DeviceNotFoundError(FormatMessageWithArgumentsException): - """Device isn't on USB.""" + """Device isn't on USB. + + .. image:: _static/adb.usb_exceptions.DeviceNotFoundError.CALL_GRAPH.svg + + """ class DeviceAuthError(FormatMessageWithArgumentsException): - """Device authentication failed.""" + """Device authentication failed. + + .. image:: _static/adb.usb_exceptions.DeviceAuthError.CALL_GRAPH.svg + + """ class LibusbWrappingError(CommonUsbError): - """Wraps libusb1 errors while keeping its original usefulness. + """Wraps ``libusb1`` errors while keeping their original usefulness. - Attributes: - usb_error: Instance of libusb1.USBError - """ + .. image:: _static/adb.usb_exceptions.LibusbWrappingError.CALL_GRAPH.svg + Parameters + ---------- + msg : str + The error message + usb_error : libusb1.USBError + An exception from ``libusb1`` + + Attributes + ---------- + usb_error : libusb1.USBError + An exception from ``libusb1`` + + """ def __init__(self, msg, usb_error): super(LibusbWrappingError, self).__init__(msg) self.usb_error = usb_error def __str__(self): - return '%s: %s' % ( - super(LibusbWrappingError, self).__str__(), str(self.usb_error)) + return '%s: %s' % (super(LibusbWrappingError, self).__str__(), str(self.usb_error)) class WriteFailedError(LibusbWrappingError): - """Raised when the device doesn't accept our command.""" + """Raised when the device doesn't accept our command. + + .. image:: _static/adb.usb_exceptions.WriteFailedError.CALL_GRAPH.svg + + """ class ReadFailedError(LibusbWrappingError): - """Raised when the device doesn't respond to our commands.""" + """Raised when the device doesn't respond to our commands. + + .. image:: _static/adb.usb_exceptions.ReadFailedError.CALL_GRAPH.svg + + """ class AdbCommandFailureException(Exception): - """ADB Command returned a FAIL.""" + """ADB Command returned a FAIL. + + .. image:: _static/adb.usb_exceptions.AdbCommandFailureException.CALL_GRAPH.svg + + """ class AdbOperationException(Exception): - """Failed to communicate over adb with device after multiple retries.""" + """Failed to communicate over adb with device after multiple retries. + + .. image:: _static/adb.usb_exceptions.AdbOperationException.CALL_GRAPH.svg + + """ class TcpTimeoutException(FormatMessageWithArgumentsException): - """TCP connection timed out in the time out given.""" + """TCP connection timed out in the time out given. + + .. image:: _static/adb.usb_exceptions.TcpTimeoutException.CALL_GRAPH.svg + + """ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..4a11cd7 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = adb +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..21c0799 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=adb + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..94610a4 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +sphinx==2.1.2 diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.CALL_GRAPH.svg new file mode 100644 index 0000000..51a6f86 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.adb_commands.AdbCommands + + +Node1 + +adb.adb_commands.AdbCommands + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Close.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Close.CALLER_GRAPH.svg new file mode 100644 index 0000000..267225c --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Close.CALLER_GRAPH.svg @@ -0,0 +1,32 @@ + + + + + + +adb.adb_commands.AdbCommands.Close + + +Node1 + +adb.adb_commands.AdbCommands. +Close + + +Node2 + + +adb.common.UsbHandle.Open + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Close.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Close.CALL_GRAPH.svg new file mode 100644 index 0000000..13eee9e --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Close.CALL_GRAPH.svg @@ -0,0 +1,47 @@ + + + + + + +adb.adb_commands.AdbCommands.Close + + +Node1 + +adb.adb_commands.AdbCommands. +Close + + +Node2 + + +adb.adb_commands.AdbCommands. +__reset + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_commands.AdbCommands. +__init__ + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.ConnectDevice.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.ConnectDevice.CALL_GRAPH.svg new file mode 100644 index 0000000..7452f60 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.ConnectDevice.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.ConnectDevice + + +Node1 + +adb.adb_commands.AdbCommands. +ConnectDevice + + +Node2 + + +adb.adb_commands.AdbCommands. +_Connect + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.GetState.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.GetState.CALL_GRAPH.svg new file mode 100644 index 0000000..10e0609 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.GetState.CALL_GRAPH.svg @@ -0,0 +1,70 @@ + + + + + + +adb.adb_commands.AdbCommands.GetState + + +Node1 + +adb.adb_commands.AdbCommands. +GetState + + +Node2 + + +adb.adb_commands.AdbCommands. +Install + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_commands.AdbCommands.Push + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_commands.AdbCommands. +Shell + + + + +Node2->Node4 + + + + +Node3->Node3 + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Install.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Install.CALLER_GRAPH.svg new file mode 100644 index 0000000..0fbde81 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Install.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.Install + + +Node1 + +adb.adb_commands.AdbCommands. +Install + + +Node2 + + +adb.adb_commands.AdbCommands. +GetState + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Install.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Install.CALL_GRAPH.svg new file mode 100644 index 0000000..60043b5 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Install.CALL_GRAPH.svg @@ -0,0 +1,56 @@ + + + + + + +adb.adb_commands.AdbCommands.Install + + +Node1 + +adb.adb_commands.AdbCommands. +Install + + +Node2 + + +adb.adb_commands.AdbCommands.Push + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_commands.AdbCommands. +Shell + + + + +Node1->Node3 + + + + +Node2->Node2 + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.InteractiveShell.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.InteractiveShell.CALL_GRAPH.svg new file mode 100644 index 0000000..7cbf910 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.InteractiveShell.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.InteractiveShell + + +Node1 + +adb.adb_commands.AdbCommands. +InteractiveShell + + +Node2 + + +adb.adb_commands.AdbCommands. +_get_service_connection + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Logcat.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Logcat.CALL_GRAPH.svg new file mode 100644 index 0000000..f74302c --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Logcat.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.Logcat + + +Node1 + +adb.adb_commands.AdbCommands. +Logcat + + +Node2 + + +adb.adb_commands.AdbCommands. +StreamingShell + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Push.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Push.CALLER_GRAPH.svg new file mode 100644 index 0000000..46c9118 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Push.CALLER_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.adb_commands.AdbCommands.Push + + +Node1 + +adb.adb_commands.AdbCommands.Push + + +Node1->Node1 + + + + +Node2 + + +adb.adb_commands.AdbCommands. +Install + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_commands.AdbCommands. +GetState + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Push.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Push.CALL_GRAPH.svg new file mode 100644 index 0000000..91b145b --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Push.CALL_GRAPH.svg @@ -0,0 +1,37 @@ + + + + + + +adb.adb_commands.AdbCommands.Push + + +Node1 + +adb.adb_commands.AdbCommands.Push + + +Node1->Node1 + + + + +Node2 + + +adb.adb_commands.AdbCommands. +Shell + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Reboot.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Reboot.CALLER_GRAPH.svg new file mode 100644 index 0000000..4fd353a --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Reboot.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.Reboot + + +Node1 + +adb.adb_commands.AdbCommands. +Reboot + + +Node2 + + +adb.adb_commands.AdbCommands. +RebootBootloader + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.RebootBootloader.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.RebootBootloader.CALL_GRAPH.svg new file mode 100644 index 0000000..9d4785e --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.RebootBootloader.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.RebootBootloader + + +Node1 + +adb.adb_commands.AdbCommands. +RebootBootloader + + +Node2 + + +adb.adb_commands.AdbCommands. +Reboot + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Shell.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Shell.CALLER_GRAPH.svg new file mode 100644 index 0000000..ab0be15 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Shell.CALLER_GRAPH.svg @@ -0,0 +1,84 @@ + + + + + + +adb.adb_commands.AdbCommands.Shell + + +Node1 + +adb.adb_commands.AdbCommands. +Shell + + +Node2 + + +adb.adb_commands.AdbCommands. +Install + + + + +Node1->Node2 + + + + +Node4 + + +adb.adb_commands.AdbCommands.Push + + + + +Node1->Node4 + + + + +Node5 + + +adb.adb_commands.AdbCommands. +Uninstall + + + + +Node1->Node5 + + + + +Node3 + + +adb.adb_commands.AdbCommands. +GetState + + + + +Node2->Node3 + + + + +Node4->Node2 + + + + +Node4->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Stat.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Stat.CALLER_GRAPH.svg new file mode 100644 index 0000000..d2ad899 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Stat.CALLER_GRAPH.svg @@ -0,0 +1,32 @@ + + + + + + +adb.adb_commands.AdbCommands.Stat + + +Node1 + +adb.adb_commands.AdbCommands.Stat + + +Node2 + + +adb.filesync_protocol.Filesync +Protocol.Pull + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.StreamingShell.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.StreamingShell.CALLER_GRAPH.svg new file mode 100644 index 0000000..c754287 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.StreamingShell.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.StreamingShell + + +Node1 + +adb.adb_commands.AdbCommands. +StreamingShell + + +Node2 + + +adb.adb_commands.AdbCommands. +Logcat + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.Uninstall.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.Uninstall.CALL_GRAPH.svg new file mode 100644 index 0000000..8955bb2 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.Uninstall.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.Uninstall + + +Node1 + +adb.adb_commands.AdbCommands. +Uninstall + + +Node2 + + +adb.adb_commands.AdbCommands. +Shell + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands._Connect.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands._Connect.CALLER_GRAPH.svg new file mode 100644 index 0000000..5b46b81 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands._Connect.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands._Connect + + +Node1 + +adb.adb_commands.AdbCommands. +_Connect + + +Node2 + + +adb.adb_commands.AdbCommands. +ConnectDevice + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..6441b7d --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.__init__.CALLER_GRAPH.svg @@ -0,0 +1,74 @@ + + + + + + +adb.adb_commands.AdbCommands.__init__ + + +Node1 + +adb.adb_commands.AdbCommands. +__init__ + + +Node2 + + +adb.adb_commands.AdbCommands. +__reset + + + + +Node1->Node2 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node5 + + + + +Node3 + + +adb.adb_commands.AdbCommands. +Close + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.UsbHandle.Open + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALLER_GRAPH.svg new file mode 100644 index 0000000..2f7541a --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALLER_GRAPH.svg @@ -0,0 +1,46 @@ + + + + + + +adb.adb_commands.AdbCommands.__reset + + +Node1 + +adb.adb_commands.AdbCommands. +__reset + + +Node2 + + +adb.adb_commands.AdbCommands. +Close + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Open + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALL_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALL_GRAPH.svg new file mode 100644 index 0000000..6357ff4 --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands.__reset.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands.__reset + + +Node1 + +adb.adb_commands.AdbCommands. +__reset + + +Node2 + + +adb.adb_commands.AdbCommands. +__init__ + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_commands.AdbCommands._get_service_connection.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_commands.AdbCommands._get_service_connection.CALLER_GRAPH.svg new file mode 100644 index 0000000..17ff06d --- /dev/null +++ b/docs/source/_static/adb.adb_commands.AdbCommands._get_service_connection.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_commands.AdbCommands._get_service_connection + + +Node1 + +adb.adb_commands.AdbCommands. +_get_service_connection + + +Node2 + + +adb.adb_commands.AdbCommands. +InteractiveShell + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_debug.Devices.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_debug.Devices.CALLER_GRAPH.svg new file mode 100644 index 0000000..db4fb16 --- /dev/null +++ b/docs/source/_static/adb.adb_debug.Devices.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.adb_debug.Devices + + +Node1 + +adb.adb_debug.Devices + + +Node2 + + +adb.adb_debug.main + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_debug.main.CALL_GRAPH.svg b/docs/source/_static/adb.adb_debug.main.CALL_GRAPH.svg new file mode 100644 index 0000000..7c14bd2 --- /dev/null +++ b/docs/source/_static/adb.adb_debug.main.CALL_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.adb_debug.main + + +Node1 + +adb.adb_debug.main + + +Node2 + + +adb.adb_debug.Devices + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.CALL_GRAPH.svg new file mode 100644 index 0000000..ddb9c6b --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.adb_protocol.AdbMessage + + +Node1 + +adb.adb_protocol.AdbMessage + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.CalculateChecksum.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.CalculateChecksum.CALLER_GRAPH.svg new file mode 100644 index 0000000..4a89a24 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.CalculateChecksum.CALLER_GRAPH.svg @@ -0,0 +1,140 @@ + + + + + + +adb.adb_protocol.AdbMessage.CalculateChecksum + + +Node1 + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + +Node2 + + +adb.adb_protocol.AdbMessage.checksum + + + + +Node1->Node2 + + + + +Node5 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node1->Node5 + + + + +Node3 + + +adb.adb_protocol.AdbMessage.Pack + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage.Send + + + + +Node3->Node4 + + + + +Node6 + + +adb.adb_protocol.AdbMessage. +Connect + + + + +Node5->Node6 + + + + +Node7 + + +adb.adb_protocol.AdbMessage.Open + + + + +Node5->Node7 + + + + +Node10 + + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + + + +Node5->Node10 + + + + +Node8 + + +adb.adb_protocol.AdbMessage. +StreamingCommand + + + + +Node7->Node8 + + + + +Node9 + + +adb.adb_protocol.AdbMessage. +Command + + + + +Node8->Node9 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Command.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Command.CALL_GRAPH.svg new file mode 100644 index 0000000..6d70e21 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Command.CALL_GRAPH.svg @@ -0,0 +1,87 @@ + + + + + + +adb.adb_protocol.AdbMessage.Command + + +Node1 + +adb.adb_protocol.AdbMessage. +Command + + +Node2 + + +adb.adb_protocol.AdbMessage. +StreamingCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage.Open + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node3->Node4 + + + + +Node5 + + +adb.adb_protocol.AdbMessage. +Unpack + + + + +Node4->Node5 + + + + +Node6 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node4->Node6 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Connect.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Connect.CALL_GRAPH.svg new file mode 100644 index 0000000..70e7557 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Connect.CALL_GRAPH.svg @@ -0,0 +1,60 @@ + + + + + + +adb.adb_protocol.AdbMessage.Connect + + +Node1 + +adb.adb_protocol.AdbMessage. +Connect + + +Node2 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +Unpack + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node2->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.InteractiveShellCommand.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.InteractiveShellCommand.CALL_GRAPH.svg new file mode 100644 index 0000000..30bdc77 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.InteractiveShellCommand.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_protocol.AdbMessage.InteractiveShellCommand + + +Node1 + +adb.adb_protocol.AdbMessage. +InteractiveShellCommand + + +Node2 + + +adb.adb_protocol.find +_backspace_runs + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALLER_GRAPH.svg new file mode 100644 index 0000000..9ccb730 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALLER_GRAPH.svg @@ -0,0 +1,46 @@ + + + + + + +adb.adb_protocol.AdbMessage.Open + + +Node1 + +adb.adb_protocol.AdbMessage.Open + + +Node2 + + +adb.adb_protocol.AdbMessage. +StreamingCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +Command + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALL_GRAPH.svg new file mode 100644 index 0000000..4283b1e --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Open.CALL_GRAPH.svg @@ -0,0 +1,59 @@ + + + + + + +adb.adb_protocol.AdbMessage.Open + + +Node1 + +adb.adb_protocol.AdbMessage.Open + + +Node2 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +Unpack + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node2->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALLER_GRAPH.svg new file mode 100644 index 0000000..fede063 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.adb_protocol.AdbMessage.Pack + + +Node1 + +adb.adb_protocol.AdbMessage.Pack + + +Node2 + + +adb.adb_protocol.AdbMessage.Send + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALL_GRAPH.svg new file mode 100644 index 0000000..6a55f6d --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Pack.CALL_GRAPH.svg @@ -0,0 +1,45 @@ + + + + + + +adb.adb_protocol.AdbMessage.Pack + + +Node1 + +adb.adb_protocol.AdbMessage.Pack + + +Node2 + + +adb.adb_protocol.AdbMessage.checksum + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALLER_GRAPH.svg new file mode 100644 index 0000000..2c19eac --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALLER_GRAPH.svg @@ -0,0 +1,87 @@ + + + + + + +adb.adb_protocol.AdbMessage.Read + + +Node1 + +adb.adb_protocol.AdbMessage.Read + + +Node2 + + +adb.adb_protocol.AdbMessage. +Connect + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage.Open + + + + +Node1->Node3 + + + + +Node6 + + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + + + +Node1->Node6 + + + + +Node4 + + +adb.adb_protocol.AdbMessage. +StreamingCommand + + + + +Node3->Node4 + + + + +Node5 + + +adb.adb_protocol.AdbMessage. +Command + + + + +Node4->Node5 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALL_GRAPH.svg new file mode 100644 index 0000000..c6aa34e --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Read.CALL_GRAPH.svg @@ -0,0 +1,46 @@ + + + + + + +adb.adb_protocol.AdbMessage.Read + + +Node1 + +adb.adb_protocol.AdbMessage.Read + + +Node2 + + +adb.adb_protocol.AdbMessage. +Unpack + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node1->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Send.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Send.CALL_GRAPH.svg new file mode 100644 index 0000000..d8e0aeb --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Send.CALL_GRAPH.svg @@ -0,0 +1,58 @@ + + + + + + +adb.adb_protocol.AdbMessage.Send + + +Node1 + +adb.adb_protocol.AdbMessage.Send + + +Node2 + + +adb.adb_protocol.AdbMessage.Pack + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage.checksum + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALLER_GRAPH.svg new file mode 100644 index 0000000..d372912 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_protocol.AdbMessage.StreamingCommand + + +Node1 + +adb.adb_protocol.AdbMessage. +StreamingCommand + + +Node2 + + +adb.adb_protocol.AdbMessage. +Command + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALL_GRAPH.svg new file mode 100644 index 0000000..3c61c00 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.StreamingCommand.CALL_GRAPH.svg @@ -0,0 +1,73 @@ + + + + + + +adb.adb_protocol.AdbMessage.StreamingCommand + + +Node1 + +adb.adb_protocol.AdbMessage. +StreamingCommand + + +Node2 + + +adb.adb_protocol.AdbMessage.Open + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage. +Unpack + + + + +Node3->Node4 + + + + +Node5 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node3->Node5 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.Unpack.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.Unpack.CALLER_GRAPH.svg new file mode 100644 index 0000000..c3a57c8 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.Unpack.CALLER_GRAPH.svg @@ -0,0 +1,101 @@ + + + + + + +adb.adb_protocol.AdbMessage.Unpack + + +Node1 + +adb.adb_protocol.AdbMessage. +Unpack + + +Node2 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +Connect + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage.Open + + + + +Node2->Node4 + + + + +Node7 + + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + + + +Node2->Node7 + + + + +Node5 + + +adb.adb_protocol.AdbMessage. +StreamingCommand + + + + +Node4->Node5 + + + + +Node6 + + +adb.adb_protocol.AdbMessage. +Command + + + + +Node5->Node6 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..60bc60c --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_protocol.AdbMessage.__init__ + + +Node1 + +adb.adb_protocol.AdbMessage. +__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALLER_GRAPH.svg new file mode 100644 index 0000000..33c0eb4 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALLER_GRAPH.svg @@ -0,0 +1,44 @@ + + + + + + +adb.adb_protocol.AdbMessage.checksum + + +Node1 + +adb.adb_protocol.AdbMessage.checksum + + +Node2 + + +adb.adb_protocol.AdbMessage.Pack + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.AdbMessage.Send + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALL_GRAPH.svg new file mode 100644 index 0000000..cac01ea --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AdbMessage.checksum.CALL_GRAPH.svg @@ -0,0 +1,32 @@ + + + + + + +adb.adb_protocol.AdbMessage.checksum + + +Node1 + +adb.adb_protocol.AdbMessage.checksum + + +Node2 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.AuthSigner.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.AuthSigner.CALL_GRAPH.svg new file mode 100644 index 0000000..d9bb1f7 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.AuthSigner.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.adb_protocol.AuthSigner + + +Node1 + +adb.adb_protocol.AuthSigner + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.InterleavedDataError.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.InterleavedDataError.CALL_GRAPH.svg new file mode 100644 index 0000000..b4679b3 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.InterleavedDataError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.adb_protocol.InterleavedDataError + + +Node1 + +adb.adb_protocol.Interleaved +DataError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.InvalidChecksumError.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.InvalidChecksumError.CALL_GRAPH.svg new file mode 100644 index 0000000..7f7e499 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.InvalidChecksumError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.adb_protocol.InvalidChecksumError + + +Node1 + +adb.adb_protocol.Invalid +ChecksumError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.InvalidCommandError.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.InvalidCommandError.CALL_GRAPH.svg new file mode 100644 index 0000000..96bd5a3 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.InvalidCommandError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.adb_protocol.InvalidCommandError + + +Node1 + +adb.adb_protocol.Invalid +CommandError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.InvalidCommandError.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.InvalidCommandError.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..2a15d71 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.InvalidCommandError.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_protocol.InvalidCommandError.__init__ + + +Node1 + +adb.adb_protocol.Invalid +CommandError.__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.InvalidResponseError.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol.InvalidResponseError.CALL_GRAPH.svg new file mode 100644 index 0000000..78a9e64 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.InvalidResponseError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.adb_protocol.InvalidResponseError + + +Node1 + +adb.adb_protocol.Invalid +ResponseError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.CALL_GRAPH.svg new file mode 100644 index 0000000..50b9ec9 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.adb_protocol._AdbConnection + + +Node1 + +adb.adb_protocol._AdbConnection + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALLER_GRAPH.svg new file mode 100644 index 0000000..85a27ec --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALLER_GRAPH.svg @@ -0,0 +1,32 @@ + + + + + + +adb.adb_protocol._AdbConnection.Close + + +Node1 + +adb.adb_protocol._AdbConnection. +Close + + +Node2 + + +adb.common.UsbHandle.Open + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALL_GRAPH.svg new file mode 100644 index 0000000..de29bf2 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.Close.CALL_GRAPH.svg @@ -0,0 +1,64 @@ + + + + + + +adb.adb_protocol._AdbConnection.Close + + +Node1 + +adb.adb_protocol._AdbConnection. +Close + + +Node2 + + +adb.adb_protocol._AdbConnection._Send + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol._AdbConnection. +ReadUntil + + + + +Node1->Node3 + + + + +Node4 + + +adb.adb_protocol._AdbConnection.Okay + + + + +Node3->Node4 + + + + +Node4->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALLER_GRAPH.svg new file mode 100644 index 0000000..d94bd71 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALLER_GRAPH.svg @@ -0,0 +1,87 @@ + + + + + + +adb.adb_protocol._AdbConnection.Okay + + +Node1 + +adb.adb_protocol._AdbConnection.Okay + + +Node2 + + +adb.adb_protocol._AdbConnection. +ReadUntil + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol._AdbConnection. +Write + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol._AdbConnection. +ReadUntilClose + + + + +Node2->Node4 + + + + +Node5 + + +adb.adb_protocol._AdbConnection. +Close + + + + +Node2->Node5 + + + + +Node6 + + +adb.common.UsbHandle.Open + + + + +Node5->Node6 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALL_GRAPH.svg new file mode 100644 index 0000000..5d748bf --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.Okay.CALL_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.adb_protocol._AdbConnection.Okay + + +Node1 + +adb.adb_protocol._AdbConnection.Okay + + +Node2 + + +adb.adb_protocol._AdbConnection._Send + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALLER_GRAPH.svg new file mode 100644 index 0000000..0c4d024 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALLER_GRAPH.svg @@ -0,0 +1,74 @@ + + + + + + +adb.adb_protocol._AdbConnection.ReadUntil + + +Node1 + +adb.adb_protocol._AdbConnection. +ReadUntil + + +Node2 + + +adb.adb_protocol._AdbConnection. +Close + + + + +Node1->Node2 + + + + +Node4 + + +adb.adb_protocol._AdbConnection. +ReadUntilClose + + + + +Node1->Node4 + + + + +Node5 + + +adb.adb_protocol._AdbConnection. +Write + + + + +Node1->Node5 + + + + +Node3 + + +adb.common.UsbHandle.Open + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALL_GRAPH.svg new file mode 100644 index 0000000..3c4ca0c --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntil.CALL_GRAPH.svg @@ -0,0 +1,45 @@ + + + + + + +adb.adb_protocol._AdbConnection.ReadUntil + + +Node1 + +adb.adb_protocol._AdbConnection. +ReadUntil + + +Node2 + + +adb.adb_protocol._AdbConnection.Okay + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol._AdbConnection._Send + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntilClose.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntilClose.CALL_GRAPH.svg new file mode 100644 index 0000000..db806fc --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.ReadUntilClose.CALL_GRAPH.svg @@ -0,0 +1,64 @@ + + + + + + +adb.adb_protocol._AdbConnection.ReadUntilClose + + +Node1 + +adb.adb_protocol._AdbConnection. +ReadUntilClose + + +Node2 + + +adb.adb_protocol._AdbConnection. +ReadUntil + + + + +Node1->Node2 + + + + +Node4 + + +adb.adb_protocol._AdbConnection._Send + + + + +Node1->Node4 + + + + +Node3 + + +adb.adb_protocol._AdbConnection.Okay + + + + +Node2->Node3 + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.Write.CALL_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.Write.CALL_GRAPH.svg new file mode 100644 index 0000000..030306e --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.Write.CALL_GRAPH.svg @@ -0,0 +1,64 @@ + + + + + + +adb.adb_protocol._AdbConnection.Write + + +Node1 + +adb.adb_protocol._AdbConnection. +Write + + +Node2 + + +adb.adb_protocol._AdbConnection._Send + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol._AdbConnection. +ReadUntil + + + + +Node1->Node3 + + + + +Node4 + + +adb.adb_protocol._AdbConnection.Okay + + + + +Node3->Node4 + + + + +Node4->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection._Send.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection._Send.CALLER_GRAPH.svg new file mode 100644 index 0000000..17ea54a --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection._Send.CALLER_GRAPH.svg @@ -0,0 +1,115 @@ + + + + + + +adb.adb_protocol._AdbConnection._Send + + +Node1 + +adb.adb_protocol._AdbConnection._Send + + +Node2 + + +adb.adb_protocol._AdbConnection. +Close + + + + +Node1->Node2 + + + + +Node4 + + +adb.adb_protocol._AdbConnection.Okay + + + + +Node1->Node4 + + + + +Node6 + + +adb.adb_protocol._AdbConnection. +Write + + + + +Node1->Node6 + + + + +Node7 + + +adb.adb_protocol._AdbConnection. +ReadUntilClose + + + + +Node1->Node7 + + + + +Node3 + + +adb.common.UsbHandle.Open + + + + +Node2->Node3 + + + + +Node5 + + +adb.adb_protocol._AdbConnection. +ReadUntil + + + + +Node4->Node5 + + + + +Node5->Node2 + + + + +Node5->Node6 + + + + +Node5->Node7 + + + + + diff --git a/docs/source/_static/adb.adb_protocol._AdbConnection.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol._AdbConnection.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..ea8ba7e --- /dev/null +++ b/docs/source/_static/adb.adb_protocol._AdbConnection.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_protocol._AdbConnection.__init__ + + +Node1 + +adb.adb_protocol._AdbConnection. +__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.adb_protocol.find_backspace_runs.CALLER_GRAPH.svg b/docs/source/_static/adb.adb_protocol.find_backspace_runs.CALLER_GRAPH.svg new file mode 100644 index 0000000..6465457 --- /dev/null +++ b/docs/source/_static/adb.adb_protocol.find_backspace_runs.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.adb_protocol.find_backspace_runs + + +Node1 + +adb.adb_protocol.find +_backspace_runs + + +Node2 + + +adb.adb_protocol.AdbMessage. +InteractiveShellCommand + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.GetInterface.CALLER_GRAPH.svg b/docs/source/_static/adb.common.GetInterface.CALLER_GRAPH.svg new file mode 100644 index 0000000..95f33eb --- /dev/null +++ b/docs/source/_static/adb.common.GetInterface.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common.GetInterface + + +Node1 + +adb.common.GetInterface + + +Node2 + + +adb.common.InterfaceMatcher + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.InterfaceMatcher.CALL_GRAPH.svg b/docs/source/_static/adb.common.InterfaceMatcher.CALL_GRAPH.svg new file mode 100644 index 0000000..b1f7adc --- /dev/null +++ b/docs/source/_static/adb.common.InterfaceMatcher.CALL_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common.InterfaceMatcher + + +Node1 + +adb.common.InterfaceMatcher + + +Node2 + + +adb.common.GetInterface + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.BulkRead.CALL_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.BulkRead.CALL_GRAPH.svg new file mode 100644 index 0000000..49dcba8 --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.BulkRead.CALL_GRAPH.svg @@ -0,0 +1,58 @@ + + + + + + +adb.common.TcpHandle.BulkRead + + +Node1 + +adb.common.TcpHandle.BulkRead + + +Node2 + + +adb.common.TcpHandle.Timeout +Seconds + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Timeout + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.TcpHandle.Timeout + + + + +Node2->Node4 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.BulkWrite.CALL_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.BulkWrite.CALL_GRAPH.svg new file mode 100644 index 0000000..114351f --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.BulkWrite.CALL_GRAPH.svg @@ -0,0 +1,87 @@ + + + + + + +adb.common.TcpHandle.BulkWrite + + +Node1 + +adb.common.TcpHandle.Bulk +Write + + +Node2 + + +adb.common.TcpHandle.Timeout +Seconds + + + + +Node1->Node2 + + + + +Node5 + + +adb.common.UsbHandle.serial +_number + + + + +Node1->Node5 + + + + +Node6 + + +adb.common.TcpHandle.serial +_number + + + + +Node1->Node6 + + + + +Node3 + + +adb.common.UsbHandle.Timeout + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.TcpHandle.Timeout + + + + +Node2->Node4 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.CALL_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.CALL_GRAPH.svg new file mode 100644 index 0000000..cc7a211 --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.common.TcpHandle + + +Node1 + +adb.common.TcpHandle + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.Timeout.CALLER_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.Timeout.CALLER_GRAPH.svg new file mode 100644 index 0000000..4246645 --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.Timeout.CALLER_GRAPH.svg @@ -0,0 +1,73 @@ + + + + + + +adb.common.TcpHandle.Timeout + + +Node1 + +adb.common.TcpHandle.Timeout + + +Node2 + + +adb.common.TcpHandle.Timeout +Seconds + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.TcpHandle. +_connect + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.TcpHandle.Bulk +Write + + + + +Node2->Node4 + + + + +Node5 + + +adb.common.TcpHandle.BulkRead + + + + +Node2->Node5 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALLER_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALLER_GRAPH.svg new file mode 100644 index 0000000..46c573b --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALLER_GRAPH.svg @@ -0,0 +1,60 @@ + + + + + + +adb.common.TcpHandle.TimeoutSeconds + + +Node1 + +adb.common.TcpHandle.Timeout +Seconds + + +Node2 + + +adb.common.TcpHandle. +_connect + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.TcpHandle.BulkRead + + + + +Node1->Node3 + + + + +Node4 + + +adb.common.TcpHandle.Bulk +Write + + + + +Node1->Node4 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALL_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALL_GRAPH.svg new file mode 100644 index 0000000..ef22147 --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.TimeoutSeconds.CALL_GRAPH.svg @@ -0,0 +1,45 @@ + + + + + + +adb.common.TcpHandle.TimeoutSeconds + + +Node1 + +adb.common.TcpHandle.Timeout +Seconds + + +Node2 + + +adb.common.UsbHandle.Timeout + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.TcpHandle.Timeout + + + + +Node1->Node3 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..383d7ca --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.common.TcpHandle.__init__ + + +Node1 + +adb.common.TcpHandle. +__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle._connect.CALL_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle._connect.CALL_GRAPH.svg new file mode 100644 index 0000000..b486258 --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle._connect.CALL_GRAPH.svg @@ -0,0 +1,59 @@ + + + + + + +adb.common.TcpHandle._connect + + +Node1 + +adb.common.TcpHandle. +_connect + + +Node2 + + +adb.common.TcpHandle.Timeout +Seconds + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Timeout + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.TcpHandle.Timeout + + + + +Node2->Node4 + + + + + diff --git a/docs/source/_static/adb.common.TcpHandle.serial_number.CALLER_GRAPH.svg b/docs/source/_static/adb.common.TcpHandle.serial_number.CALLER_GRAPH.svg new file mode 100644 index 0000000..7fb0747 --- /dev/null +++ b/docs/source/_static/adb.common.TcpHandle.serial_number.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.common.TcpHandle.serial_number + + +Node1 + +adb.common.TcpHandle.serial +_number + + +Node2 + + +adb.common.TcpHandle.Bulk +Write + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.BulkRead.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.BulkRead.CALLER_GRAPH.svg new file mode 100644 index 0000000..1eec197 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.BulkRead.CALLER_GRAPH.svg @@ -0,0 +1,32 @@ + + + + + + +adb.common.UsbHandle.BulkRead + + +Node1 + +adb.common.UsbHandle.BulkRead + + +Node2 + + +adb.common.UsbHandle.Flush +Buffers + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.BulkRead.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.BulkRead.CALL_GRAPH.svg new file mode 100644 index 0000000..60b1666 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.BulkRead.CALL_GRAPH.svg @@ -0,0 +1,58 @@ + + + + + + +adb.common.UsbHandle.BulkRead + + +Node1 + +adb.common.UsbHandle.BulkRead + + +Node2 + + +adb.common.UsbHandle.Timeout + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.usb_info + + + + +Node1->Node3 + + + + +Node4 + + +adb.common.UsbHandle.serial +_number + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.BulkWrite.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.BulkWrite.CALL_GRAPH.svg new file mode 100644 index 0000000..20510d9 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.BulkWrite.CALL_GRAPH.svg @@ -0,0 +1,59 @@ + + + + + + +adb.common.UsbHandle.BulkWrite + + +Node1 + +adb.common.UsbHandle.Bulk +Write + + +Node2 + + +adb.common.UsbHandle.Timeout + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.usb_info + + + + +Node1->Node3 + + + + +Node4 + + +adb.common.UsbHandle.serial +_number + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.CALL_GRAPH.svg new file mode 100644 index 0000000..5069fa9 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.common.UsbHandle + + +Node1 + +adb.common.UsbHandle + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.Close.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.Close.CALLER_GRAPH.svg new file mode 100644 index 0000000..e8a1bb2 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.Close.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common.UsbHandle.Close + + +Node1 + +adb.common.UsbHandle.Close + + +Node2 + + +adb.common.UsbHandle.Open + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.Close.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.Close.CALL_GRAPH.svg new file mode 100644 index 0000000..f5a6c33 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.Close.CALL_GRAPH.svg @@ -0,0 +1,45 @@ + + + + + + +adb.common.UsbHandle.Close + + +Node1 + +adb.common.UsbHandle.Close + + +Node2 + + +adb.common.UsbHandle.usb_info + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.serial +_number + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.Find.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.Find.CALLER_GRAPH.svg new file mode 100644 index 0000000..9d1f1dd --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.Find.CALLER_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.common.UsbHandle.Find + + +Node1 + +adb.common.UsbHandle.Find + + +Node2 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node2->Node3 + + + + +Node3->Node1 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.Find.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.Find.CALL_GRAPH.svg new file mode 100644 index 0000000..886caab --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.Find.CALL_GRAPH.svg @@ -0,0 +1,93 @@ + + + + + + +adb.common.UsbHandle.Find + + +Node1 + +adb.common.UsbHandle.Find + + +Node2 + + +adb.common.UsbHandle.Port +PathMatcher + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node1->Node3 + + + + +Node5 + + +adb.common.UsbHandle.Find +First + + + + +Node1->Node5 + + + + +Node4 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node3->Node4 + + + + +Node4->Node1 + + + + +Node6 + + +adb.common.UsbHandle.Find +Devices + + + + +Node5->Node6 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALLER_GRAPH.svg new file mode 100644 index 0000000..cd799a3 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALLER_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.common.UsbHandle.FindAndOpen + + +Node1 + +adb.common.UsbHandle.Find +AndOpen + + +Node2 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Find + + + + +Node2->Node3 + + + + +Node3->Node1 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALL_GRAPH.svg new file mode 100644 index 0000000..4f4b7e7 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.FindAndOpen.CALL_GRAPH.svg @@ -0,0 +1,93 @@ + + + + + + +adb.common.UsbHandle.FindAndOpen + + +Node1 + +adb.common.UsbHandle.Find +AndOpen + + +Node2 + + +adb.common.UsbHandle.Find + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Port +PathMatcher + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node2->Node4 + + + + +Node5 + + +adb.common.UsbHandle.Find +First + + + + +Node2->Node5 + + + + +Node4->Node1 + + + + +Node6 + + +adb.common.UsbHandle.Find +Devices + + + + +Node5->Node6 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.FindDevices.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.FindDevices.CALLER_GRAPH.svg new file mode 100644 index 0000000..9cb9419 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.FindDevices.CALLER_GRAPH.svg @@ -0,0 +1,79 @@ + + + + + + +adb.common.UsbHandle.FindDevices + + +Node1 + +adb.common.UsbHandle.Find +Devices + + +Node2 + + +adb.common.UsbHandle.Find +First + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Find + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node3->Node4 + + + + +Node5 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node4->Node5 + + + + +Node5->Node3 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.FindFirst.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.FindFirst.CALLER_GRAPH.svg new file mode 100644 index 0000000..c1bcfe4 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.FindFirst.CALLER_GRAPH.svg @@ -0,0 +1,65 @@ + + + + + + +adb.common.UsbHandle.FindFirst + + +Node1 + +adb.common.UsbHandle.Find +First + + +Node2 + + +adb.common.UsbHandle.Find + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node3->Node4 + + + + +Node4->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.FindFirst.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.FindFirst.CALL_GRAPH.svg new file mode 100644 index 0000000..76f0250 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.FindFirst.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.common.UsbHandle.FindFirst + + +Node1 + +adb.common.UsbHandle.Find +First + + +Node2 + + +adb.common.UsbHandle.Find +Devices + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.FlushBuffers.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.FlushBuffers.CALL_GRAPH.svg new file mode 100644 index 0000000..95a13f8 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.FlushBuffers.CALL_GRAPH.svg @@ -0,0 +1,72 @@ + + + + + + +adb.common.UsbHandle.FlushBuffers + + +Node1 + +adb.common.UsbHandle.Flush +Buffers + + +Node2 + + +adb.common.UsbHandle.BulkRead + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Timeout + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.UsbHandle.usb_info + + + + +Node2->Node4 + + + + +Node5 + + +adb.common.UsbHandle.serial +_number + + + + +Node4->Node5 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.Open.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.Open.CALL_GRAPH.svg new file mode 100644 index 0000000..c918aba --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.Open.CALL_GRAPH.svg @@ -0,0 +1,172 @@ + + + + + + +adb.common.UsbHandle.Open + + +Node1 + +adb.common.UsbHandle.Open + + +Node2 + + +adb.common.UsbHandle.port_path + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_commands.AdbCommands. +Close + + + + +Node1->Node3 + + + + +Node6 + + +adb.adb_protocol._AdbConnection. +Close + + + + +Node1->Node6 + + + + +Node10 + + +adb.common.UsbHandle.Close + + + + +Node1->Node10 + + + + +Node4 + + +adb.adb_commands.AdbCommands. +__reset + + + + +Node3->Node4 + + + + +Node5 + + +adb.adb_commands.AdbCommands. +__init__ + + + + +Node4->Node5 + + + + +Node7 + + +adb.adb_protocol._AdbConnection._Send + + + + +Node6->Node7 + + + + +Node8 + + +adb.adb_protocol._AdbConnection. +ReadUntil + + + + +Node6->Node8 + + + + +Node9 + + +adb.adb_protocol._AdbConnection.Okay + + + + +Node8->Node9 + + + + +Node9->Node7 + + + + +Node11 + + +adb.common.UsbHandle.usb_info + + + + +Node10->Node11 + + + + +Node12 + + +adb.common.UsbHandle.serial +_number + + + + +Node11->Node12 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.PortPathMatcher.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.PortPathMatcher.CALLER_GRAPH.svg new file mode 100644 index 0000000..e7bcb76 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.PortPathMatcher.CALLER_GRAPH.svg @@ -0,0 +1,65 @@ + + + + + + +adb.common.UsbHandle.PortPathMatcher + + +Node1 + +adb.common.UsbHandle.Port +PathMatcher + + +Node2 + + +adb.common.UsbHandle.Find + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node2->Node3 + + + + +Node4 + + +adb.common.UsbHandle.Serial +Matcher + + + + +Node3->Node4 + + + + +Node4->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALLER_GRAPH.svg new file mode 100644 index 0000000..c43f32b --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALLER_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.common.UsbHandle.SerialMatcher + + +Node1 + +adb.common.UsbHandle.Serial +Matcher + + +Node2 + + +adb.common.UsbHandle.Find + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node2->Node3 + + + + +Node3->Node1 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALL_GRAPH.svg new file mode 100644 index 0000000..cca6002 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.SerialMatcher.CALL_GRAPH.svg @@ -0,0 +1,93 @@ + + + + + + +adb.common.UsbHandle.SerialMatcher + + +Node1 + +adb.common.UsbHandle.Serial +Matcher + + +Node2 + + +adb.common.UsbHandle.Find +AndOpen + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.Find + + + + +Node2->Node3 + + + + +Node3->Node1 + + + + +Node4 + + +adb.common.UsbHandle.Port +PathMatcher + + + + +Node3->Node4 + + + + +Node5 + + +adb.common.UsbHandle.Find +First + + + + +Node3->Node5 + + + + +Node6 + + +adb.common.UsbHandle.Find +Devices + + + + +Node5->Node6 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.Timeout.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.Timeout.CALLER_GRAPH.svg new file mode 100644 index 0000000..c81c278 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.Timeout.CALLER_GRAPH.svg @@ -0,0 +1,114 @@ + + + + + + +adb.common.UsbHandle.Timeout + + +Node1 + +adb.common.UsbHandle.Timeout + + +Node2 + + +adb.common.UsbHandle.BulkRead + + + + +Node1->Node2 + + + + +Node4 + + +adb.common.UsbHandle.Bulk +Write + + + + +Node1->Node4 + + + + +Node5 + + +adb.common.TcpHandle.Timeout +Seconds + + + + +Node1->Node5 + + + + +Node3 + + +adb.common.UsbHandle.Flush +Buffers + + + + +Node2->Node3 + + + + +Node6 + + +adb.common.TcpHandle. +_connect + + + + +Node5->Node6 + + + + +Node7 + + +adb.common.TcpHandle.BulkRead + + + + +Node5->Node7 + + + + +Node8 + + +adb.common.TcpHandle.Bulk +Write + + + + +Node5->Node8 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..d10f236 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.common.UsbHandle.__init__ + + +Node1 + +adb.common.UsbHandle. +__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.port_path.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.port_path.CALLER_GRAPH.svg new file mode 100644 index 0000000..4ce2a32 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.port_path.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common.UsbHandle.port_path + + +Node1 + +adb.common.UsbHandle.port_path + + +Node2 + + +adb.common.UsbHandle.Open + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.serial_number.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.serial_number.CALLER_GRAPH.svg new file mode 100644 index 0000000..9f7f1a0 --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.serial_number.CALLER_GRAPH.svg @@ -0,0 +1,113 @@ + + + + + + +adb.common.UsbHandle.serial_number + + +Node1 + +adb.common.UsbHandle.serial +_number + + +Node2 + + +adb.common.TcpHandle.Bulk +Write + + + + +Node1->Node2 + + + + +Node3 + + +adb.common.UsbHandle.usb_info + + + + +Node1->Node3 + + + + +Node4 + + +adb.common.UsbHandle.Close + + + + +Node3->Node4 + + + + +Node6 + + +adb.common.UsbHandle.Bulk +Write + + + + +Node3->Node6 + + + + +Node7 + + +adb.common.UsbHandle.BulkRead + + + + +Node3->Node7 + + + + +Node5 + + +adb.common.UsbHandle.Open + + + + +Node4->Node5 + + + + +Node8 + + +adb.common.UsbHandle.Flush +Buffers + + + + +Node7->Node8 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.usb_info.CALLER_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.usb_info.CALLER_GRAPH.svg new file mode 100644 index 0000000..5f8066b --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.usb_info.CALLER_GRAPH.svg @@ -0,0 +1,85 @@ + + + + + + +adb.common.UsbHandle.usb_info + + +Node1 + +adb.common.UsbHandle.usb_info + + +Node2 + + +adb.common.UsbHandle.BulkRead + + + + +Node1->Node2 + + + + +Node4 + + +adb.common.UsbHandle.Bulk +Write + + + + +Node1->Node4 + + + + +Node5 + + +adb.common.UsbHandle.Close + + + + +Node1->Node5 + + + + +Node3 + + +adb.common.UsbHandle.Flush +Buffers + + + + +Node2->Node3 + + + + +Node6 + + +adb.common.UsbHandle.Open + + + + +Node5->Node6 + + + + + diff --git a/docs/source/_static/adb.common.UsbHandle.usb_info.CALL_GRAPH.svg b/docs/source/_static/adb.common.UsbHandle.usb_info.CALL_GRAPH.svg new file mode 100644 index 0000000..f50a91a --- /dev/null +++ b/docs/source/_static/adb.common.UsbHandle.usb_info.CALL_GRAPH.svg @@ -0,0 +1,32 @@ + + + + + + +adb.common.UsbHandle.usb_info + + +Node1 + +adb.common.UsbHandle.usb_info + + +Node2 + + +adb.common.UsbHandle.serial +_number + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common_cli.MakeSubparser.CALL_GRAPH.svg b/docs/source/_static/adb.common_cli.MakeSubparser.CALL_GRAPH.svg new file mode 100644 index 0000000..fa80e2a --- /dev/null +++ b/docs/source/_static/adb.common_cli.MakeSubparser.CALL_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common_cli.MakeSubparser + + +Node1 + +adb.common_cli.MakeSubparser + + +Node2 + + +adb.common_cli._DocToArgs + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common_cli.PositionalArg.CALL_GRAPH.svg b/docs/source/_static/adb.common_cli.PositionalArg.CALL_GRAPH.svg new file mode 100644 index 0000000..2fd33e8 --- /dev/null +++ b/docs/source/_static/adb.common_cli.PositionalArg.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.common_cli.PositionalArg + + +Node1 + +adb.common_cli.PositionalArg + + +Node2 + +Action + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.common_cli.StartCli.CALL_GRAPH.svg b/docs/source/_static/adb.common_cli.StartCli.CALL_GRAPH.svg new file mode 100644 index 0000000..572b56e --- /dev/null +++ b/docs/source/_static/adb.common_cli.StartCli.CALL_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common_cli.StartCli + + +Node1 + +adb.common_cli.StartCli + + +Node2 + + +adb.common_cli._RunMethod + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common_cli._DocToArgs.CALLER_GRAPH.svg b/docs/source/_static/adb.common_cli._DocToArgs.CALLER_GRAPH.svg new file mode 100644 index 0000000..962bd29 --- /dev/null +++ b/docs/source/_static/adb.common_cli._DocToArgs.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common_cli._DocToArgs + + +Node1 + +adb.common_cli._DocToArgs + + +Node2 + + +adb.common_cli.MakeSubparser + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.common_cli._PortPathAction.CALL_GRAPH.svg b/docs/source/_static/adb.common_cli._PortPathAction.CALL_GRAPH.svg new file mode 100644 index 0000000..c96367f --- /dev/null +++ b/docs/source/_static/adb.common_cli._PortPathAction.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.common_cli._PortPathAction + + +Node1 + +adb.common_cli._PortPath +Action + + +Node2 + +argparse::Action + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.common_cli._RunMethod.CALLER_GRAPH.svg b/docs/source/_static/adb.common_cli._RunMethod.CALLER_GRAPH.svg new file mode 100644 index 0000000..20141b6 --- /dev/null +++ b/docs/source/_static/adb.common_cli._RunMethod.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.common_cli._RunMethod + + +Node1 + +adb.common_cli._RunMethod + + +Node2 + + +adb.common_cli.StartCli + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.CALL_GRAPH.svg new file mode 100644 index 0000000..90c3d7b --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.fastboot.FastbootCommands + + +Node1 + +adb.fastboot.FastbootCommands + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Continue.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Continue.CALL_GRAPH.svg new file mode 100644 index 0000000..3a375f0 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Continue.CALL_GRAPH.svg @@ -0,0 +1,80 @@ + + + + + + +adb.fastboot.FastbootCommands.Continue + + +Node1 + +adb.fastboot.FastbootCommands. +Continue + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node5 + + + + +Node5->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Download.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Download.CALLER_GRAPH.svg new file mode 100644 index 0000000..bf0a5cd --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Download.CALLER_GRAPH.svg @@ -0,0 +1,149 @@ + + + + + + +adb.fastboot.FastbootCommands.Download + + +Node1 + +adb.fastboot.FastbootCommands. +Download + + +Node2 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Continue + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Erase + + + + +Node3->Node5 + + + + +Node6 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node6 + + + + +Node7 + + +adb.fastboot.FastbootCommands. +Getvar + + + + +Node3->Node7 + + + + +Node8 + + +adb.fastboot.FastbootCommands.Oem + + + + +Node3->Node8 + + + + +Node9 + + +adb.fastboot.FastbootCommands. +Reboot + + + + +Node3->Node9 + + + + +Node10 + + +adb.fastboot.FastbootCommands. +RebootBootloader + + + + +Node3->Node10 + + + + +Node6->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Erase.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Erase.CALL_GRAPH.svg new file mode 100644 index 0000000..f1c8c32 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Erase.CALL_GRAPH.svg @@ -0,0 +1,80 @@ + + + + + + +adb.fastboot.FastbootCommands.Erase + + +Node1 + +adb.fastboot.FastbootCommands. +Erase + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node5 + + + + +Node5->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALLER_GRAPH.svg new file mode 100644 index 0000000..5bf203a --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALLER_GRAPH.svg @@ -0,0 +1,135 @@ + + + + + + +adb.fastboot.FastbootCommands.Flash + + +Node1 + +adb.fastboot.FastbootCommands. +Flash + + +Node2 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node2->Node3 + + + + +Node3->Node1 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Continue + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Erase + + + + +Node3->Node5 + + + + +Node6 + + +adb.fastboot.FastbootCommands. +Getvar + + + + +Node3->Node6 + + + + +Node7 + + +adb.fastboot.FastbootCommands.Oem + + + + +Node3->Node7 + + + + +Node8 + + +adb.fastboot.FastbootCommands. +Reboot + + + + +Node3->Node8 + + + + +Node9 + + +adb.fastboot.FastbootCommands. +RebootBootloader + + + + +Node3->Node9 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALL_GRAPH.svg new file mode 100644 index 0000000..ac0ed99 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Flash.CALL_GRAPH.svg @@ -0,0 +1,66 @@ + + + + + + +adb.fastboot.FastbootCommands.Flash + + +Node1 + +adb.fastboot.FastbootCommands. +Flash + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node3->Node1 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALLER_GRAPH.svg new file mode 100644 index 0000000..8bad89b --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALLER_GRAPH.svg @@ -0,0 +1,135 @@ + + + + + + +adb.fastboot.FastbootCommands.FlashFromFile + + +Node1 + +adb.fastboot.FastbootCommands. +FlashFromFile + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +Continue + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Erase + + + + +Node2->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node2->Node5 + + + + +Node6 + + +adb.fastboot.FastbootCommands. +Getvar + + + + +Node2->Node6 + + + + +Node7 + + +adb.fastboot.FastbootCommands.Oem + + + + +Node2->Node7 + + + + +Node8 + + +adb.fastboot.FastbootCommands. +Reboot + + + + +Node2->Node8 + + + + +Node9 + + +adb.fastboot.FastbootCommands. +RebootBootloader + + + + +Node2->Node9 + + + + +Node5->Node1 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALL_GRAPH.svg new file mode 100644 index 0000000..90ada28 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.FlashFromFile.CALL_GRAPH.svg @@ -0,0 +1,66 @@ + + + + + + +adb.fastboot.FastbootCommands.FlashFromFile + + +Node1 + +adb.fastboot.FastbootCommands. +FlashFromFile + + +Node2 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node1->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node3->Node4 + + + + +Node4->Node1 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Getvar.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Getvar.CALL_GRAPH.svg new file mode 100644 index 0000000..ddb60bd --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Getvar.CALL_GRAPH.svg @@ -0,0 +1,80 @@ + + + + + + +adb.fastboot.FastbootCommands.Getvar + + +Node1 + +adb.fastboot.FastbootCommands. +Getvar + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node5 + + + + +Node5->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Oem.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Oem.CALL_GRAPH.svg new file mode 100644 index 0000000..e28e6ef --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Oem.CALL_GRAPH.svg @@ -0,0 +1,79 @@ + + + + + + +adb.fastboot.FastbootCommands.Oem + + +Node1 + +adb.fastboot.FastbootCommands.Oem + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node5 + + + + +Node5->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.Reboot.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.Reboot.CALL_GRAPH.svg new file mode 100644 index 0000000..5946045 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.Reboot.CALL_GRAPH.svg @@ -0,0 +1,80 @@ + + + + + + +adb.fastboot.FastbootCommands.Reboot + + +Node1 + +adb.fastboot.FastbootCommands. +Reboot + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node5 + + + + +Node5->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.RebootBootloader.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.RebootBootloader.CALL_GRAPH.svg new file mode 100644 index 0000000..577eb05 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.RebootBootloader.CALL_GRAPH.svg @@ -0,0 +1,80 @@ + + + + + + +adb.fastboot.FastbootCommands.RebootBootloader + + +Node1 + +adb.fastboot.FastbootCommands. +RebootBootloader + + +Node2 + + +adb.fastboot.FastbootCommands. +_SimpleCommand + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node3->Node5 + + + + +Node5->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALLER_GRAPH.svg new file mode 100644 index 0000000..0d73bc2 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALLER_GRAPH.svg @@ -0,0 +1,135 @@ + + + + + + +adb.fastboot.FastbootCommands._SimpleCommand + + +Node1 + +adb.fastboot.FastbootCommands. +_SimpleCommand + + +Node2 + + +adb.fastboot.FastbootCommands. +Continue + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +Erase + + + + +Node1->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node1->Node4 + + + + +Node6 + + +adb.fastboot.FastbootCommands. +Getvar + + + + +Node1->Node6 + + + + +Node7 + + +adb.fastboot.FastbootCommands.Oem + + + + +Node1->Node7 + + + + +Node8 + + +adb.fastboot.FastbootCommands. +Reboot + + + + +Node1->Node8 + + + + +Node9 + + +adb.fastboot.FastbootCommands. +RebootBootloader + + + + +Node1->Node9 + + + + +Node5 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node4->Node5 + + + + +Node5->Node1 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALL_GRAPH.svg new file mode 100644 index 0000000..27755db --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands._SimpleCommand.CALL_GRAPH.svg @@ -0,0 +1,66 @@ + + + + + + +adb.fastboot.FastbootCommands._SimpleCommand + + +Node1 + +adb.fastboot.FastbootCommands. +_SimpleCommand + + +Node2 + + +adb.fastboot.FastbootCommands. +FlashFromFile + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootCommands. +Download + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootCommands. +Flash + + + + +Node2->Node4 + + + + +Node4->Node1 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..e0a2dbb --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.fastboot.FastbootCommands.__init__ + + +Node1 + +adb.fastboot.FastbootCommands. +__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootCommands.__reset.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootCommands.__reset.CALL_GRAPH.svg new file mode 100644 index 0000000..c356d0c --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootCommands.__reset.CALL_GRAPH.svg @@ -0,0 +1,131 @@ + + + + + + +adb.fastboot.FastbootCommands.__reset + + +Node1 + +adb.fastboot.FastbootCommands. +__reset + + +Node2 + + +adb.adb_commands.AdbCommands. +__init__ + + + + +Node1->Node2 + + + + +Node3 + + +adb.adb_protocol.Invalid +CommandError.__init__ + + + + +Node1->Node3 + + + + +Node4 + + +adb.adb_protocol._AdbConnection. +__init__ + + + + +Node1->Node4 + + + + +Node5 + + +adb.adb_protocol.AdbMessage. +__init__ + + + + +Node1->Node5 + + + + +Node6 + + +adb.common.UsbHandle. +__init__ + + + + +Node1->Node6 + + + + +Node7 + + +adb.common.TcpHandle. +__init__ + + + + +Node1->Node7 + + + + +Node8 + + +adb.fastboot.FastbootProtocol. +__init__ + + + + +Node1->Node8 + + + + +Node9 + + +adb.fastboot.FastbootCommands. +__init__ + + + + +Node1->Node9 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootInvalidResponse.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootInvalidResponse.CALL_GRAPH.svg new file mode 100644 index 0000000..deb9605 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootInvalidResponse.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.fastboot.FastbootInvalidResponse + + +Node1 + +adb.fastboot.FastbootInvalid +Response + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.CALL_GRAPH.svg new file mode 100644 index 0000000..d7bb348 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.CALL_GRAPH.svg @@ -0,0 +1,28 @@ + + + + + + +adb.fastboot.FastbootProtocol + + +Node1 + +adb.fastboot.FastbootProtocol + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALLER_GRAPH.svg new file mode 100644 index 0000000..4955d2e --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALLER_GRAPH.svg @@ -0,0 +1,47 @@ + + + + + + +adb.fastboot.FastbootProtocol.HandleDataSending + + +Node1 + +adb.fastboot.FastbootProtocol. +HandleDataSending + + +Node2 + + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +SendCommand + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALL_GRAPH.svg new file mode 100644 index 0000000..664c518 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleDataSending.CALL_GRAPH.svg @@ -0,0 +1,61 @@ + + + + + + +adb.fastboot.FastbootProtocol.HandleDataSending + + +Node1 + +adb.fastboot.FastbootProtocol. +HandleDataSending + + +Node2 + + +adb.fastboot.FastbootProtocol. +_AcceptResponses + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +_Write + + + + +Node1->Node3 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALLER_GRAPH.svg new file mode 100644 index 0000000..43ad3cb --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.fastboot.FastbootProtocol.HandleSimpleResponses + + +Node1 + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + +Node2 + + +adb.fastboot.FastbootProtocol. +SendCommand + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALL_GRAPH.svg new file mode 100644 index 0000000..4d54d73 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.HandleSimpleResponses.CALL_GRAPH.svg @@ -0,0 +1,80 @@ + + + + + + +adb.fastboot.FastbootProtocol.HandleSimpleResponses + + +Node1 + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + +Node2 + + +adb.fastboot.FastbootProtocol. +_AcceptResponses + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +HandleDataSending + + + + +Node1->Node3 + + + + +Node3->Node2 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +_Write + + + + +Node3->Node4 + + + + +Node5 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node4->Node5 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.SendCommand.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.SendCommand.CALL_GRAPH.svg new file mode 100644 index 0000000..ba93cc7 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.SendCommand.CALL_GRAPH.svg @@ -0,0 +1,99 @@ + + + + + + +adb.fastboot.FastbootProtocol.SendCommand + + +Node1 + +adb.fastboot.FastbootProtocol. +SendCommand + + +Node2 + + +adb.fastboot.FastbootProtocol. +_Write + + + + +Node1->Node2 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + + + +Node1->Node4 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node2->Node3 + + + + +Node5 + + +adb.fastboot.FastbootProtocol. +_AcceptResponses + + + + +Node4->Node5 + + + + +Node6 + + +adb.fastboot.FastbootProtocol. +HandleDataSending + + + + +Node4->Node6 + + + + +Node6->Node2 + + + + +Node6->Node5 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol._AcceptResponses.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol._AcceptResponses.CALLER_GRAPH.svg new file mode 100644 index 0000000..cdd28d2 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol._AcceptResponses.CALLER_GRAPH.svg @@ -0,0 +1,66 @@ + + + + + + +adb.fastboot.FastbootProtocol._AcceptResponses + + +Node1 + +adb.fastboot.FastbootProtocol. +_AcceptResponses + + +Node2 + + +adb.fastboot.FastbootProtocol. +HandleDataSending + + + + +Node1->Node2 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + + + +Node1->Node3 + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +SendCommand + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol._HandleProgress.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol._HandleProgress.CALLER_GRAPH.svg new file mode 100644 index 0000000..cf9f984 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol._HandleProgress.CALLER_GRAPH.svg @@ -0,0 +1,132 @@ + + + + + + +adb.fastboot.FastbootProtocol._HandleProgress + + +Node1 + +adb.fastboot.FastbootProtocol. +_HandleProgress + + +Node2 + + +adb.fastboot.FastbootProtocol. +_Write + + + + +Node1->Node2 + + + + +Node6 + + +adb.filesync_protocol.Filesync +Protocol.Pull + + + + +Node1->Node6 + + + + +Node7 + + +adb.filesync_protocol.Filesync +Protocol.Push + + + + +Node1->Node7 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +SendCommand + + + + +Node2->Node3 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +HandleDataSending + + + + +Node2->Node4 + + + + +Node5 + + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + + + +Node4->Node5 + + + + +Node5->Node3 + + + + +Node8 + + +adb.filesync_protocol.Filesync +Protocol._HandleProgress + + + + +Node7->Node8 + + + + +Node8->Node6 + + + + +Node8->Node7 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALLER_GRAPH.svg new file mode 100644 index 0000000..1a0aa10 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALLER_GRAPH.svg @@ -0,0 +1,66 @@ + + + + + + +adb.fastboot.FastbootProtocol._Write + + +Node1 + +adb.fastboot.FastbootProtocol. +_Write + + +Node2 + + +adb.fastboot.FastbootProtocol. +HandleDataSending + + + + +Node1->Node2 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +SendCommand + + + + +Node1->Node4 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +HandleSimpleResponses + + + + +Node2->Node3 + + + + +Node3->Node4 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALL_GRAPH.svg new file mode 100644 index 0000000..6dbc007 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol._Write.CALL_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.fastboot.FastbootProtocol._Write + + +Node1 + +adb.fastboot.FastbootProtocol. +_Write + + +Node2 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootProtocol.__init__.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootProtocol.__init__.CALLER_GRAPH.svg new file mode 100644 index 0000000..264de64 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootProtocol.__init__.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.fastboot.FastbootProtocol.__init__ + + +Node1 + +adb.fastboot.FastbootProtocol. +__init__ + + +Node2 + + +adb.fastboot.FastbootCommands. +__reset + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootRemoteFailure.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootRemoteFailure.CALL_GRAPH.svg new file mode 100644 index 0000000..1207988 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootRemoteFailure.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.fastboot.FastbootRemoteFailure + + +Node1 + +adb.fastboot.FastbootRemote +Failure + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootStateMismatch.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootStateMismatch.CALL_GRAPH.svg new file mode 100644 index 0000000..1d08c22 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootStateMismatch.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.fastboot.FastbootStateMismatch + + +Node1 + +adb.fastboot.FastbootState +Mismatch + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.fastboot.FastbootTransferError.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot.FastbootTransferError.CALL_GRAPH.svg new file mode 100644 index 0000000..17792f9 --- /dev/null +++ b/docs/source/_static/adb.fastboot.FastbootTransferError.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.fastboot.FastbootTransferError + + +Node1 + +adb.fastboot.FastbootTransfer +Error + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.fastboot_debug.Devices.CALLER_GRAPH.svg b/docs/source/_static/adb.fastboot_debug.Devices.CALLER_GRAPH.svg new file mode 100644 index 0000000..eae9f7a --- /dev/null +++ b/docs/source/_static/adb.fastboot_debug.Devices.CALLER_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.fastboot_debug.Devices + + +Node1 + +adb.fastboot_debug.Devices + + +Node2 + + +adb.fastboot_debug.main + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.fastboot_debug.main.CALL_GRAPH.svg b/docs/source/_static/adb.fastboot_debug.main.CALL_GRAPH.svg new file mode 100644 index 0000000..34cf10a --- /dev/null +++ b/docs/source/_static/adb.fastboot_debug.main.CALL_GRAPH.svg @@ -0,0 +1,31 @@ + + + + + + +adb.fastboot_debug.main + + +Node1 + +adb.fastboot_debug.main + + +Node2 + + +adb.fastboot_debug.Devices + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.CALL_GRAPH.svg new file mode 100644 index 0000000..0fcaab7 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection + + +Node1 + +adb.filesync_protocol.File +SyncConnection + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALLER_GRAPH.svg new file mode 100644 index 0000000..9ded3c1 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection.Read + + +Node1 + +adb.filesync_protocol.File +SyncConnection.Read + + +Node2 + + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALL_GRAPH.svg new file mode 100644 index 0000000..fa1630c --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Read.CALL_GRAPH.svg @@ -0,0 +1,47 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection.Read + + +Node1 + +adb.filesync_protocol.File +SyncConnection.Read + + +Node2 + + +adb.filesync_protocol.File +SyncConnection._Flush + + + + +Node1->Node2 + + + + +Node3 + + +adb.filesync_protocol.File +SyncConnection._ReadBuffered + + + + +Node1->Node3 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection.ReadUntil.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.ReadUntil.CALL_GRAPH.svg new file mode 100644 index 0000000..6757958 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.ReadUntil.CALL_GRAPH.svg @@ -0,0 +1,102 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection.ReadUntil + + +Node1 + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + +Node2 + + +adb.adb_protocol.AdbMessage.Read + + + + +Node1->Node2 + + + + +Node5 + + +adb.filesync_protocol.File +SyncConnection.Read + + + + +Node1->Node5 + + + + +Node3 + + +adb.adb_protocol.AdbMessage. +Unpack + + + + +Node2->Node3 + + + + +Node4 + + +adb.adb_protocol.AdbMessage. +CalculateChecksum + + + + +Node2->Node4 + + + + +Node6 + + +adb.filesync_protocol.File +SyncConnection._Flush + + + + +Node5->Node6 + + + + +Node7 + + +adb.filesync_protocol.File +SyncConnection._ReadBuffered + + + + +Node5->Node7 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Send.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Send.CALL_GRAPH.svg new file mode 100644 index 0000000..ebefd03 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection.Send.CALL_GRAPH.svg @@ -0,0 +1,47 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection.Send + + +Node1 + +adb.filesync_protocol.File +SyncConnection.Send + + +Node2 + + +adb.filesync_protocol.File +SyncConnection._CanAddToSendBuffer + + + + +Node1->Node2 + + + + +Node3 + + +adb.filesync_protocol.File +SyncConnection._Flush + + + + +Node1->Node3 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection._CanAddToSendBuffer.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection._CanAddToSendBuffer.CALLER_GRAPH.svg new file mode 100644 index 0000000..1ac46ee --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection._CanAddToSendBuffer.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection._CanAddToSendBuffer + + +Node1 + +adb.filesync_protocol.File +SyncConnection._CanAddToSendBuffer + + +Node2 + + +adb.filesync_protocol.File +SyncConnection.Send + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection._Flush.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection._Flush.CALLER_GRAPH.svg new file mode 100644 index 0000000..db8faa2 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection._Flush.CALLER_GRAPH.svg @@ -0,0 +1,61 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection._Flush + + +Node1 + +adb.filesync_protocol.File +SyncConnection._Flush + + +Node2 + + +adb.filesync_protocol.File +SyncConnection.Read + + + + +Node1->Node2 + + + + +Node4 + + +adb.filesync_protocol.File +SyncConnection.Send + + + + +Node1->Node4 + + + + +Node3 + + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FileSyncConnection._ReadBuffered.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FileSyncConnection._ReadBuffered.CALLER_GRAPH.svg new file mode 100644 index 0000000..eeda0ba --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FileSyncConnection._ReadBuffered.CALLER_GRAPH.svg @@ -0,0 +1,47 @@ + + + + + + +adb.filesync_protocol.FileSyncConnection._ReadBuffered + + +Node1 + +adb.filesync_protocol.File +SyncConnection._ReadBuffered + + +Node2 + + +adb.filesync_protocol.File +SyncConnection.Read + + + + +Node1->Node2 + + + + +Node3 + + +adb.filesync_protocol.File +SyncConnection.ReadUntil + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.CALL_GRAPH.svg new file mode 100644 index 0000000..f8fe785 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol + + +Node1 + +adb.filesync_protocol.Filesync +Protocol + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Pull.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Pull.CALL_GRAPH.svg new file mode 100644 index 0000000..31beb6f --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Pull.CALL_GRAPH.svg @@ -0,0 +1,98 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol.Pull + + +Node1 + +adb.filesync_protocol.Filesync +Protocol.Pull + + +Node2 + + +adb.adb_commands.AdbCommands.Stat + + + + +Node1->Node2 + + + + +Node3 + + +adb.filesync_protocol.Filesync +Protocol.Stat + + + + +Node1->Node3 + + + + +Node4 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node1->Node4 + + + + +Node5 + + +adb.filesync_protocol.Filesync +Protocol._HandleProgress + + + + +Node1->Node5 + + + + +Node6 + + +adb.filesync_protocol.Filesync +Protocol.Push + + + + +Node5->Node6 + + + + +Node6->Node4 + + + + +Node6->Node5 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALLER_GRAPH.svg new file mode 100644 index 0000000..75ef6f7 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALLER_GRAPH.svg @@ -0,0 +1,52 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol.Push + + +Node1 + +adb.filesync_protocol.Filesync +Protocol.Push + + +Node2 + + +adb.filesync_protocol.Filesync +Protocol._HandleProgress + + + + +Node1->Node2 + + + + +Node2->Node1 + + + + +Node3 + + +adb.filesync_protocol.Filesync +Protocol.Pull + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALL_GRAPH.svg new file mode 100644 index 0000000..eccfdb8 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Push.CALL_GRAPH.svg @@ -0,0 +1,52 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol.Push + + +Node1 + +adb.filesync_protocol.Filesync +Protocol.Push + + +Node2 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node1->Node2 + + + + +Node3 + + +adb.filesync_protocol.Filesync +Protocol._HandleProgress + + + + +Node1->Node3 + + + + +Node3->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Stat.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Stat.CALLER_GRAPH.svg new file mode 100644 index 0000000..224a476 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol.Stat.CALLER_GRAPH.svg @@ -0,0 +1,33 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol.Stat + + +Node1 + +adb.filesync_protocol.Filesync +Protocol.Stat + + +Node2 + + +adb.filesync_protocol.Filesync +Protocol.Pull + + + + +Node1->Node2 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALLER_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALLER_GRAPH.svg new file mode 100644 index 0000000..81b75e2 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALLER_GRAPH.svg @@ -0,0 +1,52 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol._HandleProgress + + +Node1 + +adb.filesync_protocol.Filesync +Protocol._HandleProgress + + +Node2 + + +adb.filesync_protocol.Filesync +Protocol.Pull + + + + +Node1->Node2 + + + + +Node3 + + +adb.filesync_protocol.Filesync +Protocol.Push + + + + +Node1->Node3 + + + + +Node3->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALL_GRAPH.svg new file mode 100644 index 0000000..2bed025 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.FilesyncProtocol._HandleProgress.CALL_GRAPH.svg @@ -0,0 +1,52 @@ + + + + + + +adb.filesync_protocol.FilesyncProtocol._HandleProgress + + +Node1 + +adb.filesync_protocol.Filesync +Protocol._HandleProgress + + +Node2 + + +adb.filesync_protocol.Filesync +Protocol.Push + + + + +Node1->Node2 + + + + +Node2->Node1 + + + + +Node3 + + +adb.fastboot.FastbootProtocol. +_HandleProgress + + + + +Node2->Node3 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.InterleavedDataError.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.InterleavedDataError.CALL_GRAPH.svg new file mode 100644 index 0000000..48b49d3 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.InterleavedDataError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.filesync_protocol.InterleavedDataError + + +Node1 + +adb.filesync_protocol.Interleaved +DataError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.InvalidChecksumError.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.InvalidChecksumError.CALL_GRAPH.svg new file mode 100644 index 0000000..bead790 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.InvalidChecksumError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.filesync_protocol.InvalidChecksumError + + +Node1 + +adb.filesync_protocol.Invalid +ChecksumError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.PullFailedError.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.PullFailedError.CALL_GRAPH.svg new file mode 100644 index 0000000..0440412 --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.PullFailedError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.filesync_protocol.PullFailedError + + +Node1 + +adb.filesync_protocol.Pull +FailedError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.filesync_protocol.PushFailedError.CALL_GRAPH.svg b/docs/source/_static/adb.filesync_protocol.PushFailedError.CALL_GRAPH.svg new file mode 100644 index 0000000..62567fb --- /dev/null +++ b/docs/source/_static/adb.filesync_protocol.PushFailedError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.filesync_protocol.PushFailedError + + +Node1 + +adb.filesync_protocol.Push +FailedError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.sign_cryptography.CryptographySigner.CALL_GRAPH.svg b/docs/source/_static/adb.sign_cryptography.CryptographySigner.CALL_GRAPH.svg new file mode 100644 index 0000000..33dd444 --- /dev/null +++ b/docs/source/_static/adb.sign_cryptography.CryptographySigner.CALL_GRAPH.svg @@ -0,0 +1,39 @@ + + + + + + +adb.sign_cryptography.CryptographySigner + + +Node1 + +adb.sign_cryptography.Cryptography +Signer + + +Node2 + +adb.adb_protocol.AuthSigner + + +Node2->Node1 + + + + +Node3 + +object + + +Node3->Node2 + + + + + diff --git a/docs/source/_static/adb.sign_pycryptodome.PycryptodomeAuthSigner.CALL_GRAPH.svg b/docs/source/_static/adb.sign_pycryptodome.PycryptodomeAuthSigner.CALL_GRAPH.svg new file mode 100644 index 0000000..ec42279 --- /dev/null +++ b/docs/source/_static/adb.sign_pycryptodome.PycryptodomeAuthSigner.CALL_GRAPH.svg @@ -0,0 +1,39 @@ + + + + + + +adb.sign_pycryptodome.PycryptodomeAuthSigner + + +Node1 + +adb.sign_pycryptodome.Pycryptodome +AuthSigner + + +Node2 + +adb.adb_protocol.AuthSigner + + +Node2->Node1 + + + + +Node3 + +object + + +Node3->Node2 + + + + + diff --git a/docs/source/_static/adb.sign_pythonrsa.PythonRSASigner.CALL_GRAPH.svg b/docs/source/_static/adb.sign_pythonrsa.PythonRSASigner.CALL_GRAPH.svg new file mode 100644 index 0000000..bb5f8be --- /dev/null +++ b/docs/source/_static/adb.sign_pythonrsa.PythonRSASigner.CALL_GRAPH.svg @@ -0,0 +1,39 @@ + + + + + + +adb.sign_pythonrsa.PythonRSASigner + + +Node1 + +adb.sign_pythonrsa.Python +RSASigner + + +Node2 + +adb.adb_protocol.AuthSigner + + +Node2->Node1 + + + + +Node3 + +object + + +Node3->Node2 + + + + + diff --git a/docs/source/_static/adb.sign_pythonrsa._Accum.CALL_GRAPH.svg b/docs/source/_static/adb.sign_pythonrsa._Accum.CALL_GRAPH.svg new file mode 100644 index 0000000..3dcc80f --- /dev/null +++ b/docs/source/_static/adb.sign_pythonrsa._Accum.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.sign_pythonrsa._Accum + + +Node1 + +adb.sign_pythonrsa. +_Accum + + +Node2 + +object + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.AdbCommandFailureException.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.AdbCommandFailureException.CALL_GRAPH.svg new file mode 100644 index 0000000..04bda64 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.AdbCommandFailureException.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.usb_exceptions.AdbCommandFailureException + + +Node1 + +adb.usb_exceptions.AdbCommand +FailureException + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.AdbOperationException.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.AdbOperationException.CALL_GRAPH.svg new file mode 100644 index 0000000..f5d89d0 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.AdbOperationException.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.usb_exceptions.AdbOperationException + + +Node1 + +adb.usb_exceptions.AdbOperation +Exception + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.CommonUsbError.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.CommonUsbError.CALL_GRAPH.svg new file mode 100644 index 0000000..998e6ce --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.CommonUsbError.CALL_GRAPH.svg @@ -0,0 +1,29 @@ + + + + + + +adb.usb_exceptions.CommonUsbError + + +Node1 + +adb.usb_exceptions.Common +UsbError + + +Node2 + +Exception + + +Node2->Node1 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.DeviceAuthError.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.DeviceAuthError.CALL_GRAPH.svg new file mode 100644 index 0000000..36dd87a --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.DeviceAuthError.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.usb_exceptions.DeviceAuthError + + +Node1 + +adb.usb_exceptions.Device +AuthError + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.DeviceNotFoundError.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.DeviceNotFoundError.CALL_GRAPH.svg new file mode 100644 index 0000000..ded8fc8 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.DeviceNotFoundError.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.usb_exceptions.DeviceNotFoundError + + +Node1 + +adb.usb_exceptions.Device +NotFoundError + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.FormatMessageWithArgumentsException.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.FormatMessageWithArgumentsException.CALL_GRAPH.svg new file mode 100644 index 0000000..d19a6da --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.FormatMessageWithArgumentsException.CALL_GRAPH.svg @@ -0,0 +1,117 @@ + + + + + + +adb.usb_exceptions.FormatMessageWithArgumentsException + + +Node1 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node4 + +adb.fastboot.FastbootInvalid +Response + + +Node1->Node4 + + + + +Node5 + +adb.fastboot.FastbootRemote +Failure + + +Node1->Node5 + + + + +Node6 + +adb.fastboot.FastbootState +Mismatch + + +Node1->Node6 + + + + +Node7 + +adb.fastboot.FastbootTransfer +Error + + +Node1->Node7 + + + + +Node8 + +adb.usb_exceptions.Device +AuthError + + +Node1->Node8 + + + + +Node9 + +adb.usb_exceptions.Device +NotFoundError + + +Node1->Node9 + + + + +Node10 + +adb.usb_exceptions.TcpTimeout +Exception + + +Node1->Node10 + + + + +Node2 + +adb.usb_exceptions.Common +UsbError + + +Node2->Node1 + + + + +Node3 + +Exception + + +Node3->Node2 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.LibusbWrappingError.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.LibusbWrappingError.CALL_GRAPH.svg new file mode 100644 index 0000000..ff38d86 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.LibusbWrappingError.CALL_GRAPH.svg @@ -0,0 +1,62 @@ + + + + + + +adb.usb_exceptions.LibusbWrappingError + + +Node1 + +adb.usb_exceptions.Libusb +WrappingError + + +Node4 + +adb.usb_exceptions.ReadFailed +Error + + +Node1->Node4 + + + + +Node5 + +adb.usb_exceptions.Write +FailedError + + +Node1->Node5 + + + + +Node2 + +adb.usb_exceptions.Common +UsbError + + +Node2->Node1 + + + + +Node3 + +Exception + + +Node3->Node2 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.ReadFailedError.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.ReadFailedError.CALL_GRAPH.svg new file mode 100644 index 0000000..843b695 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.ReadFailedError.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.usb_exceptions.ReadFailedError + + +Node1 + +adb.usb_exceptions.ReadFailed +Error + + +Node2 + +adb.usb_exceptions.Libusb +WrappingError + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.TcpTimeoutException.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.TcpTimeoutException.CALL_GRAPH.svg new file mode 100644 index 0000000..17f75a6 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.TcpTimeoutException.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.usb_exceptions.TcpTimeoutException + + +Node1 + +adb.usb_exceptions.TcpTimeout +Exception + + +Node2 + +adb.usb_exceptions.Format +MessageWithArgumentsException + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/_static/adb.usb_exceptions.WriteFailedError.CALL_GRAPH.svg b/docs/source/_static/adb.usb_exceptions.WriteFailedError.CALL_GRAPH.svg new file mode 100644 index 0000000..6ba6cb3 --- /dev/null +++ b/docs/source/_static/adb.usb_exceptions.WriteFailedError.CALL_GRAPH.svg @@ -0,0 +1,51 @@ + + + + + + +adb.usb_exceptions.WriteFailedError + + +Node1 + +adb.usb_exceptions.Write +FailedError + + +Node2 + +adb.usb_exceptions.Libusb +WrappingError + + +Node2->Node1 + + + + +Node3 + +adb.usb_exceptions.Common +UsbError + + +Node3->Node2 + + + + +Node4 + +Exception + + +Node4->Node3 + + + + + diff --git a/docs/source/adb.adb_commands.rst b/docs/source/adb.adb_commands.rst new file mode 100644 index 0000000..021a69d --- /dev/null +++ b/docs/source/adb.adb_commands.rst @@ -0,0 +1,7 @@ +adb.adb\_commands module +======================== + +.. automodule:: adb.adb_commands + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.adb_debug.rst b/docs/source/adb.adb_debug.rst new file mode 100644 index 0000000..d412a7f --- /dev/null +++ b/docs/source/adb.adb_debug.rst @@ -0,0 +1,7 @@ +adb.adb\_debug module +===================== + +.. automodule:: adb.adb_debug + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.adb_keygen.rst b/docs/source/adb.adb_keygen.rst new file mode 100644 index 0000000..39f422b --- /dev/null +++ b/docs/source/adb.adb_keygen.rst @@ -0,0 +1,7 @@ +adb.adb\_keygen module +====================== + +.. automodule:: adb.adb_keygen + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.adb_protocol.rst b/docs/source/adb.adb_protocol.rst new file mode 100644 index 0000000..9ea9695 --- /dev/null +++ b/docs/source/adb.adb_protocol.rst @@ -0,0 +1,7 @@ +adb.adb\_protocol module +======================== + +.. automodule:: adb.adb_protocol + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.common.rst b/docs/source/adb.common.rst new file mode 100644 index 0000000..19b26bd --- /dev/null +++ b/docs/source/adb.common.rst @@ -0,0 +1,7 @@ +adb.common module +================= + +.. automodule:: adb.common + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.common_cli.rst b/docs/source/adb.common_cli.rst new file mode 100644 index 0000000..1e217c7 --- /dev/null +++ b/docs/source/adb.common_cli.rst @@ -0,0 +1,7 @@ +adb.common\_cli module +====================== + +.. automodule:: adb.common_cli + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.debug.rst b/docs/source/adb.debug.rst new file mode 100644 index 0000000..2ba2f2f --- /dev/null +++ b/docs/source/adb.debug.rst @@ -0,0 +1,7 @@ +adb.debug module +================ + +.. automodule:: adb.debug + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.fastboot.rst b/docs/source/adb.fastboot.rst new file mode 100644 index 0000000..de980b6 --- /dev/null +++ b/docs/source/adb.fastboot.rst @@ -0,0 +1,7 @@ +adb.fastboot module +=================== + +.. automodule:: adb.fastboot + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.fastboot_debug.rst b/docs/source/adb.fastboot_debug.rst new file mode 100644 index 0000000..da21ba5 --- /dev/null +++ b/docs/source/adb.fastboot_debug.rst @@ -0,0 +1,7 @@ +adb.fastboot\_debug module +========================== + +.. automodule:: adb.fastboot_debug + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.filesync_protocol.rst b/docs/source/adb.filesync_protocol.rst new file mode 100644 index 0000000..9fa26fa --- /dev/null +++ b/docs/source/adb.filesync_protocol.rst @@ -0,0 +1,7 @@ +adb.filesync\_protocol module +============================= + +.. automodule:: adb.filesync_protocol + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.rst b/docs/source/adb.rst new file mode 100644 index 0000000..76c8691 --- /dev/null +++ b/docs/source/adb.rst @@ -0,0 +1,30 @@ +adb package +=========== + +Submodules +---------- + +.. toctree:: + + adb.adb_commands + adb.adb_debug + adb.adb_keygen + adb.adb_protocol + adb.common + adb.common_cli + adb.debug + adb.fastboot + adb.fastboot_debug + adb.filesync_protocol + adb.sign_cryptography + adb.sign_pycryptodome + adb.sign_pythonrsa + adb.usb_exceptions + +Module contents +--------------- + +.. automodule:: adb + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.sign_cryptography.rst b/docs/source/adb.sign_cryptography.rst new file mode 100644 index 0000000..c5b7211 --- /dev/null +++ b/docs/source/adb.sign_cryptography.rst @@ -0,0 +1,7 @@ +adb.sign\_cryptography module +============================= + +.. automodule:: adb.sign_cryptography + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.sign_pycryptodome.rst b/docs/source/adb.sign_pycryptodome.rst new file mode 100644 index 0000000..4a33df4 --- /dev/null +++ b/docs/source/adb.sign_pycryptodome.rst @@ -0,0 +1,7 @@ +adb.sign\_pycryptodome module +============================= + +.. automodule:: adb.sign_pycryptodome + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.sign_pythonrsa.rst b/docs/source/adb.sign_pythonrsa.rst new file mode 100644 index 0000000..1f3bf48 --- /dev/null +++ b/docs/source/adb.sign_pythonrsa.rst @@ -0,0 +1,7 @@ +adb.sign\_pythonrsa module +========================== + +.. automodule:: adb.sign_pythonrsa + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/adb.usb_exceptions.rst b/docs/source/adb.usb_exceptions.rst new file mode 100644 index 0000000..addb15a --- /dev/null +++ b/docs/source/adb.usb_exceptions.rst @@ -0,0 +1,7 @@ +adb.usb\_exceptions module +========================== + +.. automodule:: adb.usb_exceptions + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..33a382b --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../..')) + +import sphinx_rtd_theme + + +# -- Project information ----------------------------------------------------- + +project = 'adb' +copyright = '2019, Google' +author = 'Fahrzin Hemmati' + +# The short X.Y version +version = '1.3.0' +# The full version, including alpha/beta/rc tags +release = '1.3.0' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.todo', + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinx.ext.autodoc', + 'sphinx.ext.napoleon' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +autodoc_mock_imports = ['Crypto', 'cryptography', 'libusb1', 'pyasn1', 'usb1'] + +autodoc_default_options = {'members': True, 'undoc-members': True, 'private-members': True, 'show-inheritance': True} + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'adbdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'adb.tex', 'adb Documentation', + 'Fahrzin Hemmati', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'adb', 'adb Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'adb', 'adb Documentation', + author, 'adb', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +def autodoc_skip_member(app, what, name, obj, skip, options): + exclusions = ('_asdict', '_fields', '_make', '_replace', '_source', 'header', 'message') + exclude = name in exclusions + return skip or exclude + +def setup(app): + app.connect('autodoc-skip-member', autodoc_skip_member) diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..eb33752 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,25 @@ +.. ADB documentation master file, created by + sphinx-quickstart on Mon Sep 05 22:06:10 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +adb Documentation +================= + +.. toctree:: + :hidden: + + self + modules.rst + + +.. include:: ../../README.rst + :start-line: 15 + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 0000000..1dedc85 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,7 @@ +adb +=== + +.. toctree:: + :maxdepth: 4 + + adb diff --git a/setup.py b/setup.py index fbcdb81..d782040 100644 --- a/setup.py +++ b/setup.py @@ -65,10 +65,12 @@ rsa_signer_library ], - extra_requires = { + extras_require = { 'fastboot': 'progressbar>=2.3' }, + tests_require = ['cryptography', 'pycryptodome', 'rsa'], + ## classifier list https://pypi.python.org/pypi?:action=list_classifiers classifiers = [ 'Development Status :: 4 - Beta', diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e669d95 --- /dev/null +++ b/test/__init__.py @@ -0,0 +1,4 @@ +import os +import sys + +sys.path.insert(0, os.path.dirname(__file__)) diff --git a/test/adb_keygen_stub.py b/test/adb_keygen_stub.py new file mode 100644 index 0000000..a19fbfa --- /dev/null +++ b/test/adb_keygen_stub.py @@ -0,0 +1,29 @@ +from contextlib import contextmanager +from mock import patch + + +class FileReadWrite(object): + """Mock an opened file that can be read and written to.""" + def __init__(self): + self._content = b'' + + def read(self): + return self._content + + def write(self, content): + self._content = content + + +PRIVATE_KEY = FileReadWrite() +PUBLIC_KEY = FileReadWrite() + + +@contextmanager +def open_priv_pub(infile, mode='r'): + try: + if infile.endswith('.pub'): + yield PUBLIC_KEY + else: + yield PRIVATE_KEY + finally: + pass diff --git a/test/test_adb_protocol.py b/test/test_adb_protocol.py new file mode 100755 index 0000000..0ce1ead --- /dev/null +++ b/test/test_adb_protocol.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python +# Copyright 2014 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests for adb.""" + +from io import BytesIO +import struct +import unittest +from mock import mock + + +from adb import common +from adb import adb_commands +from adb import adb_protocol +from adb.usb_exceptions import TcpTimeoutException, DeviceNotFoundError +import common_stub + + +BANNER = b'blazetest' +LOCAL_ID = 1 +REMOTE_ID = 2 + + +class BaseAdbTest(unittest.TestCase): + + @classmethod + def _ExpectWrite(cls, usb, command, arg0, arg1, data): + usb.ExpectWrite(cls._MakeHeader(command, arg0, arg1, data)) + usb.ExpectWrite(data) + if command == b'WRTE': + cls._ExpectRead(usb, b'OKAY', 0, 0) + + @classmethod + def _ExpectRead(cls, usb, command, arg0, arg1, data=b''): + usb.ExpectRead(cls._MakeHeader(command, arg0, arg1, data)) + if data: + usb.ExpectRead(data) + if command == b'WRTE': + cls._ExpectWrite(usb, b'OKAY', LOCAL_ID, REMOTE_ID, b'') + + @classmethod + def _ConvertCommand(cls, command): + return sum(c << (i * 8) for i, c in enumerate(bytearray(command))) + + @classmethod + def _MakeHeader(cls, command, arg0, arg1, data): + command = cls._ConvertCommand(command) + magic = command ^ 0xFFFFFFFF + checksum = adb_protocol.AdbMessage.CalculateChecksum(data) + return struct.pack(b'<6I', command, arg0, arg1, len(data), checksum, magic) + + @classmethod + def _ExpectConnection(cls, usb): + cls._ExpectWrite(usb, b'CNXN', 0x01000000, 4096, b'host::%s\0' % BANNER) + cls._ExpectRead(usb, b'CNXN', 0, 0, b'device::\0') + + @classmethod + def _ExpectOpen(cls, usb, service): + cls._ExpectWrite(usb, b'OPEN', LOCAL_ID, 0, service) + cls._ExpectRead(usb, b'OKAY', REMOTE_ID, LOCAL_ID) + + @classmethod + def _ExpectClose(cls, usb): + cls._ExpectRead(usb, b'CLSE', REMOTE_ID, 0) + cls._ExpectWrite(usb, b'CLSE', LOCAL_ID, REMOTE_ID, b'') + + @classmethod + def _Connect(cls, usb): + return adb_commands.AdbCommands.Connect(usb, BANNER) + + +class AdbTest(BaseAdbTest): + @classmethod + def _ExpectCommand(cls, service, command, *responses): + usb = common_stub.StubUsb(device=None, setting=None) + cls._ExpectConnection(usb) + cls._ExpectOpen(usb, b'%s:%s\0' % (service, command)) + + for response in responses: + cls._ExpectRead(usb, b'WRTE', REMOTE_ID, 0, response) + cls._ExpectClose(usb) + return usb + + def testConnect(self): + usb = common_stub.StubUsb(device=None, setting=None) + self._ExpectConnection(usb) + + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + + def testConnectSerialString(self): + dev = adb_commands.AdbCommands() + + with mock.patch.object(common.UsbHandle, 'FindAndOpen', return_value=None): + with mock.patch.object(adb_commands.AdbCommands, '_Connect', return_value=None): + dev.ConnectDevice(serial='/dev/invalidHandle') + + def testSmallResponseShell(self): + command = b'keepin it real' + response = 'word.' + usb = self._ExpectCommand(b'shell', command, response) + + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + self.assertEqual(response, dev.Shell(command)) + + def testBigResponseShell(self): + command = b'keepin it real big' + # The data doesn't have to be big, the point is that it just concatenates + # the data from different WRTEs together. + responses = [b'other stuff, ', b'and some words.'] + + usb = self._ExpectCommand(b'shell', command, *responses) + + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + self.assertEqual(b''.join(responses).decode('utf8'), + dev.Shell(command)) + + def testUninstall(self): + package_name = "com.test.package" + response = 'Success' + + usb = self._ExpectCommand(b'shell', ('pm uninstall "%s"' % package_name).encode('utf8'), response) + + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + self.assertEqual(response, dev.Uninstall(package_name)) + + def testStreamingResponseShell(self): + command = b'keepin it real big' + # expect multiple lines + + responses = ['other stuff, ', 'and some words.'] + + usb = self._ExpectCommand(b'shell', command, *responses) + + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + response_count = 0 + for (expected,actual) in zip(responses, dev.StreamingShell(command)): + self.assertEqual(expected, actual) + response_count = response_count + 1 + self.assertEqual(len(responses), response_count) + + def testReboot(self): + usb = self._ExpectCommand(b'reboot', b'', b'') + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.Reboot() + + def testRebootBootloader(self): + usb = self._ExpectCommand(b'reboot', b'bootloader', b'') + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.RebootBootloader() + + def testRemount(self): + usb = self._ExpectCommand(b'remount', b'', b'') + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.Remount() + + def testRoot(self): + usb = self._ExpectCommand(b'root', b'', b'') + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.Root() + + def testEnableVerity(self): + usb = self._ExpectCommand(b'enable-verity', b'', b'') + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.EnableVerity() + + def testDisableVerity(self): + usb = self._ExpectCommand(b'disable-verity', b'', b'') + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.DisableVerity() + +class FilesyncAdbTest(BaseAdbTest): + + @classmethod + def _MakeSyncHeader(cls, command, *int_parts): + command = cls._ConvertCommand(command) + return struct.pack(b'<%dI' % (len(int_parts) + 1), command, *int_parts) + + @classmethod + def _MakeWriteSyncPacket(cls, command, data=b'', size=None): + if not isinstance(data, bytes): + data = data.encode('utf8') + return cls._MakeSyncHeader(command, size or len(data)) + data + + @classmethod + def _ExpectSyncCommand(cls, write_commands, read_commands): + usb = common_stub.StubUsb(device=None, setting=None) + cls._ExpectConnection(usb) + cls._ExpectOpen(usb, b'sync:\0') + + while write_commands or read_commands: + if write_commands: + command = write_commands.pop(0) + cls._ExpectWrite(usb, b'WRTE', LOCAL_ID, REMOTE_ID, command) + + if read_commands: + command = read_commands.pop(0) + cls._ExpectRead(usb, b'WRTE', REMOTE_ID, LOCAL_ID, command) + + cls._ExpectClose(usb) + return usb + + def testPush(self): + filedata = b'alo there, govnah' + mtime = 100 + + send = [ + self._MakeWriteSyncPacket(b'SEND', b'/data,33272'), + self._MakeWriteSyncPacket(b'DATA', filedata), + self._MakeWriteSyncPacket(b'DONE', size=mtime), + ] + data = b'OKAY\0\0\0\0' + usb = self._ExpectSyncCommand([b''.join(send)], [data]) + + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + dev.Push(BytesIO(filedata), '/data', mtime=mtime) + + def testPull(self): + filedata = b"g'ddayta, govnah" + + recv = self._MakeWriteSyncPacket(b'RECV', b'/data') + data = [ + self._MakeWriteSyncPacket(b'DATA', filedata), + self._MakeWriteSyncPacket(b'DONE'), + ] + usb = self._ExpectSyncCommand([recv], [b''.join(data)]) + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=usb, banner=BANNER) + self.assertEqual(filedata, dev.Pull('/data')) + + +class TcpTimeoutAdbTest(BaseAdbTest): + + @classmethod + def _ExpectCommand(cls, service, command, *responses): + tcp = common_stub.StubTcp('10.0.0.123') + cls._ExpectConnection(tcp) + cls._ExpectOpen(tcp, b'%s:%s\0' % (service, command)) + + for response in responses: + cls._ExpectRead(tcp, b'WRTE', REMOTE_ID, 0, response) + cls._ExpectClose(tcp) + return tcp + + def _run_shell(self, cmd, timeout_ms=None): + tcp = self._ExpectCommand(b'shell', cmd) + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=tcp, banner=BANNER) + dev.Shell(cmd, timeout_ms=timeout_ms) + + def testConnect(self): + tcp = common_stub.StubTcp('10.0.0.123') + self._ExpectConnection(tcp) + dev = adb_commands.AdbCommands() + dev.ConnectDevice(handle=tcp, banner=BANNER) + + def testTcpTimeout(self): + timeout_ms = 1 + command = b'i_need_a_timeout' + self.assertRaises( + TcpTimeoutException, + self._run_shell, + command, + timeout_ms=timeout_ms) + + +class TcpHandleTest(unittest.TestCase): + def testInitWithHost(self): + tcp = common_stub.StubTcp('10.11.12.13') + + self.assertEqual('10.11.12.13:5555', tcp._serial_number) + self.assertEqual(None, tcp._timeout_ms) + + def testInitWithHostAndPort(self): + tcp = common_stub.StubTcp('10.11.12.13:5678') + + self.assertEqual('10.11.12.13:5678', tcp._serial_number) + self.assertEqual(None, tcp._timeout_ms) + + def testInitWithTimeout(self): + tcp = common_stub.StubTcp('10.0.0.2', timeout_ms=234.5) + + self.assertEqual('10.0.0.2:5555', tcp._serial_number) + self.assertEqual(234.5, tcp._timeout_ms) + + def testInitWithTimeoutInt(self): + tcp = common_stub.StubTcp('10.0.0.2', timeout_ms=234) + + self.assertEqual('10.0.0.2:5555', tcp._serial_number) + self.assertEqual(234.0, tcp._timeout_ms) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_sign_cryptography.py b/test/test_sign_cryptography.py new file mode 100644 index 0000000..fc0f9c8 --- /dev/null +++ b/test/test_sign_cryptography.py @@ -0,0 +1,29 @@ +from mock import patch +import os +import unittest + +from adb.adb_keygen import keygen +from adb.sign_cryptography import CryptographySigner + +from adb_keygen_stub import open_priv_pub + + +class TestCryptographySigner(unittest.TestCase): + def setUp(self): + with patch('adb.sign_cryptography.open', open_priv_pub), patch('adb.adb_keygen.open', open_priv_pub): + keygen('test/adbkey') + self.signer = CryptographySigner('test/adbkey') + + def test_sign(self): + """Test that the ``Sign`` method does not raise an exception.""" + with self.assertRaises(ValueError): + self.signer.Sign(b'notadb') + self.assertTrue(True) + + def test_get_public_key(self): + """Test that the ``GetPublicKey`` method works correctly.""" + with patch('{}.open'.format(__name__), open_priv_pub): + with open('test/adbkey.pub') as f: + pub = f.read() + + self.assertEqual(pub, self.signer.GetPublicKey()) diff --git a/test/test_sign_pycryptodome.py b/test/test_sign_pycryptodome.py new file mode 100644 index 0000000..2de1509 --- /dev/null +++ b/test/test_sign_pycryptodome.py @@ -0,0 +1,28 @@ +from mock import patch +import os +import unittest + +from adb.adb_keygen import keygen +from adb.sign_pycryptodome import PycryptodomeAuthSigner + +from adb_keygen_stub import open_priv_pub + + +class TestPycryptodomeAuthSigner(unittest.TestCase): + def setUp(self): + with patch('adb.sign_pycryptodome.open', open_priv_pub), patch('adb.adb_keygen.open', open_priv_pub): + keygen('test/adbkey') + self.signer = PycryptodomeAuthSigner('test/adbkey') + + def test_sign(self): + """Test that the ``Sign`` method does not raise an exception.""" + self.signer.Sign(b'notadb') + self.assertTrue(True) + + def test_get_public_key(self): + """Test that the ``GetPublicKey`` method works correctly.""" + with patch('{}.open'.format(__name__), open_priv_pub): + with open('test/adbkey.pub') as f: + pub = f.read() + + self.assertEqual(pub, self.signer.GetPublicKey()) diff --git a/test/test_sign_pythonrsa.py b/test/test_sign_pythonrsa.py new file mode 100644 index 0000000..2137388 --- /dev/null +++ b/test/test_sign_pythonrsa.py @@ -0,0 +1,28 @@ +from mock import patch +import os +import unittest + +from adb.adb_keygen import keygen +from adb.sign_pythonrsa import PythonRSASigner + +from adb_keygen_stub import open_priv_pub + + +class TestPythonRSASigner(unittest.TestCase): + def setUp(self): + with patch('adb.sign_pythonrsa.open', open_priv_pub), patch('adb.adb_keygen.open', open_priv_pub): + keygen('test/adbkey') + self.signer = PythonRSASigner.FromRSAKeyPath('test/adbkey') + + def test_sign(self): + """Test that the ``Sign`` method does not raise an exception.""" + self.signer.Sign(b'notadb') + self.assertTrue(True) + + def test_get_public_key(self): + """Test that the ``GetPublicKey`` method works correctly.""" + with patch('{}.open'.format(__name__), open_priv_pub): + with open('test/adbkey.pub') as f: + pub = f.read() + + self.assertEqual(pub, self.signer.GetPublicKey()) diff --git a/tox.ini b/tox.ini index 0f9881a..9cb1435 100644 --- a/tox.ini +++ b/tox.ini @@ -13,5 +13,8 @@ deps = pytest pytest-cov mock + cryptography + pycryptodome + rsa usedevelop = True commands = py.test --cov adb test