<commit_before>import json
import logging
import os
import subprocess
import time
from threading import Timer

from input_event import EventLog
from input_policy import InputPolicy, UtgBasedInputPolicy, UtgBfsPolicy, UtgDfsPolicy

POLICY_NONE = "none"
POLICY_MONKEY = "monkey"
POLICY_BFS = "bfs"
POLICY_DFS = "dfs"
POLICY_MANUAL = "manual"

DEFAULT_POLICY = POLICY_DFS
DEFAULT_EVENT_INTERVAL = 1
DEFAULT_EVENT_COUNT = 1000
DEFAULT_TIMEOUT = -1

START_RETRY_THRESHOLD = 20


class UnknownInputException(Exception):
    pass


class InputManager(object):
    """
    This class manages all events to send during app running
    """

    def __init__(self, device, app, policy_name, no_shuffle,
                 event_count, event_interval, timeout,
                 script_path=None, profiling_method=None):
        """
        manage input event sent to the target device
        :param device: instance of Device
        :param app: instance of App
        :param policy_name: policy of generating events, string
        :return:
        """
        self.logger = logging.getLogger('InputEventManager')
        self.enabled = True

        self.device = device
        self.app = app
        self.policy_name = policy_name
        self.no_shuffle = no_shuffle
        self.events = []
        self.policy = None
        self.script = None
        self.event_count = event_count
        self.event_interval = event_interval
        self.timeout = timeout

        self.monkey = None
        self.timer = None

        if script_path is not None:
            f = open(script_path, 'r')
            script_dict = json.load(f)
            from input_script import DroidBotScript
            self.script = DroidBotScript(script_dict)

        self.policy = self.get_input_policy(device, app)
        self.profiling_method = profiling_method

    def get_input_policy(self, device, app):
        input_policy = None
        if self.policy_name == POLICY_NONE:
            input_policy = None
        elif self.policy_name == POLICY_MONKEY:
            input_policy = None
        elif self.policy_name == POLICY_BFS:
            input_policy = UtgBfsPolicy(device, app, self.no_shuffle)
        elif self.policy_name == POLICY_DFS:
            input_policy = UtgDfsPolicy(device, app, self.no_shuffle)
        # elif self.policy_name == POLICY_MANUAL:
        #     input_policy = ManualEventFactory(device, app)
        else:
            input_policy = None
        if isinstance(input_policy, UtgBasedInputPolicy):
            input_policy.script = self.script
        return input_policy

    def add_event(self, event):
        """
        add one event to the event list
        :param event: the event to be added, should be subclass of AppEvent
        :return:
        """
        if event is None:
            return
        self.events.append(event)

        event_log = EventLog(self.device, self.app, event, self.profiling_method)
        if self.profiling_method is not None:
            event_log.start_profiling()
        self.device.send_event(event)
        time.sleep(self.event_interval)
        if self.profiling_method is not None:
            event_log.stop_profiling()
        event_log.save2dir()

    def start(self):
        """
        start sending event
        """
        self.logger.info("start sending events, policy is %s" % self.policy_name)

        if self.timeout > 0:
            self.timer = Timer(self.timeout, self.stop)
            self.timer.start()

        try:
            if self.policy is not None:
                self.policy.start(self)
            elif self.policy_name == POLICY_NONE:
                self.device.start_app(self.app)
                if self.event_count == 0:
                    return
                while self.enabled:
                    time.sleep(1)
            elif self.policy_name == POLICY_MONKEY:
                throttle = self.event_interval * 1000
                monkey_cmd = "adb -s %s shell monkey %s --ignore-crashes --ignore-security-exceptions" \
                             " --throttle %d %d" % \
                             (self.device.serial,
                              "" if self.app.get_package_name() is None else "-p " + self.app.get_package_name(),
                              throttle,
                              self.event_count)
                self.monkey = subprocess.Popen(monkey_cmd.split(),
                                               stdout=subprocess.PIPE,
                                               stderr=subprocess.PIPE)
                while self.enabled:
                    time.sleep(1)
            elif self.policy_name == POLICY_MANUAL:
                self.device.start_app(self.app)
                while self.enabled:
                    keyboard_input = raw_input("press ENTER to save current state, type q to exit...")
                    if keyboard_input.startswith('q'):
                        break
                    state = self.device.get_current_state()
                    if state is not None:
                        state.save2dir()
        except KeyboardInterrupt:
            pass

        self.stop()
        self.logger.info("Finish sending events")

    def stop(self):
        """
        stop sending event
        """
        if self.monkey:
            self.monkey.terminate()
            self.monkey = None
            pid = self.device.get_app_pid("com.android.commands.monkey")
            if pid is not None:
                self.device.shell("kill -9 %d" % pid)
        if self.timer and self.timer.isAlive():
            self.timer.cancel()
            self.timer = None
        self.enabled = False<commit_msg>fix bug: stop monkey when disconnected<commit_after>import json
import logging
import subprocess
import time
from threading import Timer

