|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +"""SQLite parser plugin for Android turbo 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 AndroidTurboBatteryEvent(events.EventData): |
| 12 | + """Android turbo battery event data. |
| 13 | +
|
| 14 | + Attributes: |
| 15 | + battery_level (int): Remaining battery level, expressed as a percentage. |
| 16 | + battery_saver (int): Indicates if battery saver is turn on. |
| 17 | + charge_type (int): Indicates that the device is charging. |
| 18 | + recorded_time (dfdatetime.DateTimeValues): date and time the battery event |
| 19 | + was recorded. |
| 20 | + """ |
| 21 | + |
| 22 | + DATA_TYPE = 'android:event:battery' |
| 23 | + |
| 24 | + def __init__(self): |
| 25 | + """Initializes event data.""" |
| 26 | + super(AndroidTurboBatteryEvent, self).__init__(data_type=self.DATA_TYPE) |
| 27 | + self.battery_level = None |
| 28 | + self.battery_saver = None |
| 29 | + self.charge_type = None |
| 30 | + self.recorded_time = None |
| 31 | + |
| 32 | + |
| 33 | +class AndroidTurboPlugin(interface.SQLitePlugin): |
| 34 | + """SQLite parser plugin for Android's turbo.db database files.""" |
| 35 | + |
| 36 | + NAME = 'android_turbo' |
| 37 | + DATA_FORMAT = 'Android turbo SQLite database (turbo.db) file' |
| 38 | + |
| 39 | + REQUIRED_STRUCTURE = { |
| 40 | + 'battery_event': frozenset([ |
| 41 | + 'timestamp_millis', 'battery_level', 'charge_type', 'battery_saver'])} |
| 42 | + |
| 43 | + QUERIES = [ |
| 44 | + ('SELECT timestamp_millis, battery_level, charge_type, battery_saver ' |
| 45 | + 'FROM battery_event', |
| 46 | + 'ParseBatteryEventRow')] |
| 47 | + |
| 48 | + SCHEMAS = [{ |
| 49 | + 'android_metadata': 'CREATE TABLE android_metadata (locale TEXT)', |
| 50 | + 'battery_event': ( |
| 51 | + 'CREATE TABLE battery_event(timestamp_millis INTEGER PRIMARY KEY ' |
| 52 | + 'DESC, battery_level INTEGER, charge_type INTEGER, battery_saver ' |
| 53 | + 'INTEGER, timezone TEXT, place_key INTEGER, FOREIGN KEY(place_key) ' |
| 54 | + 'REFERENCES charging_places(_id))'), |
| 55 | + 'charging_places': ( |
| 56 | + 'CREATE TABLE charging_places(_id INTEGER PRIMARY KEY, place_name ' |
| 57 | + 'TEXT, place_api_id TEXT, UNIQUE(place_api_id) ON CONFLICT IGNORE)')}] |
| 58 | + |
| 59 | + def ParseBatteryEventRow(self, parser_mediator, query, row, **unused_kwargs): |
| 60 | + """Parses a row from the battery_event table. |
| 61 | +
|
| 62 | + Args: |
| 63 | + parser_mediator (ParserMediator): mediates interactions between parsers |
| 64 | + and other components, such as storage and dfVFS. |
| 65 | + query (str): query that created the row. |
| 66 | + row (sqlite3.Row): row. |
| 67 | + """ |
| 68 | + query_hash = hash(query) |
| 69 | + |
| 70 | + event_data = AndroidTurboBatteryEvent() |
| 71 | + event_data.battery_level = self._GetRowValue( |
| 72 | + query_hash, row, 'battery_level') |
| 73 | + event_data.battery_saver = self._GetRowValue( |
| 74 | + query_hash, row, 'battery_saver') |
| 75 | + event_data.charge_type = self._GetRowValue(query_hash, row, 'charge_type') |
| 76 | + |
| 77 | + timestamp = self._GetRowValue(query_hash, row, 'timestamp_millis') |
| 78 | + |
| 79 | + event_data.recorded_time = dfdatetime_posix_time.PosixTimeInMilliseconds( |
| 80 | + timestamp=timestamp) |
| 81 | + |
| 82 | + parser_mediator.ProduceEventData(event_data) |
| 83 | + |
| 84 | + |
| 85 | +sqlite.SQLiteParser.RegisterPlugin(AndroidTurboPlugin) |
0 commit comments