Source code for plaso.parsers.android_app_usage

# -*- coding: utf-8 -*-
"""Parser for the Android usage history (usage-history.xml) files."""

import os

from defusedxml import ElementTree
from dfdatetime import java_time as dfdatetime_java_time

from plaso.containers import events
from plaso.containers import time_events
from plaso.lib import errors
from plaso.lib import definitions
from plaso.parsers import interface
from plaso.parsers import manager

[docs]class AndroidAppUsageEventData(events.EventData): """Android application usage event data. Attributes: package (str): name of the Android application. component (str): name of the individual component of the application. """ DATA_TYPE = 'android:event:last_resume_time' def __init__(self): """Initializes event data.""" super(AndroidAppUsageEventData, self).__init__(data_type=self.DATA_TYPE) self.component = None self.package = None
[docs]class AndroidAppUsageParser(interface.FileObjectParser): """Parses the Android usage history (usage-history.xml) file.""" NAME = 'android_app_usage' DATA_FORMAT = 'Android usage history (usage-history.xml) file' _HEADER_READ_SIZE = 128
[docs] def ParseFileObject(self, parser_mediator, file_object): """Parses an Android usage-history file-like object. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. file_object (dfvfs.FileIO): file-like object. Raises: UnableToParseFile: when the file cannot be parsed. """ data = if not data.startswith(b'<?xml'): raise errors.UnableToParseFile( 'Not an Android usage history file [not XML]') _, _, data = data.partition(b'\n') if not data.startswith(b'<usage-history'): raise errors.UnableToParseFile( 'Not an Android usage history file [wrong XML root key]') # The current offset of the file-like object needs to point at # the start of the file for ElementTree to parse the XML data correctly., os.SEEK_SET) xml = ElementTree.parse(file_object) root_node = xml.getroot() for application_node in root_node: package_name = application_node.get('name', None) for part_node in application_node.iter(): if part_node.tag != 'comp': continue last_resume_time = part_node.get('lrt', None) if last_resume_time is None: parser_mediator.ProduceExtractionWarning('missing last resume time.') continue try: last_resume_time = int(last_resume_time, 10) except ValueError: parser_mediator.ProduceExtractionWarning( 'unsupported last resume time: {0:s}.'.format(last_resume_time)) continue event_data = AndroidAppUsageEventData() event_data.component = part_node.get('name', None) event_data.package = package_name date_time = dfdatetime_java_time.JavaTime(timestamp=last_resume_time) event = time_events.DateTimeValuesEvent( date_time, definitions.TIME_DESCRIPTION_LAST_RESUME) parser_mediator.ProduceEventWithEventData(event, event_data)