Example #1
0
def ux_clear_keys(no_aborts=False):
    # flush any pending keypresses
    from main import numpad

    try:
        while 1:
            ch = numpad.get_nowait()

            if not no_aborts and ch == numpad.ABORT_KEY:
                raise AbortInteraction

    except QueueEmpty:
        return
Example #2
0
    async def wait(self):
        from main import numpad

        armed = None

        while 1:
            rep_delay = numpad.repeat_delay if not self.num_repeats else 100
            so_far = 0

            while 1:
                try:
                    # Poll for an event
                    ch = numpad.get_nowait()
                    break
                except QueueEmpty:
                    so_far += 5
                    await sleep_ms(5)

                    if self.last_key and numpad.key_pressed == self.last_key:
                        if so_far >= rep_delay:
                            self.num_repeats += 1
                            return self.last_key

                    continue

            if ch == numpad.ABORT_KEY:
                raise AbortInteraction

            self.num_repeats = 0

            if len(ch) > 1:
                # multipress: cancel press/release cycle and be a keyup
                # for other keys.
                armed = None
                continue

            if ch == '':
                self.last_key = None
                if armed:
                    return armed
            elif ch in self.need_release:
                # no key-repeat on these ones
                armed = ch
            else:
                self.last_key = ch
                return ch
Example #3
0
    async def wait(self):
        from main import numpad

        armed = None

        while 1:
            # two values here:
            #  - (ms) time to wait before first key-repeat
            #  - (ms) time between 2nd and Nth repeated events
            #  - these values approved by @nvk
            rep_delay = 200 if not self.num_repeats else 20
            so_far = 0

            while numpad.empty():
                if self.last_key and numpad.key_pressed == self.last_key:
                    if so_far >= rep_delay:
                        self.num_repeats += 1
                        return self.last_key

                await sleep_ms(1)
                so_far += 1

            ch = numpad.get_nowait()

            if ch == numpad.ABORT_KEY:
                raise AbortInteraction

            self.num_repeats = 0

            if len(ch) > 1:
                # multipress: cancel press/release cycle and be a keyup
                # for other keys.
                armed = None
                continue

            if ch == '':
                self.last_key = None
                if armed:
                    return armed
            elif ch in self.need_release:
                # no key-repeat on these ones
                armed = ch
            else:
                self.last_key = ch
                return ch
Example #4
0
def ux_poll_once(expected='x'):
    # non-blocking check if key is pressed
    # - ignore and suppress any key not in expected
    # - responds to key down only
    # - eats any existing key presses
    from main import numpad

    while 1:
        try:
            ch = numpad.key_pressed
            while not ch:
                ch = numpad.get_nowait()

                if ch == numpad.ABORT_KEY:
                    raise AbortInteraction
        except QueueEmpty:
            return None

        for c in ch:
            if c in expected:
                return c
Example #5
0
    async def interact(self):
        import main
        from main import numpad, is_devmode
        from actions import login_now
        from uasyncio import sleep_ms

        # Replace some drawing functions
        orig_fullscreen = main.dis.fullscreen
        orig_progress_bar = main.dis.progress_bar
        orig_progress_bar_show = main.dis.progress_bar_show
        main.dis.fullscreen = self.hack_fullscreen
        main.dis.progress_bar = self.hack_progress_bar
        main.dis.progress_bar_show = self.hack_progress_bar

        # get ready ourselves
        main.dis.set_brightness(0)        # dimest, but still readable
        self.draw_background()

        # Kill time, waiting for user input
        self.digits = ''
        self.test_restart = False
        while not self.test_restart:
            self.show()
            gc.collect()

            try:
                # Poll for an event, no block
                ch = numpad.get_nowait()

                if ch == 'x':
                    self.digits = ''
                elif ch == 'y':
                    if len(self.digits) == LOCAL_PIN_LENGTH:
                        main.hsm_active.local_pin_entered(self.digits)
                        self.digits = ''
                elif ch == numpad.ABORT_KEY:
                    # important to eat these and fully suppress them
                    pass
                elif ch:
                    if len(self.digits) < LOCAL_PIN_LENGTH:
                        # allow only 6 digits
                        self.digits += ch[0]
                    if len(self.digits) == LOCAL_PIN_LENGTH:
                        # send it, even if they didn't press OK yet
                        main.hsm_active.local_pin_entered(self.digits)

                # do immediate screen update
                continue

            except QueueEmpty:
                await sleep_ms(100)
            except BaseException as exc:
                # just in case, keep going
                sys.print_exception(exc)
                continue

            # do the interactions, but don't let user actually press anything
            req = UserAuthorizedAction.active_request
            if req and not req.ux_done:
                try:
                    await req.interact()
                except AbortInteraction:
                    pass

        # This code only reachable on the simulator and modified devices under test,
        # and when the "boot_to_hsm" feature is used and successfully unlock near
        # boottime.
        from actions import goto_top_menu
        main.hsm_active = None
        goto_top_menu()

        # restore normal operation of UX
        from display import Display
        main.dis.fullscreen = orig_fullscreen
        main.dis.progress_bar = orig_progress_bar
        main.dis.progress_bar_show = orig_progress_bar_show

        return