Source code for plaso.parsers.android_app_usage

"""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.lib import errors
from plaso.parsers import interface
from plaso.parsers import manager


[docs] class AndroidAppUsageEventData(events.EventData): """Android application usage event data. Attributes: component (str): name of the individual component of the application. last_resume_time (dfdatetime.DateTimeValues): date and time the application was last resumed. package (str): name of the Android application. """ DATA_TYPE = "android:app_usage"
[docs] def __init__(self): """Initializes event data.""" super().__init__(data_type=self.DATA_TYPE) self.component = None self.last_resume_time = 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: WrongParser: when the file cannot be parsed. """ data = file_object.read(self._HEADER_READ_SIZE) if not data.startswith(b"<?xml"): raise errors.WrongParser("Not an Android usage history file [not XML]") _, _, data = data.partition(b"\n") if not data.startswith(b"<usage-history"): raise errors.WrongParser( "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. file_object.seek(0, os.SEEK_SET) xml = ElementTree.parse(file_object) root_node = xml.getroot() for application_node in root_node: package_name = application_node.get("name") for part_node in application_node.iter(): if part_node.tag != "comp": continue last_resume_time = part_node.get("lrt") 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( f"unsupported last resume time: {last_resume_time:s}." ) continue event_data = AndroidAppUsageEventData() event_data.component = part_node.get("name") event_data.last_resume_time = dfdatetime_java_time.JavaTime( timestamp=last_resume_time ) event_data.package = package_name parser_mediator.ProduceEventData(event_data)
manager.ParsersManager.RegisterParser(AndroidAppUsageParser)