Пример #1
0
    def generate_event_based_on_utg(self):
        """
        generate an event based on current device state
        note: ensure these fields are properly maintained in each transaction:
          last_event_flag, last_touched_view, last_state, exploited_views, state_transitions
        @return: InputEvent
        """
        self.save_state_transition(self.last_event_str, self.last_state,
                                   self.current_state)

        if self.device.is_foreground(self.app):
            # the app is in foreground, clear last_event_flag
            self.last_event_flag = EVENT_FLAG_STARTED
        else:
            number_of_starts = self.last_event_flag.count(EVENT_FLAG_START_APP)
            # If we have tried too many times but the app is still not started, stop DroidBot
            if number_of_starts > MAX_NUM_RESTARTS:
                raise InputInterruptedException("The app cannot be started.")

            # if app is not started, try start it
            if self.last_event_flag.endswith(EVENT_FLAG_START_APP):
                # It seems the app stuck at some state, and cannot be started
                # just pass to let viewclient deal with this case
                self.logger.info("The app had been restarted %d times.",
                                 number_of_starts)
                self.logger.info("Trying to restart app...")
                pass
            else:
                start_app_intent = self.app.get_start_intent()

                self.last_event_flag += EVENT_FLAG_START_APP
                self.last_event_str = EVENT_FLAG_START_APP
                return IntentEvent(start_app_intent)

        # select a view to click
        view_to_touch = self.select_a_view(self.current_state)

        # if no view can be selected, restart the app
        if view_to_touch is None:
            stop_app_intent = self.app.get_stop_intent()
            self.last_event_flag += EVENT_FLAG_STOP_APP
            self.last_event_str = EVENT_FLAG_STOP_APP
            return IntentEvent(stop_app_intent)

        view_to_touch_str = view_to_touch['view_str']
        if view_to_touch_str.startswith('BACK'):
            result = KeyEvent('BACK')
        else:
            result = TouchEvent(view=view_to_touch)

        self.last_event_flag += EVENT_FLAG_TOUCH
        self.last_event_str = view_to_touch_str
        self.save_explored_view(self.current_state, self.last_event_str)
        return result
Пример #2
0
 def start(self, input_manager):
     """
     start producing events
     :param input_manager: instance of InputManager
     """
     count = 0
     while input_manager.enabled and count < input_manager.event_count:
         try:
             # make sure the first event is go to HOME screen
             # the second event is to start the app
             if count == 0:
                 event = KeyEvent(name="HOME")
             elif count == 1:
                 event = IntentEvent(self.app.get_start_intent())
             else:
                 event = self.generate_event()
             input_manager.add_event(event)
         except KeyboardInterrupt:
             break
         except InputInterruptedException as e:
             self.logger.warning("stop sending events: %s" % e)
             break
         # except RuntimeError as e:
         #     self.logger.warning(e.message)
         #     break
         except Exception as e:
             self.logger.warning("exception during sending events: %s" % e)
             import traceback
             traceback.print_exc()
             continue
         count += 1
Пример #3
0
 def generate_event_based_on_utg(self):
     """
     generate an event based on current UTG
     @return: InputEvent
     """
     if self.__first_event:
         self.__first_event = False
         self.logger.info("Trying to start the app...")
         start_app_intent = self.app.get_start_intent()
         return IntentEvent(intent=start_app_intent)
     else:
         return ManualEvent()
