Ejemplo n.º 1
0
def search_popup_window_group(log_info, logs, curr_idx):
    content = log_info['content']
    popup_window = content['popupWindow']
    msg_type = content['msgType']

    popup_window_width = int(content['width'])
    popup_window_heigth = int(content['height'])

    if msg_type.lower() == 'action' and content['action'].lower() == 'show':
        # if msg_type.lower() == 'action' and content['action'].lower() == 'show' and (popup_window_width != -2 or popup_window_heigth != -2):
        idx = curr_idx + 1
        while idx < len(logs):
            _log_info = extract_info(logs[idx])
            _content = _log_info['content']
            idx += 1

            if _log_info['tag'] == POPUPWINDOW_TAG and _content[
                    'popupWindow'] == popup_window and _content[
                        'action'].lower() == 'hide':
                # search view
                v_idx = curr_idx + 1
                view_groups = list()
                while v_idx < idx - 1:

                    v_log_info = extract_info(logs[v_idx])

                    if v_log_info['tag'] == DIALOG_TAG:
                        group, next_v_idx = search_dialog_group(
                            v_log_info, logs, v_idx)
                        if group is None:
                            v_idx += 1
                        else:
                            v_idx += 1
                            view_groups.append(group)
                    elif v_log_info['tag'] == VIEW_TAG:
                        group, next_v_idx = search_view_group(
                            v_log_info, logs, v_idx)
                        if group is None:
                            v_idx += 1
                        else:
                            v_idx = next_v_idx
                            view_groups.append(group)
                    else:
                        v_idx += 1
                        continue

                return (curr_idx, idx - 1, POPUPWINDOW_TAG, popup_window,
                        view_groups, msg_type), idx

    return None, curr_idx + 1
Ejemplo n.º 2
0
def preprocess(file):
    """
    1. Eliminate redundant log
    2. Eliminate irrelevant logs (Only reserve [Activity], [Dialog], [PopupWindow], [ViewOnTouchEvent], [EditableInputConnection], [SpannerStringBuilder], [TextViewKeyboard])
    """
    valid_logs = list()
    with open(file, 'r') as f:
        prev_log = None
        for log in f:
            log = log.strip()
            if not find_match(log):
                continue
            if VIEW_PATTERN.match(log):
                log_info = extract_info(log)
                if 'handle' in log_info['content']:
                    continue
            if prev_log is None:
                prev_log = log
                valid_logs.append(log)
            else:
                if LOCATION_LISTENER_PATTERN.match(
                        log) or SENSOR_LISTENER_PATTERN.match(log):
                    valid_logs.append(log)
                    prev_log = log
                else:
                    if compare_logs(prev_log, log):
                        continue
                    valid_logs.append(log)
                    prev_log = log
    save_path = save_file(file, 'preprocess', '\n'.join(valid_logs))
    return save_path
Ejemplo n.º 3
0
def clear_logs(logs, target_tags):
    valid_logs = list()
    for log in logs:
        lf = extract_info(log)
        if lf['tag'] in target_tags:
            valid_logs.append(log)
    return valid_logs
Ejemplo n.º 4
0
def compare_logs(log_1, log_2):
    log_1_info, log_2_info = extract_info(log_1), extract_info(log_2)

    keys = ['tag', 'plid', 'package']
    for k in keys:
        if log_1_info[k] != log_2_info[k]:
            return False

    if len(log_1_info['content']) != len(log_2_info['content']):
        return False

    keys = list(log_1_info['content'].keys())
    for k in keys:
        if k == 'target' or k == 'webview':
            continue
        if log_1_info['content'][k] != log_2_info['content'][k]:
            return False
    return True
