def get_possible_input(self): """ Get a list of possible input events for this state :return: """ possible_events = [] enabled_view_ids = set() touch_exclude_view_ids = set() for view_dict in self.views: if self.__safe_dict_get(view_dict, 'enabled'): enabled_view_ids.add(view_dict['temp_id']) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'clickable'): possible_events.append(TouchEvent(view=self.views[view_id])) touch_exclude_view_ids.add(view_id) touch_exclude_view_ids.union( self.get_all_children(self.views[view_id])) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'scrollable'): possible_events.append( ScrollEvent(view=self.views[view_id], direction="UP")) possible_events.append( ScrollEvent(view=self.views[view_id], direction="DOWN")) possible_events.append( ScrollEvent(view=self.views[view_id], direction="LEFT")) possible_events.append( ScrollEvent(view=self.views[view_id], direction="RIGHT")) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'checkable'): possible_events.append(TouchEvent(view=self.views[view_id])) touch_exclude_view_ids.add(view_id) touch_exclude_view_ids.union( self.get_all_children(self.views[view_id])) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'long_clickable'): possible_events.append( LongTouchEvent(view=self.views[view_id])) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'editable'): touch_exclude_view_ids.add(view_id) # TODO figure out what event can be sent to editable views pass for view_id in enabled_view_ids: if view_id in touch_exclude_view_ids: continue children = self.__safe_dict_get(self.views[view_id], 'children') if children and len(children) > 0: continue possible_events.append(TouchEvent(view=self.views[view_id])) return possible_events
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
def get_possible_input(self): """ Get a list of possible input events for this state :return: list of InputEvent """ if self.possible_events: return [] + self.possible_events possible_events = [] enabled_view_ids = [] touch_exclude_view_ids = set() for view_dict in self.views: # exclude navigation bar if exists if self.__safe_dict_get(view_dict, 'enabled') and \ self.__safe_dict_get(view_dict, 'resource_id') not in \ ['android:id/navigationBarBackground', 'android:id/statusBarBackground']: enabled_view_ids.append(view_dict['temp_id']) enabled_view_ids.reverse() for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'clickable'): possible_events.append(TouchEvent(view=self.views[view_id])) touch_exclude_view_ids.add(view_id) touch_exclude_view_ids.union( self.get_all_children(self.views[view_id])) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'scrollable'): possible_events.append( ScrollEvent(view=self.views[view_id], direction="UP")) possible_events.append( ScrollEvent(view=self.views[view_id], direction="DOWN")) possible_events.append( ScrollEvent(view=self.views[view_id], direction="LEFT")) possible_events.append( ScrollEvent(view=self.views[view_id], direction="RIGHT")) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'checkable') and not self.__safe_dict_get( self.views[view_id], 'clickable'): possible_events.append(TouchEvent(view=self.views[view_id])) touch_exclude_view_ids.add(view_id) touch_exclude_view_ids.union( self.get_all_children(self.views[view_id])) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'long_clickable'): possible_events.append( LongTouchEvent(view=self.views[view_id])) for view_id in enabled_view_ids: if self.__safe_dict_get(self.views[view_id], 'editable'): possible_events.append( SetTextEvent(view=self.views[view_id], text="HelloWorld")) touch_exclude_view_ids.add(view_id) # TODO figure out what event can be sent to editable views pass for view_id in enabled_view_ids: if view_id in touch_exclude_view_ids: continue children = self.__safe_dict_get(self.views[view_id], 'children') if children and len(children) > 0: continue possible_events.append(TouchEvent(view=self.views[view_id])) # For old Android navigation bars possible_events.append(KeyEvent(name="MENU")) state_now = self.device.get_current_state() #print('BASIC SOURCE') events, event_ids = [], [] for i, event in enumerate(possible_events): event_str = str(type(event)) + '_' + event.get_event_str(state_now) if event_str in event_ids: continue events.append(event) event_ids.append(event_str) self.possible_events = events return [] + events