Пример #4
0
    def generate_event_based_on_utg(self):
        """
        generate an event based on current UTG
        @return: InputEvent
        """
        current_state = self.current_state
        if current_state.state_str in self.__missed_states:
            self.__missed_states.remove(current_state.state_str)

        if current_state.get_app_activity_depth(self.app) < 0:
            # If the app is not in the activity stack
            start_app_intent = self.app.get_start_intent()

            if self.__event_trace.endswith(EVENT_FLAG_START_APP + EVENT_FLAG_STOP_APP) \
                    or self.__event_trace.endswith(EVENT_FLAG_START_APP):
                self.__num_restarts += 1
            else:
                self.__num_restarts = 0

            if self.__num_restarts > MAX_NUM_RESTARTS:
                # If the app had been restarted too many times, abort
                msg = "The app had been restarted too many times."
                self.logger.info(msg)
                raise InputInterruptedException(msg)
            else:
                # Start the app
                self.__event_trace += EVENT_FLAG_START_APP
                self.logger.info("Trying to start the app...")
                return IntentEvent(intent=start_app_intent)

        elif current_state.get_app_activity_depth(self.app) > 0:
            # If the app is in activity stack but is not in foreground
            self.__num_steps_outside += 1

            if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE:
                # If the app has not been in foreground for too long, try to go back
                go_back_event = KeyEvent(name="BACK")
                self.__event_trace += EVENT_FLAG_NAVIGATE
                self.logger.info("Going back to the app...")
                return go_back_event
        else:
            # If the app is in foreground
            self.__num_steps_outside = 0

        # Get all possible input events
        possible_events = current_state.get_possible_input()

        if self.random_input:
            random.shuffle(possible_events)

        # If there is an unexplored event, try the event first
        for input_event in possible_events:
            if not self.utg.is_event_explored(event=input_event,
                                              state=current_state):
                self.logger.info("Trying a unexplored event.")
                self.__event_trace += EVENT_FLAG_EXPLORE
                return input_event

        target_state = self.__get_nav_target(current_state)
        if target_state:
            event_path = self.utg.get_event_path(current_state=current_state,
                                                 target_state=target_state)
            if event_path and len(event_path) > 0:
                self.logger.info("Navigating to %s, %d steps left." %
                                 (target_state.state_str, len(event_path)))
                self.__event_trace += EVENT_FLAG_NAVIGATE
                return event_path[0]

        # If couldn't find a exploration target, stop the app
        stop_app_intent = self.app.get_stop_intent()
        self.logger.info(
            "Cannot find an exploration target. Trying to restart app...")
        self.__event_trace += EVENT_FLAG_STOP_APP
        return IntentEvent(intent=stop_app_intent)
Пример #5
0
    def generate_event_based_on_utg(self):
        """
        generate an event based on current UTG
        @return: InputEvent
        """
        #self.logger.info("Generating events in gym state: ")
        current_state = self.device.get_current_state() #self.current_state
        self.current_state = current_state
        self.logger.info("Current state: %s" % current_state.state_str)
        if current_state.state_str in self.__missed_states:
            self.__missed_states.remove(current_state.state_str)

        if current_state.get_app_activity_depth(self.app) < 0:
            # If the app is not in the activity stack
            start_app_intent = self.app.get_start_intent()

            # It seems the app stucks at some state, has been
            # 1) force stopped (START, STOP)
            #    just start the app again by increasing self.__num_restarts
            # 2) started at least once and cannot be started (START)
            #    pass to let viewclient deal with this case
            # 3) nothing
            #    a normal start. clear self.__num_restarts.

            if self.__event_trace.endswith(EVENT_FLAG_START_APP + EVENT_FLAG_STOP_APP) \
                    or self.__event_trace.endswith(EVENT_FLAG_START_APP):
                self.__num_restarts += 1
                self.logger.info("The app had been restarted %d times.", self.__num_restarts)
            else:
                self.__num_restarts = 0

            # pass (START) through
            if not self.__event_trace.endswith(EVENT_FLAG_START_APP):
                if self.__num_restarts > MAX_NUM_RESTARTS:
                    # If the app had been restarted too many times, enter random mode
                    msg = "The app had been restarted too many times. Entering random mode."
                    self.logger.info(msg)
                    self.__random_explore = True
                else:
                    # Start the app
                    self.__event_trace += EVENT_FLAG_START_APP
                    self.logger.info("Trying to start the app...")
                    return IntentEvent(intent=start_app_intent)

        elif current_state.get_app_activity_depth(self.app) > 0:
            # If the app is in activity stack but is not in foreground
            self.__num_steps_outside += 1

            if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE:
                # If the app has not been in foreground for too long, try to go back
                if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE_KILL:
                    stop_app_intent = self.app.get_stop_intent()
                    go_back_event = IntentEvent(stop_app_intent)
                else:
                    go_back_event = KeyEvent(name="BACK")
                self.__event_trace += EVENT_FLAG_NAVIGATE
                self.logger.info("Going back to the app...")
                return go_back_event
        else:
            # If the app is in foreground
            self.__num_steps_outside = 0

        # Get all possible input events
        possible_events = current_state.get_possible_input()

        if self.random_input:
            random.shuffle(possible_events)

        if self.search_method == POLICY_GREEDY_DFS:
            possible_events.append(KeyEvent(name="BACK"))
        elif self.search_method == POLICY_GREEDY_BFS:
            possible_events.insert(0, KeyEvent(name="BACK"))

        # get humanoid result, use the result to sort possible events
        # including back events
        if self.device.humanoid is not None:
            possible_events = self.__sort_inputs_by_humanoid(possible_events)

        # If there is an unexplored event, try the event first
        for input_event in possible_events:
            if not self.utg.is_event_explored(event=input_event, state=current_state):
                self.logger.info("Trying an unexplored event.")
                self.__event_trace += EVENT_FLAG_EXPLORE
                return input_event

        target_state = self.__get_nav_target(current_state)
        if target_state:
            event_path = self.utg.get_event_path(current_state=current_state, target_state=target_state)
            if event_path and len(event_path) > 0:
                self.logger.info("Navigating to %s, %d steps left." % (target_state.state_str, len(event_path)))
                self.__event_trace += EVENT_FLAG_NAVIGATE
                return event_path[0]

        if self.__random_explore:
            self.logger.info("Trying random event.")
            random.shuffle(possible_events)
            return possible_events[0]

        # If couldn't find a exploration target, stop the app
        stop_app_intent = self.app.get_stop_intent()
        self.logger.info("Cannot find an exploration target. Trying to restart app...")
        self.__event_trace += EVENT_FLAG_STOP_APP
        return IntentEvent(intent=stop_app_intent)
