33 KiB
Statische Reverse-Analyse von EpgDatabase.db
Stand: 2026-08-25
Zielplattform: Philips TPM191E, Firmware TPM191E_R.211.000.103.000, Android TV 12
Hauptartefakt: diagnostics/raw/storage/channels.apk
Umfang und Beweisgrade
Diese Untersuchung war ausschließlich lokal und lesend. Es wurden keine ADB-Gerätebefehle und keine Reparatur-, Lösch-, Reset- oder Rebuild-Aktion auf dem Fernseher ausgeführt. Untersucht wurden die vorhandenen APK-/DEX-Artefakte, deren binäres Manifest und Ressourcen sowie bereits zuvor abgelegte Diagnoseausgaben.
Die Kennzeichnungen bedeuten:
- BEWIESEN: direkt aus Manifest, DEX-Bytecode, SQL-Literal oder vorhandener Rohdiagnose ableitbar.
- SEHR WAHRSCHEINLICH: mehrere direkte Belege ergeben dieselbe Erklärung; eine verbleibende Laufzeitunsicherheit besteht.
- PLAUSIBEL: technisch gut passende Interpretation, deren Entwicklerabsicht oder Laufzeitwirkung nicht direkt belegt ist.
- NICHT VERIFIZIERBAR: mit den lokal vorhandenen Artefakten nicht entscheidbar.
Kurzfazit
- BEWIESEN:
org.droidtv.channelsverwaltetEpgDatabase.dbüberorg.droidtv.channels.epg.bcepg.EpgDatabaseHelper, eine Unterklasse vonandroid.database.sqlite.SQLiteOpenHelper. Der Konstruktor übergibt den DatenbanknamenEpgDatabase.dbund die Schemaversion 6. - BEWIESEN: Die vorgesehene zeitbasierte Stale-Cleanup-Kette endet in
EpgProvider$deleteStaleDataRunnable.run(). Dieses Runnable berechnet zwei Grenzwerte und protokolliert sie, führt aber keinerlei Löschung aus. Es gibt darin wederSQLiteDatabase.delete/execSQLnochContentResolver.delete/applyBatchnoch einen Aufruf der vorhandenen echten Zeit-Löschmethoden. - BEWIESEN: Der beim Provider-Start ausgeführte Logpfad wird nach 120.000 ms ausgelöst. Die vorhandenen Boot-Logs passen exakt zum Bytecode, beweisen aber keine gelöschte Zeile.
- BEWIESEN: Die Rebuild-Pfade löschen Zeilen, komprimieren die SQLite-Datei jedoch nicht. In allen vier DEX-Dateien von
channels.apkfehlen Literale beziehungsweise Referenzen fürVACUUM,PRAGMA auto_vacuum,incremental_vacuumundwal_checkpoint. - BEWIESEN: Die bisher kleinen Zeilenzahlen betreffen nur
indextable,nowtable,nexttableundfastipnownexttable; sie begrenzen wederscheduletablenoch die beiden FVP-Tabellen. Eine lesende Abfrage des Join-Endpunktsantenna/scheduletablelief länger als 120 Sekunden und musste clientseitig abgebrochen werden. Aktive Schedule-/FVP-Daten können daher einen wesentlichen Teil der 1,62 GiB belegen. - SEHR WAHRSCHEINLICH: Der wirkungslose Stale-Cleanup ist ein konkreter Mechanismus, durch den alte Schedule-Daten anwachsen können. Ob die Dateigröße überwiegend aus lebenden Schedule-/FVP-Zeilen, freien Seiten oder interner Fragmentierung besteht, ist ohne
freelist_count/dbstatbeziehungsweise DB-Kopie offen. - BEWIESEN: Es gibt interne mutierende Rebuild-URIs, aber keine gefundene Benutzer-Activity, Service-Aktion oder UI-Zeichenkette „EPG zurücksetzen/löschen“. Das Umschalten der TV-Guide-Quelle ist ausdrücklich keine harmlose Reset-Funktion: Ressourcen warnen vor Verlust beziehungsweise Abbruch von Aufnahmen, Erinnerungen und programmierten Aufnahmen.
Analysierte Artefakte
| Artefakt | SHA-256 | Relevanz |
|---|---|---|
diagnostics/raw/storage/channels.apk |
3A44BC648624F0CC9CD9FEB4CFC3FD33F41323597718E4FCCFC25FE35504D34F |
EPG-Provider, Datenbankhelper, Guide-UI, Aufnahme-/Reminder-Verknüpfungen |
diagnostics/raw/tvstrings.apk |
A25724A08369FBF1AE31884044816441C4ABCD9FC0F0116BCDB563FEC44AE923 |
lokalisierte TV-Guide-Warntexte |
diagnostics/raw/TPTvService.apk |
75F492EE89906C8C267D685D2B7D0CE02BB09F3A6B4CC8456F8B096B9E441ECD |
Quersuche nach externen Rebuild-/Cleanup-Aufrufern |
diagnostics/raw/eum.apk |
3B27806AC60B946C47CCAC1BE7EDAD46938CAE10C43C3F2E1F3EF4F9D2D30B98 |
Quersuche |
diagnostics/raw/storage/gel.apk |
29A68E6B09700ED4CCDF312C0B99EEE0C3F67E329A537FE87ED4341A71D383D7 |
Quersuche |
diagnostics/raw/tvwidgets2k15.apk |
93876A5FDC637B304BD6EE988A7F7523D957A9B0135AEFD62E3C13A6AC06E496 |
Quersuche |
diagnostics/raw/emmc/usagelogger.apk |
7416D0F7017B56F2980A4F3042B49A4A6954D9FBACC7FF995509FB8BD9BF6A15 |
Quersuche |
channels.apk enthält vier DEX-Dateien: classes.dex, classes2.dex, classes3.dex und classes4.dex. Die hier relevante Implementierung liegt überwiegend in channels.apk!/classes4.dex.
Für die reproduzierbare Extraktion wurden die lokalen, dependency-freien Hilfsprogramme dex_probe.py, axml_dump.py und resource_strings.py in diesem Verzeichnis verwendet. Sie dekompilieren nicht heuristisch, sondern lesen DEX-Index-/Klassendaten, Bytecode-Referenzen, binäres Android-Manifest und Resource-Stringpools.
Datenbankname, Helper und Version
Helper
- BEWIESEN: Klasse
Lorg/droidtv/channels/epg/bcepg/EpgDatabaseHelper; - BEWIESEN: Superklasse
Landroid/database/sqlite/SQLiteOpenHelper; - BEWIESEN: Konstruktor
EpgDatabaseHelper.<init>(android.content.Context)lädt das LiteralEpgDatabase.db, setzt die CursorFactory aufnullund den Versionsparameter auf6, bevorSQLiteOpenHelper.<init>(Context,String,CursorFactory,int)aufgerufen wird. - BEWIESEN:
onCreate(SQLiteDatabase)ruft ausschließlichcreateTables(SQLiteDatabase)auf. - BEWIESEN: In der Helper-Klasse gibt es keine Overrides von
onConfigure()oderonOpen().
Schema v6
EpgDatabaseHelper.createTables(SQLiteDatabase) enthält folgende physischen Tabellen:
| Tabelle | Exakte Spalten aus dem DDL |
|---|---|
mappingtable |
mappingid INTEGER PRIMARY KEY AUTOINCREMENT, presetid INTEGER, svlid INTEGER, svlrecid INTEGER |
indextable |
dbitindex INTEGER PRIMARY KEY AUTOINCREMENT, satnum, sid, tsid, onid, pfshd, sdtguidanceinfo TEXT, dpsid, dptsid, pkgid, presetnumber, presetid, favoriteNumber, channelname TEXT, logoid, svlid, svlrecid, browsable (nicht als TEXT markierte Felder jeweils INTEGER) |
nowtable |
_id INTEGER PRIMARY KEY AUTOINCREMENT, eventid, presetid, eventname TEXT, version, starttime, endtime, shortinfo TEXT, extendedinfo TEXT, languageid, linktype, targetindex, genre, scrambled, rating, guidanceinfo TEXT |
nexttable |
identisch zu nowtable |
scheduletable |
_id INTEGER PRIMARY KEY AUTOINCREMENT, eventid, presetid, eventname TEXT, version, starttime, endtime, shortinfo TEXT, extendedinfo TEXT, languageid, genre, scrambled, rating, guidanceinfo TEXT |
fvpscheduletable |
channelid, onid, sid, eventid, crid, Start-/Endzeit, Titel-/Synopsis-, Genre-/Rating-, Bild-/On-Demand-, Accessibility-, Delivery-, Video- und Expiry-Felder; zusammengesetzter Primärschlüssel (channelid,starttime,endtime) |
fvpnownexttable |
wie FVP-Schedule mit zusätzlichem nownext, restartstatus und FVP-Now/Next-Feldern; zusammengesetzter Primärschlüssel (channelid,starttime,endtime) |
channelmapversiontable |
id INTEGER PRIMARY KEY, majorversion INTEGER, minorversion INTEGER, favouriteversion INTEGER |
fastipnownexttable |
_id INTEGER PRIMARY KEY AUTOINCREMENT, channelid, eventid, programId, nownext, Start-/Endzeit, Titel-/Synopsis-, Genre-/Rating-, Audio-/Video-, lastmodified- und expiretime-Felder |
Die vollständigen, ungekürzten DDL-Literale stehen in epg-dex-context.txt, insbesondere im Kontext von EpgDatabaseHelper.createTables().
Definierte Indizes:
mappingindex(svlid,svlrecid)indexdbit(satnum,sid,tsid,onid)indexpresetid(presetid,presetnumber)indexnowendtime(endtime),indexnowevent(presetid)indexnextendtime(endtime),indexnextevent(presetid)indexschedendtime(endtime),indexschedstarttime(starttime),indexschedpresetid(presetid),indexschedeventid(presetid,eventid)ixfvpschedpresetidstet(channelid,starttime,endtime)ixfvpnownext(channelid,starttime,endtime)
BEWIESEN: nownexttable ist trotz des URI-Pfads keine durch createTables() angelegte physische Tabelle. EpgProvider.query() bildet diesen Endpunkt über den Join
indextable AS Dbit LEFT JOIN nowtable AS Now USING(presetid) LEFT JOIN nexttable AS Next USING(presetid)
ab. Frühere Rohnotizen, die nownexttable als physische Tabelle bezeichnen, sind insofern zu präzisieren.
onUpgrade, onDowngrade und vermeintliche Drop-Funktionen
onUpgrade(SQLiteDatabase,int,int)
BEWIESEN: Der Bytecode vergleicht den Parameter newVersion mit 4, 5 und 6:
- Zielversion 4, 5 oder 6: nur
createTables(db); wegenIF NOT EXISTSeine additive/idempotente Schemaanlage. - Jede andere Zielversion:
DROP TABLE IF EXISTSfürindextable,nowtable,nexttable,scheduletable,channelmapversiontableundfastipnownexttable, anschließendcreateTables(db).
Der Fallback droppt weder mappingtable noch fvpscheduletable noch fvpnownexttable.
onDowngrade(SQLiteDatabase,int,int)
BEWIESEN: Die Methode protokolliert lediglich onDowngrade allowed und nimmt keine Schemaänderung vor.
resetInstance()
BEWIESEN: EpgDatabaseHelper.resetInstance() setzt nur das statische Singleton-Feld mEpgDbHelper auf null. Die Methode löscht weder Datei noch Tabellen oder Zeilen.
dropTables() und dropIndexTable()
Die Namen sind irreführend:
- BEWIESEN:
dropIndexTable()führt innerhalb einer TransaktionSQLiteDatabase.delete("indextable", null, null)aus; die Tabelle selbst bleibt bestehen. - BEWIESEN:
dropTables()führtSQLiteDatabase.delete(table,null,null)fürindextable,nowtable,nexttable,scheduletable,fvpnownexttable,fvpscheduletable,channelmapversiontableundfastipnownexttableaus. - BEWIESEN:
mappingtablewird vondropTables()nicht geleert.syncOnChannelTableChange()leert und rekonstruiert sie später separat aus der kanonischen Senderliste. - BEWIESEN: Keine der beiden Methoden führt anschließend
VACUUModer eine andere Dateikompaktierung aus.
Stale-/Cleanup-Logik
Tatsächliche Aufrufketten
Es existieren zwei Einstiege in dasselbe Runnable:
-
Provider-Start
EpgProvider$1.run()führt zunächstdropIndexTable(),syncChannelTable()undsyncOnChannelTableChange()aus.- Danach postet die Methode
mDeleteStaleDataRunnablemitHandler.postDelayed(..., 120000). - Das Literal und die Logmeldung
Posting stale data deletion after 2 mins in onCreatestimmen überein.
-
Alarm/Receiver-Pfad
- Manifest-Receiver:
org.droidtv.channels.epg.bcepg.EpgStaleDataCleanupAlarmReceiver - Intent-Action:
org.droidtv.channels.epg.bcepg.EpgStaleDataCleanupAlarmReceiver.CLEAR_STALE_DATA - Data-Scheme:
epgStaleDataCleanup EpgDatabaseHelper.setEpgStaleDataCleanUpAlarm()erstellt einen expliziten Pending-Broadcast und setzt perAlarmManager.setExact()einen RTC-Alarm aufcurrentTimeMillis + 43.200.000 ms, also 12 Stunden.EpgStaleDataCleanupAlarmReceiver.onReceive()ruftEpgInfoSingleton.cleanEpgStaleData()auf.EpgInfoSingleton$8.run()führtContentResolver.delete(content://org.droidtv.epgdvb/antenna/staledatacleanup,null,null)aus.EpgProvider.delete()postet dafürEpgProvider$deleteStaleDataRunnable.
- Manifest-Receiver:
BEWIESEN: In allen vier DEX-Dateien von channels.apk gibt es keinen Invoke-Verweis auf EpgDatabaseHelper.setEpgStaleDataCleanUpAlarm(). Der Receiver plant den Alarm nach Empfang nicht erneut. Damit ist die Methode in den lokal sichtbaren direkten Java-Aufrufpfaden verwaist. Ein reflektiver oder aus einem nicht vorhandenen Artefakt kommender Aufruf bleibt NICHT VERIFIZIERBAR.
Das Cleanup-Runnable löscht nichts
Lorg/droidtv/channels/epg/bcepg/EpgProvider$deleteStaleDataRunnable;->run()V enthält im Uhr-definiert-Zweig exakt folgende relevante Operationen:
System.currentTimeMillis()- Subtraktion des Wide-Literals
1800 - bei verfügbarem FreeView zusätzlich Subtraktion des Wide-Literals
604800 - Ausgabe des Ergebnisses über
Log.d("EpgProvider", "Deleting stale data for time " + threshold)
BEWIESEN: Danach folgt keine Datenoperation. Die vollständige Methodenreferenzliste enthält ausschließlich Clock-/FreeView-Abfragen, StringBuilder/Logging und im Uhr-nicht-definiert-Zweig Handler.postDelayed() mit 30000 ms. Sie enthält insbesondere nicht:
SQLiteDatabase.delete,execSQL,rawQueryoder eine andere SQLite-Mutation,ContentResolver.delete,applyBatch,updateoderinsert,EpgProgramPump.deleteChannelProgrambytime()oderdeleteScheduleProgramsByTime(),- eine native oder sonstige in dieser Methode sichtbare Löschfunktion.
Damit ist der als Stale-Cleanup bezeichnete Uhr-definiert-Pfad in dieser Firmware funktional ein No-op mit Logausgabe.
Einheitenfehler ist zusätzlich sichtbar
- BEWIESEN: Der Code verwendet
System.currentTimeMillis(), subtrahiert die Literale aber direkt als Millisekunden. - PLAUSIBEL:
1800war als 1.800 Sekunden = 30 Minuten und604800als 604.800 Sekunden = 7 Tage gemeint; die fehlende Multiplikation mit 1.000 würde daraus 1,8 Sekunden beziehungsweise 10,08 Minuten machen. - BEWIESEN: Der vorhandene Boot-Log bestätigt die tatsächliche Einheit: Logzeit
2026-08-25 11:11:48.657, protokollierter Grenzwert1787649106837= lokal2026-08-25 11:11:46.837, also rund 1,82 Sekunden früher. - Wegen der vollständig fehlenden Löschoperation ändert selbst dieser falsche Grenzwert derzeit keine Zeilen.
Vorhandene echte Zeit-Löschmethoden sind nicht verdrahtet
Folgende Methoden könnten tatsächlich alte EPG-Zeilen entfernen:
EpgProgramPump.deleteChannelProgrambytime(long): dreiContentProviderOperation.newDelete()-Operationen mitendtime < ?, danachapplyBatch("org.droidtv.epgdvb", ...); die dreimContentUri-Ziele sind Now, Next und Schedule.EpgProgramPump.deleteScheduleProgramsByTime(long):ContentResolver.delete()für Schedule mitendtime < ?.EpgSyncThread.deleteScheduleProgramsByTime(long): delegiert an die vorige Methode.
BEWIESEN: Es gibt in den vier DEX-Dateien keinen direkten Invoke-Aufrufer für diese drei öffentlichen Methoden. Insbesondere ruft deleteStaleDataRunnable.run() keine davon auf. Ein externer/reflektiver Aufruf ist NICHT VERIFIZIERBAR, aber für die sichtbare Cleanup-Kette nicht vorhanden.
Normale EPG-Synchronisation enthält dagegen selektive Lösch-/Update-Pfade wie deleteProgramsInWindow() und kanalbezogene Abgleiche. Das erklärt, warum aktuelle Tabellen klein sein können, obwohl der globale Zeit-Cleanup wirkungslos ist.
VACUUM, auto_vacuum und Dateigröße
- BEWIESEN: Quersuche über alle vier
channels.apk-DEX-Dateien fand kein Literal beziehungsweise keine Referenz fürVACUUM,PRAGMA,auto_vacuum,incremental_vacuumoderwal_checkpoint. - BEWIESEN:
dropTables()und beide Rebuild-Runnables löschen Zeilen, rufen aber selbst wederVACUUMnoch ein Auto-Vacuum-PRAGMA auf. - BEWIESEN, aber nicht gerätespezifisch: Die AOSP-libsqlite-Buildkonfiguration ist mindestens im Android-11-Branch mit
-DSQLITE_DEFAULT_AUTOVACUUM=1dokumentiert, also DefaultFULL. Der Android-12-Quellbaum besitzt dieselbe Buildstruktur. Dieser Primärquellenhinweis stammt aus der parallelen Plattformanalyse, nicht aus dem Philips-APK. - SEHR WAHRSCHEINLICH: Falls TP Vision die AOSP-Option unverändert übernommen und die DB sie bei Anlage geerbt hat, kann SQLite freie Endseiten bei Commits automatisch zurückgeben. Die bloße Abwesenheit eines appseitigen
VACUUMbeweist deshalb nicht, dass ein großer Freelist-Anteil bestehen muss. - NICHT VERIFIZIERBAR: Die konkrete Vendor-Buildoption sowie der tatsächliche Headerwert von
PRAGMA auto_vacuum,page_count,freelist_count, Seitengröße und WAL-Zustand der laufenden Datenbank, da keine lokale Kopie vonEpgDatabase.dbvorliegt und diese Teilanalyse keine Gerätezriffe ausgeführt hat.
Vorhandene lokale Rohdiagnose (diagnostics/raw/storage/epg-content-evidence.txt):
| Objekt | aktuelle Zeilen | beobachtete IDs |
|---|---|---|
indextable |
358 | dbitindex 1.267.806 bis 1.268.163 |
nowtable |
195 | _id 4.431.681 bis 4.451.328 |
nexttable |
162 | _id 4.026.589 bis 4.027.685 |
Join-Endpunkt nownexttable |
358 | kein physischer AUTOINCREMENT-Schlüssel |
fastipnownexttable |
0 | keine aktuellen Zeilen |
Die Datenbankdatei wurde dort mit 1.742.053.376 Bytes (ca. 1,62 GiB) protokolliert. Diese Tabelle ist ausdrücklich unvollständig: scheduletable, fvpscheduletable und fvpnownexttable wurden damit nicht gezählt.
- BEWIESEN: AUTOINCREMENT-Werte in Millionenhöhe bei nur wenigen hundert aktuellen Zeilen zeigen massiven historischen Insert/Delete-Churn.
- BEWIESEN: Daraus folgt nicht, dass Millionen Zeilen gleichzeitig noch vorhanden sind, aber ebenso wenig, dass die nicht gemessenen Schedule-/FVP-Tabellen klein sind.
- SEHR WAHRSCHEINLICH: Der defekte Stale-Cleanup kann insbesondere
scheduletableüber lange Zeit mit abgelaufenen Ereignissen anwachsen lassen. - NICHT VERIFIZIERBAR: Der exakte Anteil lebender Schedule-/FVP-Daten, freier Seiten und interner Fragmentierung ohne belastbare Counts beziehungsweise
page_count,freelist_count,dbstatoder eine DB-Kopie.
Die frühere Aussage in epg-content-evidence.txt, der Boot-Log zeige eine erfolgte Löschung, wird durch die statische Bytecode-Analyse korrigiert: Er zeigt nur die Ausführung des No-op-Runnables.
Query-/URI-Semantik und Grenzen einer risikoarmen Zählung
Warum antenna/scheduletable --projection _id sehr lange läuft
BEWIESEN: content://org.droidtv.epgdvb/antenna/scheduletable wird nicht direkt auf die physische Tabelle abgebildet. EpgProvider.query() ersetzt den Tabellenausdruck durch:
indextable AS Dbit LEFT JOIN scheduletable AS Schedule USING(presetid)
Für eine Client-Projektion _id ersetzt der Provider die Spalte ausdrücklich durch Dbit.dbitindex AS _id. Die Abfrage zählt oder limitiert damit nicht, sondern liefert eine Join-Zeile pro passendem Schedule-Datensatz. Eine Laufzeit von mehr als 120 Sekunden ist daher mit einer sehr großen Schedule-Menge vereinbar. Sie kann zusätzlich durch Join-/Provider-/SQLite-Latenz beeinflusst sein und ist allein noch kein exakter Rowcount.
Die physische Tabelle ist auch über antenna/scheduletablesync erreichbar. Dieser Pfad vermeidet den Dbit-Join, besitzt aber ebenfalls keinen eingebauten Count- oder Limit-Modus.
Projektion und Selection
- BEWIESEN: Für
nownexttableundscheduletablebaut der Provider Join-Ausdrücke und schreibt Projektionsnamen mit Unterstrich in qualifizierte Spalten um, zum BeispielSchedule_eventidzuSchedule.eventid AS Schedule_eventid. - BEWIESEN: Die Sonderprojektion
_idwird immer zuDbit.dbitindex AS _id. Das ist bei Join-Endpunkten beabsichtigt, beifvpscheduletableaber ungültig, weil dort kein AliasDbitexistiert. - BEWIESEN:
fvpscheduletableundfvpnownexttablebesitzen schemabedingt keine_id-Spalte; ihr Primärschlüssel ist(channelid,starttime,endtime). - BEWIESEN: Bestimmte Selection-Strings sind keine SQL-Where-Klauseln, sondern Provider-Kommandos:
GetNowNext,GetNowNextNoHidden,GetScheduleundgetFastIpNowNextForChannel. BeiGetSchedulesetzt der Provider selbst die BedingungSchedule_presetid = ? AND Schedule_endtime > ? AND Schedule_starttime < ?und sortiert nachSchedule_starttime. - BEWIESEN: Für die Join-Endpunkte tokenisiert der Provider eine normale Selection an Whitespace und ersetzt Unterstriche in Tokens durch Punkte. Komplexe Ausdrücke sind daher nicht verlässlich transparent.
- BEWIESEN: Zwei Distinct-Temp-XML-AIT-Endpunkte bauen SQL sogar per Stringverkettung auf. Sie sind für die Tabellenzählung nicht relevant und keine empfehlenswerte Diagnosefläche.
Sortierung und Limit
- BEWIESEN: Der fünfte Legacy-Query-Parameter
sortOrderwird zu Beginn nur auf den SonderwertPF_EVENTgeprüft. Dieser Wert löst eine EPG-Sync-Notification aus und liefert keinen Cursor. - BEWIESEN: Der Client-Sortstring wird danach nicht als freie Sortierung an die abschließende SQLite-Abfrage weitergereicht. Einige interne Pfade setzen stattdessen feste Sortierungen (
Dbit_presetnumber,Schedule_starttime,starttime). - BEWIESEN: Der letzte Parameter der verwendeten 8-Argument-Überladung
SQLiteDatabase.query(..., orderBy, limit)wird immer aufnullgesetzt. Es gibt in diesem Provider keinen generischen URI-Queryparameter oder Legacy-Pfad fürLIMIT 1. - BEWIESEN: Ein
LIMITim Sortstring wäre hier nicht nur unerwünschte SQL-Einschleusung, sondern wegen der Providerlogik auch kein belastbarer Weg.
Gibt es einen legitimen Count-Weg?
- BEWIESEN: Der Provider implementiert keinen eigenen Count-Endpunkt, kein
DatabaseUtils.queryNumEntries()und kein festesSELECT COUNT(*)für Schedule/FVP. - NICHT VERIFIZIERBAR: Ob ein Aggregate-Ausdruck wie
COUNT(*) AS row_countals Client-Projektion auf jedem URI akzeptiert wird. Die Provider-Umschreibung verwirft oder verändert Projektionen abhängig vom Pfad; auf dem normalenscheduletable-Join ist dies deshalb kein dokumentierter, verlässlicher Vertrag. - PLAUSIBEL: Die Spezialpfade
antenna/fvpbackwardepg,antenna/fvpnownexttableundantenna/fastipnownexttablereichen Projektionen direkter an SQLite weiter; dort könnte ein Aggregate-Count rein lesend funktionieren. Das ist statisch nicht als Philips-API zugesichert und sollte, falls später überhaupt getestet, nur mit kurzer externer Zeitbegrenzung erfolgen. - BEWIESEN: Ein garantiert maximal einzeiliger, aber nicht zählender Leseweg besteht über eine eindeutige Schlüssel-Selection: bei
scheduletablesync_id = <bekannter Wert>, bei FVP(channelid,starttime,endtime)mit bekannten Werten. Das beantwortet nur Existenz/Einzeldaten, nicht die Gesamtgröße.
Risikoarme weitere Diagnose bedeutet daher: keine unbeschränkte Ausgabe des Schedule-Joins, keine Sort-/Selection-Injection und keine mutierenden URI-Endpunkte. Sinnvoll sind ausschließlich zeitlich eng begrenzte, indexgestützte Leseselektionen auf der physischen scheduletablesync-Tabelle (starttime/endtime) sowie kurz begrenzte Aggregate-Experimente nur dort, wo die Projektion statisch unverändert durchgereicht wird. Ein vollständiger, verlässlicher Tabellen-/Seitenbefund erfordert letztlich SQLite-Metadaten oder eine lesbare DB-Kopie.
Interne Reset-/Rebuild-Flächen
ContentProvider
Manifest-Komponente:
- Klasse:
org.droidtv.channels.epg.bcepg.EpgProvider - Authority:
org.droidtv.epgdvb android:exported="true"- Im Provider-Element ist keine
readPermissionoderwritePermissiondeklariert.
Die folgenden URI-Pfade werden in EpgUriMatcher erkannt. Alle werden über ContentResolver.delete() angestoßen und sind deshalb mutierend; sie wurden nicht ausgeführt.
| URI | Runnable/Funktion | Tatsächliche Wirkung |
|---|---|---|
content://org.droidtv.epgdvb/antenna/staledatacleanup |
EpgProvider$deleteStaleDataRunnable |
derzeit nur Grenzwertberechnung/Log; keine Löschung |
content://org.droidtv.epgdvb/antenna/rebuilddb |
EpgProvider$rebuildDbRunnable |
dropIndexTable(), syncChannelTable(), syncOnChannelTableChange(), Acquisition-Notification; selektiver Reindex/Mapping-Abgleich |
content://org.droidtv.epgdvb/antenna/rebuilddbonnewchannellist |
EpgProvider$rebuildDbOnNewChannelListRunnable |
dropTables(), zusätzlich dropIndexTable(), danach Kanal-/Mapping-Neuaufbau und Notification; umfassende Zeilenleerung der EPG-Ereignistabellen, aber keine Dateikompaktierung |
EpgProgramPump.rebuildEpgDataBase() ruft den regulären rebuilddb-URI über ContentResolver.delete() auf. BEWIESEN: Auch diese Methode hat innerhalb der vier DEX-Dateien keinen direkten Invoke-Aufrufer.
Der tatsächlich verdrahtete interne Rebuild erfolgt in EpgInfoSingleton$MyRunnableHandleMessage.run():
- bei Senderlisten-Update-Ende und Installationsabbruch über
REBUILD_CONTENT_URI(rebuilddb), - bei
CHANNEL_INSTALL_COMPLETEüberREBUILD_ONNEWCHLIST_CONTENT_URI(rebuilddbonnewchannellist).
Das ist ein interner Lifecycle-Pfad der Senderinstallation, keine gefundene Benutzerfunktion zum Freigeben von Speicher.
Manifest-Activities, Services und Intent-Actions
Gefundene, EPG-nahe Benutzerkomponenten sind:
org.droidtv.channels.ChannelsActivity:org.droidtv.action.GUIDE,org.droidtv.action.DUKTPGUIDE,org.droidtv.intent.action.SHOW_PLANNER,org.droidtv.intent.action.CHANLISTorg.droidtv.channels.epg.bcepg.epgui.RecordingsManager:org.droidtv.ACTION.SHOW_RECORDINGS_LISTorg.droidtv.channels.epg.bcepg.epgui.NowNextOverview:org.droidtv.ACTION.SHOW_NOWNEXT_OVERVIEWorg.droidtv.channels.epg.bcepg.epgui.ScheduleReminder:org.droidtv.ACTION.SET_REMINDERorg.droidtv.channels.epg.bcepg.epgui.ScheduleManualRecording:org.droidtv.ACTION.SCHEDULE_MANUAL_RECORDINGorg.droidtv.channels.epg.bcepg.epgui.ScheduleEventRecording:org.droidtv.ACTION.SCHEDULE_EVENT_RECORDINGorg.droidtv.channels.epg.bcepg.epgui.ScheduleRecording:org.droidtv.ACTION.SCHEDULE_RECORDINGorg.droidtv.channels.epg.bcepg.RecordingsUpdateService: Aktionorg.droidtv.bcepg.RecordingsUpdateService, ausdrücklichandroid:exported="false"org.droidtv.channels.epg.search.EPGSearchProvider: Authorityorg.droidtv.channels.epg.search; Suchprovider, kein Reset-Pfad
BEWIESEN: Keine dieser Manifest-Aktionen ist als EPG-Datenbank-Reset implementiert. In Manifest- und Ressourcenquersuche wurde keine Activity, kein Service und kein expliziter Intent mit der Bedeutung „EPG/Guide database reset/clear/rebuild“ gefunden.
EpgStaleDataCleanupAlarmReceiver hat ein Intent-Filter, aber kein explizites android:exported-Attribut. Bei targetSdkVersion=30 ergibt sich auf der untersuchten Plattform aus dem Intent-Filter typischerweise Exportierbarkeit; die genaue vom PackageManager auf diesem Gerät aufgelöste Export-Eigenschaft ist in dieser rein lokalen Teilanalyse NICHT VERIFIZIERBAR. Für den Befund ist dies unerheblich, weil der Empfänger letztlich nur den No-op-Cleanup auslöst.
Quersuche in weiteren lokalen Philips-APKs
BEWIESEN: TPTvService.apk, eum.apk und usagelogger.apk enthalten gemeinsame EPG-Vertragskonstanten für normale EPG-Datenabfragen, aber keine Treffer für rebuilddb, rebuilddbonnewchannellist, staledatacleanup oder EpgDatabase.db. gel.apk, tvstrings.apk und tvwidgets2k15.apk enthalten ebenfalls keinen solchen Aufrufer. Ein Aufrufer aus einem nicht lokal vorliegenden Paket bleibt NICHT VERIFIZIERBAR.
Abhängigkeiten und Risikoabgrenzung
Senderliste
- BEWIESEN: Die kanonische Senderliste liegt außerhalb von
EpgDatabase.db.EpgDatabaseHelper.syncChannelTable()fragtandroid.media.tv.TvContract.Channels.CONTENT_URIab. - BEWIESEN:
indextableist ein EPG-interner Spiegel von Sender-/Presetdaten einschließlichpresetid,presetnumber,svlid,svlrecid, Name,browsableundfavoriteNumber. - BEWIESEN:
mappingtableordnetpresetidzusvlid/svlrecidzu. - BEWIESEN: Die Rebuild-Runnables löschen die kanonische
TvContract.Channels-Tabelle nicht; sie lesen sie und bauen EPG-Index/Mapping neu auf. - NICHT VERIFIZIERBAR: Ob ein konkreter Laufzeitfehler während des Abgleichs zu sichtbaren temporären Kanal-/EPG-Zuordnungsproblemen führen würde.
Favoriten
- BEWIESEN: Favoritenlisten werden über einen separaten Provider
org.droidtv.tv.provider.favoriteangesprochen, unter anderemcontent://org.droidtv.tv.provider.favorite/FavoriteListsowie Mixed-/Terrestrial-/Cable-/Satellite-Listen. - BEWIESEN:
EpgDatabase.dbenthält nur Spiegel-/Versionsfelder (favoriteNumber,favouriteversion), nicht die externen Favoritentabellen selbst. - BEWIESEN: Die EPG-Rebuild-Runnables enthalten keinen direkten Delete-Aufruf gegen den Favoriten-Provider.
- PLAUSIBEL: Der Reindex kann vorübergehend Darstellung oder Zuordnung beeinflussen, bis die Spiegelwerte erneut synchronisiert sind.
Aufnahmen, geplante Aufnahmen, Erinnerungen und Timer
Die persistenten Aufnahme-/Reminder-Daten liegen ebenfalls außerhalb von EpgDatabase.db:
-
Authority:
org.droidtv.playtv.provider.recordremind -
Datenbank:
RecordingsRemindersList.db -
Aufnahmen:
.../RecordingsTable -
Erinnerungen:
.../RemindersTable -
gemeinsame View:
.../RecRemView -
BEWIESEN: Diese Tabellen kommen weder im v6-Schema von
EpgDatabaseHelpernoch indropTables()vor. -
BEWIESEN:
EpgProgramPumpregistriert einenContentObserveraufIRecordingsContract.CONTENT_URI_Recordingsund korreliert Aufnahmen über Felder wieEventIdundChannelId; Methoden wiesyncRecordingDBbyEvent()undRecDynamicEventUpdateHandleraktualisieren Aufnahme-Metadaten bei EPG-Ereignisänderungen. -
BEWIESEN: Ein URI-basierter EPG-Rebuild besitzt keinen direkten Codepfad, der
RecordingsTableoderRemindersTablelöscht. -
NICHT VERIFIZIERBAR: Vollständige Nebenwirkungsfreiheit auf Darstellung, Event-ID-Verknüpfung, Folgeaufnahmen oder Scheduler nach Reakquisition. Das externe Persistieren verhindert nicht, dass neu vergebene Event-/Channel-IDs Beziehungen vorübergehend oder dauerhaft beeinflussen könnten.
TV-Guide-Quelle ist kein sicherer Reset
tvstrings.apk enthält unter anderem die deutsche Warnung:
Wenn Sie zu TV-Guide-Informationen aus dem Internet wechseln, gehen alle Aufnahmen verloren, die Sie mit Informationen der Sendeanstalt aufgenommen haben. Alle Erinnerungen und programmierten Aufnahmen werden abgebrochen.
Die Gegenrichtung warnt ebenfalls vor Verlust von Aufnahmen und Abbruch programmierter Aufnahmen.
- BEWIESEN: Das Umschalten zwischen Broadcaster- und Internet-Guide ist laut Philips-Ressourcen eine ausdrücklich destruktive Benutzeraktion für Aufnahme-/Timerdaten.
- BEWIESEN: Es ist nicht mit den internen
rebuilddb-URI-Pfaden gleichzusetzen und sollte nicht als Speicherbereinigung vorgeschlagen werden.
Gesamteinordnung zur Speicherwarnung
Die statische Implementierung liefert eine konsistente Ursache für die ungewöhnlich große EPG-Datei:
- EPG-Synchronisation erzeugt sehr hohen Insert/Delete-Churn; die hohen AUTOINCREMENT-Werte beweisen Millionen historische Inserts.
- Der als periodischer Stale-Cleanup bezeichnete Kernpfad löscht in dieser Firmware tatsächlich nichts.
- Der sichtbare 12-Stunden-Alarm-Setter hat keinen direkten Caller und wäre selbst bei Ausführung nur ein einmaliger Einstieg in dasselbe wirkungslose Runnable.
- Interne Rebuilds leeren Zeilen, verwenden aber selbst kein
VACUUM; ob ein Vendor-/DB-seitig aktives Full-Auto-Vacuum die Datei dabei verkleinert, ist offen. - Nur Now/Next/Index wurden als klein gemessen. Der unbeschränkte Schedule-Join lief länger als 120 Sekunden; Schedule/FVP können daher einen großen lebenden Datenanteil enthalten.
BEWIESEN: EpgDatabase.db ist mit 1,62 GiB der konkrete große Speicherverbraucher. SEHR WAHRSCHEINLICH: Der defekte Stale-Cleanup trägt wesentlich zu ihrem Wachstum bei, insbesondere durch nicht entfernte Schedule-Daten. NICHT VERIFIZIERBAR: Ob die aktuelle Dateigröße überwiegend aus lebenden Schedule-/FVP-Zeilen oder aus freien/fragmentierten Seiten besteht.
NICHT VERIFIZIERBAR: Der genaue Beitrag eines ungewöhnlichen SQLite-Headerzustands, WAL-/Journalresten oder Dateisystembesonderheiten. Dafür wären ausschließlich weitere lesende Datenbank-/Header-Messungen erforderlich; sie waren nicht Teil dieser lokalen APK-Teilanalyse.
Keine Reparaturfreigabe aus diesem Bericht
Die gefundenen ContentResolver.delete()-Endpunkte und Rebuild-Pfade sind zustandsverändernd. Sie wurden nicht ausgeführt und dieser Bericht empfiehlt keinen konkreten Ausführungsbefehl. Insbesondere ist der umfassende New-Channel-List-Rebuild nicht gleichbedeutend mit einer Dateikompaktierung und eine vollständige Nebenwirkungsfreiheit für EPG-Verknüpfungen zu Aufnahmen/Timern ist nicht bewiesen.
Reproduzierbare Belegdateien
diagnostics/deep-forensics/philips/epg-dex-context.txt– Helper, DDL, Lifecycle, Provider und Query-Joinsdiagnostics/deep-forensics/philips/epg-runnable-context.txt– vollständige Referenzkontexte der Provider-Runnablesdiagnostics/deep-forensics/philips/epg-cleanup-context.txt– Cleanup- und echte Delete-Methodendiagnostics/deep-forensics/philips/epg-stale-context.txt– Alarm-/Receiver-/URI-Kettediagnostics/deep-forensics/philips/epg-sync-thread-context.txt– SyncThread-Methodendiagnostics/deep-forensics/philips/epg-recording-deps-context.txt– Aufnahme-/Reminder-Verträge und Interaktionendiagnostics/deep-forensics/philips/epg-delete-rebuild-string-context.txt– interne Rebuild-Auslösung bei Senderlistenereignissendiagnostics/deep-forensics/philips/channels-manifest.txt– dekodiertes binäres Manifestdiagnostics/deep-forensics/philips/tvstrings-epg-matches.txt– relevante TV-Guide-Ressourcendiagnostics/raw/storage/epg-content-evidence.txt– bereits vorhandene Laufzeit-Zeilenzahlen/IDs/Dateigrößediagnostics/bugreport/extracted/files/01790__bugreport-PH9M_EA_5599-STT2.230526.001-2026-08-25-13-26-44.txt– Boot-Log, insbesondere Zeilen um 32807–32812