|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +"""SQLite parser plugin for Android app_usage database files.""" |
| 3 | + |
| 4 | +from dfdatetime import posix_time as dfdatetime_posix_time |
| 5 | + |
| 6 | +from plaso.containers import events |
| 7 | +from plaso.parsers import sqlite |
| 8 | +from plaso.parsers.sqlite_plugins import interface |
| 9 | + |
| 10 | + |
| 11 | +class AndroidAppUsage(events.EventData): |
| 12 | + """Android app usage event data. |
| 13 | +
|
| 14 | + Attributes: |
| 15 | + package_name (str): name of the launched package. |
| 16 | + start_time (dfdatetime.DateTimeValues): date and time when the application |
| 17 | + was launched. |
| 18 | + """ |
| 19 | + |
| 20 | + DATA_TYPE = 'android:sqlite:app_usage' |
| 21 | + |
| 22 | + def __init__(self): |
| 23 | + """Initializes event data.""" |
| 24 | + super(AndroidAppUsage, self).__init__(data_type=self.DATA_TYPE) |
| 25 | + self.package_name = None |
| 26 | + self.start_time = None |
| 27 | + |
| 28 | + |
| 29 | +class AndroidSQLiteAppUsage(interface.SQLitePlugin): |
| 30 | + """SQLite parser plugin for Android application usage database files.""" |
| 31 | + |
| 32 | + NAME = 'android_app_usage' |
| 33 | + DATA_FORMAT = 'Android app_usage SQLite database (app_usage) file' |
| 34 | + |
| 35 | + REQUIRED_STRUCTURE = { |
| 36 | + 'events': frozenset(['_id', 'timestamp', 'package_id']), |
| 37 | + 'packages': frozenset(['_id', 'package_name']) |
| 38 | + } |
| 39 | + |
| 40 | + QUERIES = [ |
| 41 | + ('SELECT events.timestamp, packages.package_name FROM events JOIN ' |
| 42 | + 'packages ON packages._id = events.package_id', 'ParseAppUsageRow')] |
| 43 | + |
| 44 | + SCHEMAS = [{ |
| 45 | + 'events': ( |
| 46 | + 'CREATE TABLE "events" (_id INTEGER PRIMARY KEY,timestamp INTEGER ' |
| 47 | + 'NOT NULL,type INTEGER NOT NULL,package_id INTEGER NOT NULL ' |
| 48 | + 'REFERENCES packages(_id) ON UPDATE CASCADE ON DELETE CASCADE, ' |
| 49 | + 'instance_id INTEGER DEFAULT NULL, task_root_package_id INTEGER ' |
| 50 | + 'DEFAULT NULL REFERENCES packages(_id) ON UPDATE CASCADE ON DELETE ' |
| 51 | + 'CASCADE)'), |
| 52 | + 'packages': ( |
| 53 | + 'CREATE TABLE packages (_id INTEGER PRIMARY KEY,package_name TEXT, ' |
| 54 | + 'UNIQUE(package_name) ON CONFLICT ABORT)')}] |
| 55 | + |
| 56 | + def ParseAppUsageRow(self, parser_mediator, query, row, **unused_kwargs): |
| 57 | + """Parses an event record row. |
| 58 | +
|
| 59 | + Args: |
| 60 | + parser_mediator (ParserMediator): mediates interactions between parsers |
| 61 | + and other components, such as storage and dfVFS. |
| 62 | + query (str): query that created the row. |
| 63 | + row (sqlite3.Row): row. |
| 64 | + """ |
| 65 | + query_hash = hash(query) |
| 66 | + |
| 67 | + event_data = AndroidAppUsage() |
| 68 | + event_data.package_name = self._GetRowValue(query_hash, row, 'package_name') |
| 69 | + |
| 70 | + timestamp = self._GetRowValue(query_hash, row, 'timestamp') |
| 71 | + event_data.start_time = dfdatetime_posix_time.PosixTimeInMilliseconds( |
| 72 | + timestamp=timestamp) |
| 73 | + |
| 74 | + parser_mediator.ProduceEventData(event_data) |
| 75 | + |
| 76 | + |
| 77 | +sqlite.SQLiteParser.RegisterPlugin(AndroidSQLiteAppUsage) |
0 commit comments