/* What OUR package has in the shade right now: the channels its live * notifications sit on, and the downloads one's own title and text. * `--noredact` is what makes the extras print their values rather than a * placeholder. Nobody else's notifications are read — `seen` counts the * dump's records only so that "no downloads channel" cannot pass by the * dump having come back empty. */ function shadeNotice() { try { const dump = adb("shell", "dumpsys", "notification", "--noredact").toString(); const blocks = dump.split("NotificationRecord(").slice(1); const chans = []; let title = "", text = ""; for (const block of blocks) { const head = block.slice(0, 6000); if (!/pkg=com\.soulstream\.app\b/.test(head)) continue; /* Notification.toString() carries `channel=` on the record's own first line; older dumps spell it as the channel object */ let ch = (head.match(/channel=([\w.\-]+)/) || [])[1] || ""; if (!ch || ch === "NotificationChannel") ch = (head.match(/mId='([^']*)'/) || [])[1] || ch; if (ch) chans.push(ch); if (ch !== "downloads") continue; /* the extras print as `= ()`, and the class is whatever CharSequence the builder kept — String on this one, but a Spannable on a device that styles it, so the class is matched loosely and stray quotes are trimmed */ const extra = (key) => { const m = head.match(new RegExp(key.replace(/\./g, "\\.") + "=[A-Za-z]+ \\(([^\\n]*?)\\)\\s*\\n")); return m ? m[1].replace(/^"|"$/g, "") : ""; }; title = extra("android.title"); text = extra("android.text"); } return { shadeSeen: blocks.length, shadeChans: chans.join("|"), shadeTitle: title, shadeText: text }; } catch (e) { return { shadeSeen: 0, shadeChans: "ERR " + e.message, shadeTitle: "", shadeText: "" }; } }