Пример #6
0
 def reset_start(self):
     start_app_intent = self.app.get_start_intent()
     #self.logger.info("Entering reset_start. Trying to restart app...")
     self.__event_trace += EVENT_FLAG_START_APP
     #self.logger.info(start_app_intent)
     return IntentEvent(intent=start_app_intent)
Пример #7
0
 def reset_stop(self):
     stop_app_intent = self.app.get_stop_intent()
     #self.logger.info("Entering reset_stop. Trying to restart app...")
     self.__event_trace += EVENT_FLAG_STOP_APP
     return IntentEvent(intent=stop_app_intent)
Пример #8
0
    def check_gym_event(self, event, event_trace_str = "+NA"):
        #self.logger.info("checking gym event from env.step")
        current_state = self.device.get_current_state()
        self.current_state = current_state
        #self.logger.info("Current state: %s" % current_state.state_str)
        if current_state.state_str in self.__missed_states:
            self.__missed_states.remove(current_state.state_str)

        if current_state.get_app_activity_depth(self.app) < 0:
            # If the app is not in the activity stack
            start_app_intent = self.app.get_start_intent()

            # It seems the app stucks at some state, has been
            # 1) force stopped (START, STOP)
            #    just start the app again by increasing self.__num_restarts
            # 2) started at least once and cannot be started (START)
            #    pass to let viewclient deal with this case
            # 3) nothing
            #    a normal start. clear self.__num_restarts.

            if self.__event_trace.endswith(EVENT_FLAG_START_APP + EVENT_FLAG_STOP_APP) \
                    or self.__event_trace.endswith(EVENT_FLAG_START_APP):
                self.__num_restarts += 1
                self.logger.info("The app had been restarted %d times.", self.__num_restarts)
            else:
                self.__num_restarts = 0

            # pass (START) through
            if not self.__event_trace.endswith(EVENT_FLAG_START_APP):
                if self.__num_restarts > MAX_NUM_RESTARTS:
                    # If the app had been restarted too many times, enter random mode
                    msg = "The app had been restarted too many times. Enabling random mode."
                    self.logger.info(msg)
                    self.__random_explore = True
                else:
                    # Start the app
                    self.__event_trace += EVENT_FLAG_START_APP
                    self.logger.info("Trying to start the app...")
                    return IntentEvent(intent=start_app_intent)

        elif current_state.get_app_activity_depth(self.app) > 0:
            # If the app is in activity stack but is not in foreground
            self.__num_steps_outside += 1

            if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE:
                # If the app has not been in foreground for too long, try to go back
                if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE_KILL:
                    stop_app_intent = self.app.get_stop_intent()
                    go_back_event = IntentEvent(stop_app_intent)
                else:
                    go_back_event = KeyEvent(name="BACK")
                self.__event_trace += EVENT_FLAG_NAVIGATE
                self.logger.info("Going back to the app...")
                return go_back_event
        else:
            # If the app is in foreground
            self.__num_steps_outside = 0

        #self.logger.info("Passed initial steps, returning the event for input manager")
        self.__event_trace += event_trace_str

        #update the utg
        #self.current_state = self.device.get_current_state() #updated up above
        self.__update_utg()
        self.last_state = self.current_state
        self.last_event = event

        return event