Ejemplo n.º 5
0
def search_activity_group(log_info, logs, curr_idx):
    """
    <down_idx, up_idx>
    TouchEvent and KeyEvent may be missed in activity 
    """
    content = log_info['content']
    plid = log_info['plid']
    package = log_info['package']
    activity = content['activity']
    msg_type = content['msgType']

    search_target = None
    search_msg_type = None
    search_action_name = None
    search_action = None
    if msg_type.lower() == 'touchevent' and content['actionId'] == 0:
        # Touch down
        search_msg_type = msg_type
        search_action_name = 'actionId'
        search_action = 1
        search_target = activity
        down_time = content['downTime']
    if msg_type.lower() == 'keyevent' and content['actionCode'] == 0:
        # Key down
        search_msg_type = msg_type
        search_action_name = 'actionCode'
        search_action = 1
        search_target = activity
        down_time = content['downTime']

    if search_target is None:
        return None, curr_idx + 1

    # Search
    idx = curr_idx + 1
    return_idx = -1
    while idx < len(logs):
        _log_info = extract_info(logs[idx])
        _content = _log_info['content']
        idx += 1

        if _log_info['tag'] == ACTIVITY_TAG and _content['msgType'] == search_msg_type \
         and _content['activity'] == search_target and _content[search_action_name] == search_action and _content['downTime'] == down_time:
            if return_idx == -1:
                return_idx = idx
            return (curr_idx, idx - 1, ACTIVITY_TAG, activity,
                    search_msg_type), return_idx

        if _log_info['tag'] == POPUPWINDOW_TAG:
            return_idx = idx - 1

    return (curr_idx, curr_idx, ACTIVITY_TAG, activity,
            search_msg_type), curr_idx + 1
Ejemplo n.º 6
0
def group_logs(file):
    """
    1. Activity:
        a. touch:  DOWN -> UP
        b. key:    DOWN -> UP
    2. Dialog:
        a. touch:  DOWN -> UP
        b. key:    DOWN -> UP
    3. PopupWindow:
        a. action: show -> hide
    4. View:
        a. touch:  DOWN -> UP
    5. SpannerStringBuilder
        a. text
    6. EditableInputConnection:
        a. show: first-appear, last-appear
    7. WebViewConsole
    8. WebViewClient
    """
    logs = list()
    with open(file, 'r') as f:
        logs = f.readlines()

    func_dict = {
        ACTIVITY_TAG: search_activity_group,
        DIALOG_TAG: search_dialog_group,
        POPUPWINDOW_TAG: search_popup_window_group,
        EDITABLE_INPUT_CONNECTION_TAG: search_editable_input_connection_group,
        TEXT_VIEW_KEY_TAG: search_textview_keyboard_group,
        WEBVIEW_CONSOLE_TAG: search_webview_console_group,
        WEBVIEW_CLIENT_TAG: search_webview_client_group,
        SENSOR_LISTENER_TAG: search_sensor_listener_group,
        LOCATION_MANAGER_TAG: search_location_manager_group,
        LOCATION_LISTENER_TAG: search_location_listener_group
    }
    logs_length = len(logs)
    idx = 0
    groups = list()
    while idx < logs_length:
        log_info = extract_info(logs[idx])
        tag = log_info['tag']
        if tag in func_dict:
            group_info, next_idx = func_dict[tag](log_info, logs, idx)
            idx = next_idx
            if group_info is None:
                continue
            groups.append(group_info)
        else:
            idx += 1
    pprint(groups)
    save_path = save_file(file, 'groups', '\n'.join([str(g) for g in groups]))
    return save_path, groups, logs
Ejemplo n.º 7
0
def search_dialog_group(log_info, logs, curr_idx):
    """
    <down_idx, up_idx>
    Auto complete dialog event since the event may fail to be logged when the dialog is destroying
    """
    content = log_info['content']
    dialog = content['dialog']
    msg_type = content['msgType']

    search_target = None
    search_msg_type = None
    search_action_name = None
    search_action = None
    if msg_type.lower() == 'touchevent' and content['actionId'] == 0:
        # Touch down
        search_msg_type = msg_type
        search_action_name = 'actionId'
        search_action = 1
        search_target = dialog
    if msg_type.lower() == 'keyevent' and content['actionCode'] == 0:
        # Key down
        search_msg_type = msg_type
        search_action_name = 'actionCode'
        search_action = 1
        search_target = dialog

    if search_target is None:
        return None, curr_idx + 1

    # Search
    idx = curr_idx + 1
    while idx < len(logs):
        _log_info = extract_info(logs[idx])
        _content = _log_info['content']
        idx += 1

        if _log_info['tag'] == DIALOG_TAG and _content[
                'msgType'] == search_msg_type and _content[
                    'dialog'] == search_target and _content[
                        search_action_name] == search_action:
            return (curr_idx, idx - 1, DIALOG_TAG, dialog,
                    search_msg_type), idx

    return (curr_idx, curr_idx, DIALOG_TAG, dialog,
            search_msg_type), curr_idx + 1
