From 213c4a2f1324d2105f464da21c0e14c0a7845465 Mon Sep 17 00:00:00 2001 From: KOWX712 Date: Sat, 23 Nov 2024 21:22:23 +0800 Subject: [PATCH] Optimize + set verified boot hash in WebUI Reduce load time by preload applist in service.sh. New function in WebUI: set verified boot hash in WebUI --- module/service.sh | 13 +++++ module/webroot/index.html | 15 +++++ module/webroot/index.js | 117 +++++++++++++++++++++++++++++++------- module/webroot/styles.css | 76 +++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 19 deletions(-) diff --git a/module/service.sh b/module/service.sh index 8ee0d43..a4fc8d0 100644 --- a/module/service.sh +++ b/module/service.sh @@ -1,8 +1,11 @@ MODPATH=${0%/*} +OUTPUT="$MODPATH/common/applist" TS="/data/adb/modules/tricky_store" SCRIPT_DIR="/data/adb/tricky_store" TSPA="/data/adb/modules/tsupport-advance" +aapt() { "$MODPATH/common/aapt" "$@"; } + hash_value=$(grep -v '^#' "/data/adb/boot_hash" | tr -d '[:space:]') if [ -n "$hash_value" ]; then resetprop -n ro.boot.vbmeta.digest "$hash_value" @@ -35,5 +38,15 @@ else until [ "$(getprop sys.boot_completed)" = "1" ]; do sleep 1 done + > "$OUTPUT" + pm list packages -3 | awk -F: '{print $2}' | while read -r PACKAGE; do + APK_PATH=$(pm path "$PACKAGE" | grep "base.apk" | awk -F: '{print $2}' | tr -d '\r') + if [ -n "$APK_PATH" ]; then + APP_NAME=$(aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://g; s/'//g") + echo "app-name: $APP_NAME, package-name: $PACKAGE" >> "$OUTPUT" + else + echo "app-name: Unknown App package-name: $PACKAGE" >> "$OUTPUT" + fi + done . "$SCRIPT_DIR/UpdateTargetList.sh" fi \ No newline at end of file diff --git a/module/webroot/index.html b/module/webroot/index.html index 135b895..3b7af45 100644 --- a/module/webroot/index.html +++ b/module/webroot/index.html @@ -73,6 +73,13 @@

  • +
  • Set Verified Boot Hash + +
  • @@ -97,6 +104,7 @@
  • Deselect Unnecessary
  • Set AOSP Keybox
  • Set Valid Keybox
  • +
  • Set Verified Boot Hash
  • @@ -113,6 +121,13 @@ +
    +
    + +
    + +
    +
    Loading...
    Credit to j-hc/zygisk-detach WebUI
    diff --git a/module/webroot/index.js b/module/webroot/index.js index a33eef7..ef6882d 100644 --- a/module/webroot/index.js +++ b/module/webroot/index.js @@ -60,28 +60,54 @@ function isExcluded(appName) { async function fetchAppList() { try { await readExcludeFile(); - const result = await execCommand(` - pm list packages -3 | while read -r line; do - PACKAGE=$(echo "$line" | awk -F: '{print $2}') - APK_PATH=$(pm path "$PACKAGE" | grep "base.apk" | awk -F: '{print $2}' | tr -d '\\r') - if [ -n "$APK_PATH" ]; then - APP_NAME=$( ${basePath}aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g" ) - echo "$APP_NAME|$PACKAGE" - else - echo "Unknown App|$PACKAGE" - fi - done - `); - const appEntries = result.split("\n").map(line => { - const [appName, packageName] = line.split("|").map(item => item.trim()); - return { appName, packageName }; - }).filter(entry => entry.packageName); // Remove invalid entries + let applistMap = {}; + try { + const applistResult = await execCommand(`cat ${basePath}applist`); + applistMap = applistResult + .split("\n") + .reduce((map, line) => { + const match = line.match(/app-name:\s*(.+),\s*package-name:\s*(.+)/); + if (match) { + const appName = match[1].trim(); + const packageName = match[2].trim(); + map[packageName] = appName; + } + return map; + }, {}); + console.log("Applist loaded successfully."); + } catch (error) { + console.warn("Applist file not found or could not be loaded. Skipping applist lookup."); + } + const result = await execCommand("pm list packages -3"); + const appEntries = result + .split("\n") + .map(line => { + const packageName = line.replace("package:", "").trim(); + const appName = applistMap[packageName] || null; + return { appName, packageName }; + }) + .filter(entry => entry.packageName); + for (const entry of appEntries) { + if (!entry.appName) { + try { + const apkPath = await execCommand(`pm path ${entry.packageName} | grep "base.apk" | awk -F: '{print $2}' | tr -d '\\r'`); + if (apkPath) { + const appName = await execCommand(`${basePath}aapt dump badging ${apkPath.trim()} 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g"`); + entry.appName = appName.trim() || "Unknown App"; + } else { + entry.appName = "Unknown App"; + } + } catch (error) { + entry.appName = "Unknown App"; + } + } + } const sortedApps = appEntries.sort((a, b) => { const aInExclude = isExcluded(a.packageName); const bInExclude = isExcluded(b.packageName); return aInExclude === bInExclude ? a.appName.localeCompare(b.appName) : aInExclude ? 1 : -1; }); - appListContainer.innerHTML = ""; // Clear the container before rendering + appListContainer.innerHTML = ""; sortedApps.forEach(({ appName, packageName }) => { const appElement = document.importNode(appTemplate, true); const contentElement = appElement.querySelector(".content"); @@ -96,7 +122,6 @@ async function fetchAppList() { } catch (error) { console.error("Failed to fetch or render app list with names:", error); } - floatingBtn.style.transform = "translateY(-100px)"; } @@ -252,6 +277,59 @@ async function extrakb() { } } +// Function to handle Verified Boot Hash +async function setBootHash() { + const overlay = document.getElementById("overlay"); + const card = document.getElementById("boot-hash-card"); + const inputBox = document.getElementById("boot-hash-input"); + const saveButton = document.getElementById("save-button"); + const showCard = () => { + overlay.style.display = "flex"; + card.style.display = "flex"; + requestAnimationFrame(() => { + overlay.classList.add("show"); + card.classList.add("show"); + }); + document.body.style.overflow = "hidden"; + }; + const closeCard = () => { + overlay.classList.remove("show"); + card.classList.remove("show"); + setTimeout(() => { + overlay.style.display = "none"; + card.style.display = "none"; + document.body.style.overflow = "auto"; + }, 200); + }; + showCard(); + try { + const bootHashContent = await execCommand("cat /data/adb/boot_hash"); + const validHash = bootHashContent + .split("\n") + .filter(line => !line.startsWith("#") && line.trim())[0]; + inputBox.value = validHash || ""; + } catch (error) { + console.warn("Failed to read boot_hash file. Defaulting to empty input."); + inputBox.value = ""; + } + // Save button click handler + saveButton.addEventListener("click", async () => { + const inputValue = inputBox.value.trim(); + try { + await execCommand(`echo "${inputValue}" > /data/adb/boot_hash`); + await execCommand(`su -c resetprop -n ro.boot.vbmeta.digest ${inputValue}`); + showPrompt("Verified Boot Hash saved successfully."); + closeCard(); + } catch (error) { + console.error("Failed to update boot_hash:", error); + showPrompt("Failed to update Verified Boot Hash.", false); + } + }); + overlay.addEventListener("click", (event) => { + if (event.target === overlay) closeCard(); + }); +} + // Function to show the prompt with a success or error message function showPrompt(message, isSuccess = true) { const prompt = document.getElementById('prompt'); @@ -300,7 +378,7 @@ function setupMenuToggle() { } }); - const closeMenuItems = ['refresh', 'select-all', 'deselect-all', 'select-denylist', 'deselect-unnecessary', 'aospkb', 'extrakb']; + const closeMenuItems = ['refresh', 'select-all', 'deselect-all', 'select-denylist', 'deselect-unnecessary', 'aospkb', 'extrakb', 'boot-hash']; closeMenuItems.forEach(id => { const item = document.getElementById(id); if (item) { @@ -427,6 +505,7 @@ document.addEventListener('DOMContentLoaded', async () => { document.getElementById("deselect-unnecessary").addEventListener("click", deselectUnnecessaryApps); document.getElementById("aospkb").addEventListener("click", aospkb); document.getElementById("extrakb").addEventListener("click", extrakb); + document.getElementById("boot-hash").addEventListener("click", setBootHash); await fetchAppList(); checkMagisk(); runExtraScript(); diff --git a/module/webroot/styles.css b/module/webroot/styles.css index 91c7325..8b69458 100644 --- a/module/webroot/styles.css +++ b/module/webroot/styles.css @@ -128,6 +128,79 @@ body { color: inherit; } +.overlay { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.5); + z-index: 1000; + justify-content: center; + align-items: center; + opacity: 0; + visibility: hidden; + transition: opacity 0.2s ease, visibility 0.2s ease; +} + +.boot-hash-card { + position: fixed; + top: 30%; + left: 50%; + transform: translate(-50%, -50%); + width: 80vw; + max-width: 600px; + background-color: #fff; + border-radius: 18px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); + z-index: 1100; + padding: 20px; + display: none; + flex-direction: column; + gap: 15px; + opacity: 0; + transition: opacity 0.2s ease; +} + +.overlay.show { + visibility: visible; + opacity: 1; +} + +.boot-hash-card.show { + display: flex; + opacity: 1; +} + +.input-box { + width: calc(100% - 23px); + height: 100px; + resize: none; + padding: 10px; + font-size: 16px; + background-color: #FFF; + border: 1px solid #ccc; + border-radius: 10px; +} + +.button-container { + display: flex; + justify-content: flex-start; +} + +.button { + padding: 10px 20px; + border: none; + border-radius: 38px; + font-size: 18px; +} + +.save-button { + background-color: #007bff; + color: white; + margin-left: auto; +} + #apps-list { margin-top: 100px; } @@ -397,11 +470,13 @@ body { background-color: #121212; } + .input-box, .help-button { color: #fff; } .help-menu, + .boot-hash-card, .card, .search-input, .search-card { @@ -416,6 +491,7 @@ body { color: white; } + .input-box, .menu-options, #menu-button { background-color: #343434;