Пример #9
0
    def generate_event_based_on_utg(self):
        """
        generate an event based on current UTG
        @return: InputEvent
        """
        current_state = self.current_state
        if current_state.state_str in self.__missed_states:
            self.__missed_states.remove(current_state.state_str)

        if current_state.get_app_activity_depth(self.app) < 0:
            # If the app is not in the activity stack
            start_app_intent = self.app.get_start_intent()

            if self.__event_trace.endswith(EVENT_FLAG_START_APP + EVENT_FLAG_STOP_APP) \
                    or self.__event_trace.endswith(EVENT_FLAG_START_APP):
                self.__num_restarts += 1
            else:
                self.__num_restarts = 0

            if self.__num_restarts > MAX_NUM_RESTARTS:
                # If the app had been restarted too many times, abort
                msg = "The app had been restarted too many times."
                self.logger.info(msg)
                raise InputInterruptedException(msg)
            else:
                # Start the app
                self.__event_trace += EVENT_FLAG_START_APP
                self.logger.info("Trying to start the app...")
                return IntentEvent(intent=start_app_intent)

        elif current_state.get_app_activity_depth(self.app) > 0:
            # If the app is in activity stack but is not in foreground
            self.__num_steps_outside += 1

            if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE:
                # If the app has not been in foreground for too long, try to go back
                go_back_event = KeyEvent(name="BACK")
                self.__event_trace += EVENT_FLAG_NAVIGATE
                self.logger.info("Going back to the app...")
                return go_back_event
        else:
            # If the app is in foreground
            self.__num_steps_outside = 0

        curr_screenshot = current_state.device.take_screenshot()
        new_screenshot = str(curr_screenshot).replace("/temp/", "/all_screenshots/")

        directory = os.path.dirname(new_screenshot)

        if not os.path.exists(directory):
            os.mkdir(directory)

        move(curr_screenshot, new_screenshot)

        # Get all possible input events
        all_views = current_state.views
        actionable_views = filter(lambda x : x["enabled"] and x["visible"] and
                                             (x["clickable"] or x["scrollable"] or x["checkable"] or x["long_clickable"]),
                                  all_views)

        items = []
        for view in actionable_views:
            data = {"class": view["class"]}

            if view["parent"] >= 0:
                data["parent"] = all_views[view["parent"]]["class"]
            else:
                data["parent"] = "none"

            if len(view["children"]) > 1:
                data["children2"] = all_views[view["children"][1]]["class"]
            else:
                data["children2"] = "none"

            if len(view["children"]) > 0:
                data["children1"] = all_views[view["children"][0]]["class"]
            else:
                data["children1"] = "none"

            items.append(data)

        predictions = ModelBased.classify(items)
        selected_idx = ModelBased.select(predictions)

        possible_events = current_state.get_possible_input()

        if len(possible_events) > 0:
            # If it was not possible to classify fall back to purely random strategy
            if selected_idx >= 0:
                selected_widget = actionable_views[selected_idx]
                chance = random.random()

                tmp_events = [x
                              for x in possible_events
                              if ((not isinstance(x, UIEvent)) and (chance < 0.2)) or
                                 (isinstance(x, UIEvent) and UtgRandomWidgetPolicy.are_equal(x.view, selected_widget))]

                if len(tmp_events) > 0:
                    possible_events = tmp_events

            random.shuffle(possible_events)
            self.logger.info("Trying a random event.")
            self.__event_trace += EVENT_FLAG_EXPLORE
            input_event = possible_events[0]
            return input_event

        # If couldn't find a exploration target, stop the app
        stop_app_intent = self.app.get_stop_intent()
        self.logger.info("Cannot find an exploration target. Trying to restart app...")
        self.__event_trace += EVENT_FLAG_STOP_APP
        return IntentEvent(intent=stop_app_intent)