Ejemplo n.º 8
0
def search_view_group(log_info, logs, curr_idx):
    content = log_info['content']
    msg_type = content['msgType'].lower()

    if msg_type == 'touchevent' and content['actionId'] == 0:
        view = content['view']
        down_time = content['downTime']
        idx = curr_idx + 1
        while idx < len(logs):
            _log_info = extract_info(logs[idx])
            _content = _log_info['content']
            idx += 1
            if _log_info['tag'] == VIEW_TAG and _content['msgType'].lower(
            ) == msg_type and _content['downTime'] == down_time and _content[
                    'actionId'] == 1:
                return (curr_idx, idx - 1, VIEW_TAG, view, msg_type), idx

    return None, curr_idx + 1
Ejemplo n.º 9
0
def search_textview_keyboard_group(log_info, logs, curr_idx):
    content = log_info['content']
    msg_type = content['msgType'].lower()
    textview_id = content['viewId']

    if msg_type == 'keyevent' and content['actionCode'] == 0:
        down_time = content['downTime']
        idx = curr_idx + 1
        while idx < len(logs):
            _log_info = extract_info(logs[idx])
            _content = _log_info['content']
            idx += 1
            if _log_info['tag'] == TEXT_VIEW_KEY_TAG and _content[
                    'msgType'].lower() == msg_type and _content[
                        'downTime'] == down_time and _content[
                            'actionCode'] == 1:
                return (curr_idx, idx - 1, TEXT_VIEW_KEY_TAG, textview_id,
                        msg_type), curr_idx + 1

    return None, curr_idx + 1
Ejemplo n.º 10
0
def search_editable_input_connection_group(log_info, logs, curr_idx):
    content = log_info['content']
    editable_input_connection = content['editableInputConnection']
    msg_type = content['msgType']

    nested_group = list()

    if msg_type.lower() == 'type' and content['mBatchEditNesting'] != -1:
        idx = curr_idx + 1
        last_log_idx = curr_idx
        # Handle overlap EditableInputConnection
        first_overlap_idx = None
        while idx < len(logs):
            _log_info = extract_info(logs[idx])
            _content = _log_info['content']
            idx += 1
            if _log_info['tag'] == EDITABLE_INPUT_CONNECTION_TAG:

                if _content[
                        'editableInputConnection'] == editable_input_connection:
                    last_log_idx = idx - 1
                    if _content['mBatchEditNesting'] == -1:
                        if len(nested_group) > 0:
                            nested_group = remove_invalid_groups(
                                last_log_idx, nested_group)
                        return (curr_idx, last_log_idx,
                                EDITABLE_INPUT_CONNECTION_TAG,
                                editable_input_connection, nested_group,
                                msg_type), idx
                else:
                    if first_overlap_idx is None:
                        first_overlap_idx = idx - 1
                    else:
                        first_overlap_log_info = extract_info(
                            logs[first_overlap_idx])
                        if first_overlap_log_info['content'][
                                'editableInputConnection'] != _content[
                                    'editableInputConnection']:
                            # Second overlap, then dump
                            if len(nested_group) > 0:
                                nested_group = remove_invalid_groups(
                                    last_log_idx, nested_group)
                            return_idx = min(first_overlap_idx,
                                             last_log_idx) + 1
                            return (curr_idx, last_log_idx,
                                    EDITABLE_INPUT_CONNECTION_TAG,
                                    editable_input_connection, nested_group,
                                    msg_type), return_idx

            #  Support nested interaction with activity and dialog
            if _log_info['tag'] == ACTIVITY_TAG:
                group, _ = search_activity_group(_log_info, logs, idx - 1)
                if group is not None:
                    nested_group.append(group)
            elif _log_info['tag'] == DIALOG_TAG:
                group, _ = search_dialog_group(_log_info, logs, idx - 1)
                if group is not None:
                    nested_group.append(group)
            elif _log_info['tag'] == TEXT_VIEW_KEY_TAG:
                group, _ = search_textview_keyboard_group(
                    _log_info, logs, idx - 1)
                if group is not None:
                    nested_group.append(group)
            elif _log_info['tag'] == POPUPWINDOW_TAG:
                group, _ = search_popup_window_group(_log_info, logs, idx - 1)
                if group is not None:
                    nested_group.append(group)

        if last_log_idx != curr_idx:
            if len(nested_group) > 0:
                nested_group = remove_invalid_groups(last_log_idx,
                                                     nested_group)
            return_idx = last_log_idx + 1 if first_overlap_idx is None or (
                last_log_idx < first_overlap_idx) else first_overlap_idx + 1
            return (curr_idx, last_log_idx, EDITABLE_INPUT_CONNECTION_TAG,
                    editable_input_connection, nested_group,
                    msg_type), return_idx

    return None, curr_idx + 1