from input_event import EventLog
from input_policy import UtgBasedInputPolicy, UtgBfsPolicy, UtgDfsPolicy

POLICY_NONE = "none"
POLICY_MONKEY = "monkey"
POLICY_BFS = "bfs"
POLICY_DFS = "dfs"
POLICY_MANUAL = "manual"

DEFAULT_POLICY = POLICY_DFS
DEFAULT_EVENT_INTERVAL = 1
DEFAULT_EVENT_COUNT = 1000
DEFAULT_TIMEOUT = -1


class UnknownInputException(Exception):
    pass


class InputManager(object):
    """
    This class manages all events to send during app running
    """

    def __init__(self, device, app, policy_name, no_shuffle,
                 event_count, event_interval, timeout,
                 script_path=None, profiling_method=None):
        """
        manage input event sent to the target device
        :param device: instance of Device
        :param app: instance of App
        :param policy_name: policy of generating events, string
        :return:
        """
        self.logger = logging.getLogger('InputEventManager')
        self.enabled = True

        self.device = device
        self.app = app
        self.policy_name = policy_name
        self.no_shuffle = no_shuffle
        self.events = []
        self.policy = None
        self.script = None
        self.event_count = event_count
        self.event_interval = event_interval
        self.timeout = timeout

        self.monkey = None
        self.timer = None

        if script_path is not None:
            f = open(script_path, 'r')
            script_dict = json.load(f)
            from input_script import DroidBotScript
            self.script = DroidBotScript(script_dict)

        self.policy = self.get_input_policy(device, app)
        self.profiling_method = profiling_method

    def get_input_policy(self, device, app):
        input_policy = None
        if self.policy_name == POLICY_NONE:
            input_policy = None
        elif self.policy_name == POLICY_MONKEY:
            input_policy = None
        elif self.policy_name == POLICY_BFS:
            input_policy = UtgBfsPolicy(device, app, self.no_shuffle)
        elif self.policy_name == POLICY_DFS:
            input_policy = UtgDfsPolicy(device, app, self.no_shuffle)
        # elif self.policy_name == POLICY_MANUAL:
        #     input_policy = ManualEventFactory(device, app)
        else:
            input_policy = None
        if isinstance(input_policy, UtgBasedInputPolicy):
            input_policy.script = self.script
        return input_policy

    def add_event(self, event):
        """
        add one event to the event list
        :param event: the event to be added, should be subclass of AppEvent
        :return:
        """
        if event is None:
            return
        self.events.append(event)

        event_log = EventLog(self.device, self.app, event, self.profiling_method)
        if self.profiling_method is not None:
            event_log.start_profiling()
        self.device.send_event(event)
        time.sleep(self.event_interval)
        if self.profiling_method is not None:
            event_log.stop_profiling()
        event_log.save2dir()

    def start(self):
        """
        start sending event
        """
        self.logger.info("start sending events, policy is %s" % self.policy_name)

        if self.timeout > 0:
            self.timer = Timer(self.timeout, self.stop)
            self.timer.start()

        try:
            if self.policy is not None:
                self.policy.start(self)
            elif self.policy_name == POLICY_NONE:
                self.device.start_app(self.app)
                if self.event_count == 0:
                    return
                while self.enabled:
                    time.sleep(1)
            elif self.policy_name == POLICY_MONKEY:
                throttle = self.event_interval * 1000
                monkey_cmd = "adb -s %s shell monkey %s --ignore-crashes --ignore-security-exceptions" \
                             " --throttle %d %d" % \
                             (self.device.serial,
                              "" if self.app.get_package_name() is None else "-p " + self.app.get_package_name(),
                              throttle,
                              self.event_count)
                self.monkey = subprocess.Popen(monkey_cmd.split(),
                                               stdout=subprocess.PIPE,
                                               stderr=subprocess.PIPE)
                while self.enabled:
                    time.sleep(1)
            elif self.policy_name == POLICY_MANUAL:
                self.device.start_app(self.app)
                while self.enabled:
                    keyboard_input = raw_input("press ENTER to save current state, type q to exit...")
                    if keyboard_input.startswith('q'):
                        break
                    state = self.device.get_current_state()
                    if state is not None:
                        state.save2dir()
        except KeyboardInterrupt:
            pass

        self.stop()
        self.logger.info("Finish sending events")

    def stop(self):
        """
        stop sending event
        """
        if self.monkey:
            self.monkey.terminate()
            self.monkey = None
            pid = self.device.get_app_pid("com.android.commands.monkey")
            if pid is not None:
                self.device.adb.shell("kill -9 %d" % pid)
        if self.timer and self.timer.isAlive():
            self.timer.cancel()
            self.timer = None
        self.enabled = False
{'fraction_non_alphanumeric': 0.0803319209039548, 'fraction_numerical': 0.0031779661016949155, 'mean_word_length': 1.7076959847036328, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3679014', 'n_tokens_mistral': 3211, 'n_tokens_neox': 3068, 'n_words': 753}