Пример #10
0
    def start(self, input_manager):
        """
        start producing events
        :param input_manager: instance of InputManager
        """
        count = 0
        network_monitoring = False
        while input_manager.enabled and count < input_manager.event_count:
            try:
                # make sure the first event is go to HOME screen
                # the second event is to start the app

                if count == 0 and self.master is None:
                    event = KeyEvent(name="HOME")
                elif count == 1 and self.master is None:
                    event = IntentEvent(self.app.get_start_intent())
                else:
                    event = self.generate_event()

                if network_monitoring == True and hasattr(event,"intent"):
                    process_strace.terminate()
                    network_monitoring = False

                input_manager.add_event(event)
                if hasattr(event,"intent"):
                    current_processes = self.device.adb.shell("ps").split("\r\n")
                    import re
                    for currentProcess in current_processes:
                        if currentProcess.find(self.app.package_name) != -1:
                            pattern_result = re.search(r"\s\d+\s", currentProcess)
                            pid = pattern_result.group(0)
                            break

                    from subprocess import Popen, PIPE
                    network_monitoring=True
                    process_strace = Popen(['adb' , 'shell'] , stdin=PIPE)
                    process_strace.stdin.write('su\n')
                    process_strace.stdin.flush()
                    if count==1:
                         monitor_command = "strace -f -e trace=network -s 10000 -p " + pid + " &> /mnt/user/0/primary/networkResults"
                    else:
                        monitor_command = "strace -f -e trace=network -s 10000 -p " + pid + " &>> /mnt/user/0/primary/networkResults"
                    process_strace.stdin.write(monitor_command+'\n')
                    process_strace.stdin.flush()





            except KeyboardInterrupt:
                break
            except InputInterruptedException as e:
                self.logger.warning("stop sending events: %s" % e)
                break
            # except RuntimeError as e:
            #     self.logger.warning(e.message)
            #     break
            except Exception as e:
                self.logger.warning("exception during sending events: %s" % e)
                import traceback
                traceback.print_exc()
                continue
            count += 1

        process_strace.terminate()
        process_grep = Popen(['adb', 'shell'], stdout=PIPE, stdin=PIPE)
        process_grep.stdin.write('su\n')
        process_grep.stdin.flush()
        process_grep.stdin.write('grep -a HTTP/ /mnt/user/0/primary/networkResults' + '\n')
        process_grep.stdin.flush()
        stdout_string, stderr_string = process_grep.communicate()
        process_grep.terminate()
        import os

        network_file = open(os.path.join(self.device.output_dir, "HTTPLines.txt"), 'w')
        network_file.write(stdout_string)  # python will convert \n to os.linesep
        network_file.close()  # you can omit in most cases as the destructor will call it
    def generate_event_based_on_utg(self):
        """
        generate an event based on current UTG
        @return: InputEvent
        """
        current_state = self.current_state
        self.logger.info("Current state: %s" % current_state.state_str)
        if current_state.state_str in self.__missed_states:
            self.__missed_states.remove(current_state.state_str)

        if current_state.get_app_activity_depth(self.app) < 0:
            # If the app is not in the activity stack
            start_app_intent = self.app.get_start_intent()

            # It seems the app stucks at some state, has been
            # 1) force stopped (START, STOP)
            #    just start the app again by increasing self.__num_restarts
            # 2) started at least once and cannot be started (START)
            #    pass to let viewclient deal with this case
            # 3) nothing
            #    a normal start. clear self.__num_restarts.

            if self.__event_trace.endswith(EVENT_FLAG_START_APP + EVENT_FLAG_STOP_APP) \
                    or self.__event_trace.endswith(EVENT_FLAG_START_APP):
                self.__num_restarts += 1
                self.logger.info("The app had been restarted %d times.",
                                 self.__num_restarts)
            else:
                self.__num_restarts = 0

            # pass (START) through
            if not self.__event_trace.endswith(EVENT_FLAG_START_APP):
                if self.__num_restarts > MAX_NUM_RESTARTS:
                    # If the app had been restarted too many times, enter random mode
                    msg = "The app had been restarted too many times. Entering random mode."
                    self.logger.info(msg)
                    self.__random_explore = True
                else:
                    # Start the app
                    self.__event_trace += EVENT_FLAG_START_APP
                    self.logger.info("Trying to start the app...")
                    return IntentEvent(intent=start_app_intent)

        elif current_state.get_app_activity_depth(self.app) > 0:
            # If the app is in activity stack but is not in foreground
            self.__num_steps_outside += 1

            if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE:
                # If the app has not been in foreground for too long, try to go back
                if self.__num_steps_outside > MAX_NUM_STEPS_OUTSIDE_KILL:
                    stop_app_intent = self.app.get_stop_intent()
                    go_back_event = IntentEvent(stop_app_intent)
                else:
                    go_back_event = KeyEvent(name="BACK")
                self.__event_trace += EVENT_FLAG_NAVIGATE
                self.logger.info("Going back to the app...")
                return go_back_event
        else:
            # If the app is in foreground
            self.__num_steps_outside = 0

        # Get all possible input events
        possible_events = current_state.get_possible_input()

        count = 0
        for activity in self.edit_text_value:
            count = count + len(self.edit_text_value[activity])

        print("Possible events: " + str(len(possible_events)))
        print("Editable Text Events: " + str(count))
        """
        for activity in self.edit_text_value:
            string = activity + ": "
            for resource_id in self.edit_text_value[activity]:
                string = string + resource_id + " = " + str(self.edit_text_value[activity][resource_id].text) + ", "
            print(string)
        """

        variation = False
        activity_variation = list()
        event_added = list()

        for event in possible_events:
            if isinstance(event, SetTextEvent):
                activity = event.view["activity"]
                resource_id = event.view["resource_id"]
                if activity not in self.edit_text_value or resource_id not in self.edit_text_value[
                        activity]:
                    if activity not in self.edit_text_value:
                        self.edit_text_value[activity] = dict()
                    self.edit_text_value[activity][resource_id] = event
                    event_added.append(event)
                    variation = True
                    if activity not in activity_variation:
                        activity_variation.append(activity)

        if variation:
            for activity in activity_variation:
                event_list = list(self.edit_text_value[activity].values())
                view_text_association = ViewTextAssociation(event_list)
                complete_event_list = view_text_association.GetSetTextEvents()
                for new_event in event_added:
                    for event in complete_event_list:
                        activity = event.view["activity"]
                        resource_id = event.view["resource_id"]
                        if new_event.view["resource_id"] == event.view[
                                "resource_id"]:
                            self.edit_text_value[activity][resource_id] = event

        if self.random_input:
            random.shuffle(possible_events)

        if self.search_method == POLICY_GREEDY_DFS:
            possible_events.append(KeyEvent(name="BACK"))
        elif self.search_method == POLICY_GREEDY_BFS:
            possible_events.insert(0, KeyEvent(name="BACK"))

        # get humanoid result, use the result to sort possible events
        # including back events
        if self.device.humanoid is not None:
            possible_events = self.__sort_inputs_by_humanoid(possible_events)

        new_input_event = None
        if self.last_event is not None and self.last_event.event_type == 'touch' and \
                self.last_event.view['class'] == 'android.widget.EditText':
            resource_id = self.last_event.view['resource_id']
            for input_event in possible_events:
                if isinstance(input_event, SetTextEvent) and \
                        input_event.view['resource_id'] == resource_id:
                    new_input_event = input_event
                    break

        last_event_edit = False
        if self.last_event is not None and self.last_event.event_type == 'set_text' and \
                self.last_event.view['class'] == 'android.widget.EditText':
            resource_id = self.last_event.view['resource_id']
            last_event_edit = True

        # If there is an unexplored event, try the event first
        for input_event in possible_events:
            if new_input_event is not None:
                input_event = new_input_event
            """
            elif last_event_edit:
                if input_event.view['resource_id'] == resource_id:
                    continue
            """
            if not self.utg.is_event_explored(event=input_event,
                                              state=current_state):
                self.logger.info("Trying an unexplored event.")
                self.__event_trace += EVENT_FLAG_EXPLORE
                if isinstance(input_event, SetTextEvent):
                    resource_id = input_event.view["resource_id"]
                    activity = input_event.view["activity"]
                    for event_resource_id in self.edit_text_value[activity]:
                        if resource_id == event_resource_id:
                            input_event.text = self.edit_text_value[activity][
                                event_resource_id].text
                print(input_event)
                return input_event

        target_state = self.__get_nav_target(current_state)
        if target_state:
            event_path = self.utg.get_event_path(current_state=current_state,
                                                 target_state=target_state)
            if event_path and len(event_path) > 0:
                self.logger.info("Navigating to %s, %d steps left." %
                                 (target_state.state_str, len(event_path)))
                self.__event_trace += EVENT_FLAG_NAVIGATE
                return event_path[0]

        if self.__random_explore:
            self.logger.info("Trying random event.")
            random.shuffle(possible_events)
            return possible_events[0]

        # If couldn't find a exploration target, stop the app
        stop_app_intent = self.app.get_stop_intent()
        self.logger.info(
            "Cannot find an exploration target. Trying to restart app...")
        self.__event_trace += EVENT_FLAG_STOP_APP
        return IntentEvent(intent=stop_app_intent)