caffeinatedmike

AndroidTV class

Nov 11th, 2018
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.64 KB | None | 0 0
  1. class AndroidTV:
  2.     """ Represents an Android TV device. """
  3.  
  4.     def __init__(self, host, adbkey=None):
  5.         """ Initialize AndroidTV object.
  6.  
  7.        :param host: Host in format <address>:port.
  8.        :param adbkey: The path to the "adbkey" file
  9.        """
  10.         self.host = host
  11.         self.adbkey = adbkey
  12.         self._adb = None
  13.         self.state = STATE_UNKNOWN
  14.         self.muted = False
  15.         self.device = 'hdmi'
  16.         self.volume = 0.
  17.         self.app_id = None
  18.        
  19.         self.package_launcher = None
  20.         self.package_settings = 'android.settings.SETTINGS'
  21.        
  22.         self._adb_error = False
  23.         self._adb_lock = False
  24.         self._exceptions = (TypeError, ValueError, AttributeError,
  25.                             InvalidCommandError, InvalidResponseError,
  26.                             InvalidChecksumError, BrokenPipeError)
  27.  
  28.     async def connect(self):
  29.         """ Connect to an Android TV device.
  30.  
  31.        Will attempt to establish ADB connection to the given host.
  32.        Failure sets state to UNKNOWN and disables sending actions.
  33.        """
  34.         if self.adbkey:
  35.             self._adb = AsyncADBConnection(self.host, self.adbkey)
  36.         else:
  37.             self._adb = AsyncADBConnection(self.host)
  38.         """
  39.        try:
  40.            if self.adbkey:
  41.                signer = Signer(self.adbkey)
  42.  
  43.                # Connect to the device
  44.                self._adb = adb_commands.AdbCommands().ConnectDevice(serial=self.host, rsa_keys=[signer])
  45.            else:
  46.                self._adb = adb_commands.AdbCommands().ConnectDevice(serial=self.host)
  47.                
  48.            if not self.package_launcher:
  49.                await self.home()
  50.                logging.info("Getting Launcher App Package")
  51.                self.package_launcher = await self.current_app
  52.                
  53.        except socket_error as serr:
  54.            logging.warning("Couldn't connect to host: %s, error: %s", self.host, serr.strerror)
  55.        """
  56.  
  57.     async def update(self):
  58.         """ Update the device status. """
  59.         # Check if device is disconnected.
  60.         if not self._adb:
  61.             self.state = STATE_UNKNOWN
  62.             self.app_id = None
  63.         # Check if device is off.
  64.         elif not await self._screen_on:
  65.             self.state = STATE_OFF
  66.             self.app_id = None
  67.         else:
  68.             self.app_id = await self.current_app
  69.            
  70.             if await self._wake_lock:
  71.                 self.state = STATE_PLAYING
  72.             elif self.app_id not in (self.package_launcher, self.package_settings):
  73.                 # Check if state was playing on last update
  74.                 if self.state == STATE_PLAYING:
  75.                     self.state = STATE_PAUSED
  76.                 elif self.state != STATE_PAUSED:
  77.                     self.state = STATE_IDLE
  78.             else:
  79.                 # We're on either the launcher or in settings
  80.                 self.state = STATE_ON
  81.            
  82.             # Get information from the audio status.
  83.             audio_output = await self._dump('audio')
  84.             stream_block = re.findall(BLOCK_REGEX, audio_output,
  85.                                       re.DOTALL | re.MULTILINE)[0]
  86.             self.muted = re.findall(MUTED_REGEX, stream_block,
  87.                                     re.DOTALL | re.MULTILINE)[0] == 'true'
  88.  
  89.     # ======================================================================= #
  90.     #                                                                         #
  91.     #                               properties                                #
  92.     #                                                                         #
  93.     # ======================================================================= #
  94.     @property
  95.     async def current_app(self):
  96.         filtered_dump = await self._dump("window windows", "mCurrentFocus")
  97.         current_focus = filtered_dump.replace("\r", "")
  98.         matches = WINDOW_REGEX.search(current_focus)
  99.         if matches:
  100.             (pkg, activity) = matches.group('package', 'activity')
  101.             return pkg
  102.         else:
  103.             logging.warning("Couldn't get current app, reply was %s", current_focus)
  104.             return None
  105.  
  106.     @property
  107.     async def _screen_on(self):
  108.         """ Check if the screen is on. """
  109.         return await self._dump_has('power', 'Display Power', 'state=ON')
  110.  
  111.     @property
  112.     async def _awake(self):
  113.         """ Check if the device is awake (screen saver is not running). """
  114.         return await self._dump_has('power', 'mWakefulness', 'Awake')
  115.  
  116.     @property
  117.     async def _wake_lock(self):
  118.         """ Check for wake locks (device is playing). """
  119.         return not await self._dump_has('power', 'Locks', 'size=0')
  120.  
  121.     # ======================================================================= #
  122.     #                                                                         #
  123.     #                               ADB methods                               #
  124.     #                                                                         #
  125.     # ======================================================================= #
  126.     @adb_wrapper
  127.     async def _input(self, cmd):
  128.         """ Send input to the device.
  129.  
  130.        :param cmd: Input command.
  131.        """
  132.         if not self._adb:
  133.             return
  134.         self._adb.Shell('input {0}'.format(cmd))
  135.  
  136.     @adb_wrapper
  137.     async def _dump(self, service, grep=None):
  138.         """ Perform a service dump.
  139.  
  140.        :param service: Service to dump.
  141.        :param grep: Grep for this string.
  142.        :returns: Dump, optionally grepped.
  143.        """
  144.         if not self._adb:
  145.             return
  146.         if grep:
  147.             return self._adb.Shell('dumpsys {0} | grep "{1}"'.format(service, grep))
  148.         return self._adb.Shell('dumpsys {0}'.format(service))
  149.  
  150.     async def _dump_has(self, service, grep, search):
  151.         """ Check if a dump has particular content.
  152.  
  153.        :param service: Service to dump.
  154.        :param grep: Grep for this string.
  155.        :param search: Check for this substring.
  156.        :returns: Found or not.
  157.        """
  158.         dump_result = await self._dump(service, grep=grep)
  159.         return dump_result.strip().find(search) > -1
  160.  
  161.     # ======================================================================= #
  162.     #                                                                         #
  163.     #                           turn on/off methods                           #
  164.     #                                                                         #
  165.     # ======================================================================= #
  166.     async def turn_on(self):
  167.         """ Send power action if device is off. """
  168.         if self._adb and not self._screen_on:
  169.             await self._power()
  170.  
  171.     async def turn_off(self):
  172.         """ Send power action if device is not off. """
  173.         if self._adb and self._screen_on:
  174.             await self._power()
  175.  
  176.     # ======================================================================= #
  177.     #                                                                         #
  178.     #                      "key" methods: basic commands                      #
  179.     #                                                                         #
  180.     # ======================================================================= #
  181.     @adb_wrapper
  182.     async def _key(self, key):
  183.         """ Send a key event to device.
  184.  
  185.        :param key: Key constant.
  186.        """
  187.         await self._input('keyevent {0}'.format(key))
  188.  
  189.     async def _power(self):
  190.         """ Send power action. """
  191.         await self._key(POWER)
  192.  
  193.     async def home(self):
  194.         """ Send home action. """
  195.         await self._key(HOME)
  196.  
  197.     async def up(self):
  198.         """ Send up action. """
  199.         await self._key(UP)
  200.  
  201.     async def down(self):
  202.         """ Send down action. """
  203.         await self._key(DOWN)
  204.  
  205.     async def left(self):
  206.         """ Send left action. """
  207.         await self._key(LEFT)
  208.  
  209.     async def right(self):
  210.         """ Send right action. """
  211.         await self._key(RIGHT)
  212.  
  213.     async def enter(self):
  214.         """ Send enter action. """
  215.         await self._key(ENTER)
  216.  
  217.     async def back(self):
  218.         """ Send back action. """
  219.         await self._key(BACK)
  220.  
  221.     async def menu(self):
  222.         """ Send menu action. """
  223.         await self._key(MENU)
  224.  
  225.     async def volume_up(self):
  226.         """ Send volume up action. """
  227.         await self._key(VOLUME_UP)
  228.  
  229.     async def volume_down(self):
  230.         """ Send volume down action. """
  231.         await self._key(VOLUME_DOWN)
  232.  
  233.     async def mute_volume(self):
  234.         """ Mute the volume. """
  235.         await self._key(MUTE)
  236.  
  237.     # ======================================================================= #
  238.     #                                                                         #
  239.     #                      "key" methods: media commands                      #
  240.     #                                                                         #
  241.     # ======================================================================= #
  242.     async def media_play_pause(self):
  243.         """ Send media play/pause action. """
  244.         await self._key(PLAY_PAUSE)
  245.  
  246.     async def media_play(self):
  247.         """ Send media play action. """
  248.         await self._key(PLAY)
  249.  
  250.     async def media_pause(self):
  251.         """ Send media pause action. """
  252.         await self._key(PAUSE)
  253.  
  254.     async def media_stop(self):
  255.         """ Send media stop action. """
  256.         await self._key(STOP)
  257.  
  258.     async def media_next(self):
  259.         """ Send media next action (results in fast-forward). """
  260.         await self._key(NEXT)
  261.  
  262.     async def media_previous(self):
  263.         """ Send media previous action (results in rewind). """
  264.         await self._key(PREVIOUS)
  265.  
  266.     # ======================================================================= #
  267.     #                                                                         #
  268.     #                       "key" methods: key commands                       #
  269.     #                                                                         #
  270.     # ======================================================================= #
  271.     async def space(self):
  272.         """ Send space keypress. """
  273.         await self._key(SPACE)
  274.  
  275.     async def key_0(self):
  276.         """ Send 0 keypress. """
  277.         await self._key(KEY_0)
  278.  
  279.     async def key_1(self):
  280.         """ Send 1 keypress. """
  281.         await self._key(KEY_1)
  282.  
  283.     async def key_2(self):
  284.         """ Send 2 keypress. """
  285.         await self._key(KEY_2)
  286.  
  287.     async def key_3(self):
  288.         """ Send 3 keypress. """
  289.         await self._key(KEY_3)
  290.  
  291.     async def key_4(self):
  292.         """ Send 4 keypress. """
  293.         await self._key(KEY_4)
  294.  
  295.     async def key_5(self):
  296.         """ Send 5 keypress. """
  297.         await self._key(KEY_5)
  298.  
  299.     async def key_6(self):
  300.         """ Send 6 keypress. """
  301.         await self._key(KEY_6)
  302.  
  303.     async def key_7(self):
  304.         """ Send 7 keypress. """
  305.         await self._key(KEY_7)
  306.  
  307.     async def key_8(self):
  308.         """ Send 8 keypress. """
  309.         await self._key(KEY_8)
  310.  
  311.     async def key_9(self):
  312.         """ Send 9 keypress. """
  313.         await self._key(KEY_9)
  314.  
  315.     async def key_a(self):
  316.         """ Send a keypress. """
  317.         await self._key(KEY_A)
  318.  
  319.     async def key_b(self):
  320.         """ Send b keypress. """
  321.         await self._key(KEY_B)
  322.  
  323.     async def key_c(self):
  324.         """ Send c keypress. """
  325.         await self._key(KEY_C)
  326.  
  327.     async def key_d(self):
  328.         """ Send d keypress. """
  329.         await self._key(KEY_D)
  330.  
  331.     async def key_e(self):
  332.         """ Send e keypress. """
  333.         await self._key(KEY_E)
  334.  
  335.     async def key_f(self):
  336.         """ Send f keypress. """
  337.         await self._key(KEY_F)
  338.  
  339.     async def key_g(self):
  340.         """ Send g keypress. """
  341.         await self._key(KEY_G)
  342.  
  343.     async def key_h(self):
  344.         """ Send h keypress. """
  345.         await self._key(KEY_H)
  346.  
  347.     async def key_i(self):
  348.         """ Send i keypress. """
  349.         await self._key(KEY_I)
  350.  
  351.     async def key_j(self):
  352.         """ Send j keypress. """
  353.         await self._key(KEY_J)
  354.  
  355.     async def key_k(self):
  356.         """ Send k keypress. """
  357.         await self._key(KEY_K)
  358.  
  359.     async def key_l(self):
  360.         """ Send l keypress. """
  361.         await self._key(KEY_L)
  362.  
  363.     async def key_m(self):
  364.         """ Send m keypress. """
  365.         await self._key(KEY_M)
  366.  
  367.     async def key_n(self):
  368.         """ Send n keypress. """
  369.         await self._key(KEY_N)
  370.  
  371.     async def key_o(self):
  372.         """ Send o keypress. """
  373.         await self._key(KEY_O)
  374.  
  375.     async def key_p(self):
  376.         """ Send p keypress. """
  377.         await self._key(KEY_P)
  378.  
  379.     async def key_q(self):
  380.         """ Send q keypress. """
  381.         await self._key(KEY_Q)
  382.  
  383.     async def key_r(self):
  384.         """ Send r keypress. """
  385.         await self._key(KEY_R)
  386.  
  387.     async def key_s(self):
  388.         """ Send s keypress. """
  389.         await self._key(KEY_S)
  390.  
  391.     async def key_t(self):
  392.         """ Send t keypress. """
  393.         await self._key(KEY_T)
  394.  
  395.     async def key_u(self):
  396.         """ Send u keypress. """
  397.         await self._key(KEY_U)
  398.  
  399.     async def key_v(self):
  400.         """ Send v keypress. """
  401.         await self._key(KEY_V)
  402.  
  403.     async def key_w(self):
  404.         """ Send w keypress. """
  405.         await self._key(KEY_W)
  406.  
  407.     async def key_x(self):
  408.         """ Send x keypress. """
  409.         await self._key(KEY_X)
  410.  
  411.     async def key_y(self):
  412.         """ Send y keypress. """
  413.         await self._key(KEY_Y)
  414.  
  415.     async def key_z(self):
  416.         """ Send z keypress. """
  417.         await self._key(KEY_Z)
Advertisement
Add Comment
Please, Sign In to add comment