diff --git a/.gitignore b/.gitignore
index c5439f6..f649533 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
__MACOSX
.DS_Store
+applist.json
\ No newline at end of file
diff --git a/module/service.sh b/module/service.sh
index d264ee6..b073f51 100644
--- a/module/service.sh
+++ b/module/service.sh
@@ -78,7 +78,7 @@ if [ ! -d "$TS/webroot" ] && [ ! -L "$TS/webroot" ]; then
fi
# Optimization
-OUTPUT_APP="$MODPATH/common/tmp/applist"
+OUTPUT_APP="$MODPATH/webui/applist.json"
OUTPUT_SKIP="$MODPATH/common/tmp/skiplist"
OUTPUT_XPOSED="$MODPATH/common/tmp/xposed"
@@ -97,7 +97,7 @@ else
fi
# Initialize cache files to save app list and skip list
-echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT_APP"
+echo "[" > "$OUTPUT_APP"
echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT_SKIP"
# Get list of third party apps and specific system apps, then cache app name
@@ -107,16 +107,12 @@ echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT
pm list packages -s | grep -E "$SYSTEM_APP" 2>/dev/null || true
} | awk -F: '{print $2}' | while read -r PACKAGE; do
# Get APK path for the package
- APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep "base.apk" | awk -F: '{print $2}' | tr -d '\r')
- [ -z "$APK_PATH" ] && APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep ".apk" | awk -F: '{print $2}' | tr -d '\r')
+ APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep "base.apk" | awk -F: '{print $2}')
+ [ -z "$APK_PATH" ] && APK_PATH=$(pm path "$PACKAGE" 2>/dev/null | grep ".apk" | awk -F: '{print $2}')
- if [ -n "$APK_PATH" ]; then
- # Extract app name and save package info
- 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_APP"
- else
- echo "app-name: Unknown App package-name: $PACKAGE" >> "$OUTPUT_APP"
- fi
+ APP_NAME=$(aapt dump badging "$APK_PATH" 2>/dev/null | grep "application-label:" | sed "s/application-label://g; s/'//g")
+ [ -z "$APP_NAME" ] && APP_NAME="$PACKAGE"
+ echo " {\"app_name\": \"$APP_NAME\", \"package_name\": \"$PACKAGE\"}," >> "$OUTPUT_APP"
# Check if app is Xposed module and add to skip list if not
touch "$OUTPUT_XPOSED"
@@ -126,3 +122,6 @@ echo "# This file is generated from service.sh to speed up load time" > "$OUTPUT
echo "$PACKAGE" >> "$OUTPUT_SKIP"
fi
done
+
+sed -i '$ s/,$//' "$OUTPUT_APP"
+echo "]" >> "$OUTPUT_APP"
diff --git a/module/webui/index.html b/module/webui/index.html
index 6a6d58d..704a2ee 100644
--- a/module/webui/index.html
+++ b/module/webui/index.html
@@ -105,29 +105,29 @@
diff --git a/module/webui/scripts/applist.js b/module/webui/scripts/applist.js
index 4f693f3..a61b2df 100644
--- a/module/webui/scripts/applist.js
+++ b/module/webui/scripts/applist.js
@@ -9,6 +9,7 @@ export let modeActive = false;
// Fetch and render applist
export async function fetchAppList() {
try {
+ // fetch target list
let targetList = [];
try {
const targetFileContent = await execCommand('cat /data/adb/tricky_store/target.txt');
@@ -19,56 +20,46 @@ export async function fetchAppList() {
console.error("Failed to read target.txt file:", error);
}
+ // fetch applist
let applistMap = {};
- try {
- const applistResult = await execCommand(`cat ${basePath}common/tmp/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 response = await fetch('applist.json');
+ const appList = await response.json();
+ const appNameMap = appList.reduce((map, app) => {
+ map[app.package_name] = app.app_name;
+ return map;
+ }, {});
- const result = await execCommand(`
- pm list packages -3 | awk -F: '{print $2}'
- [ -f "/data/adb/tricky_store/system_app" ] && SYSTEM_APP=$(cat "/data/adb/tricky_store/system_app" | tr '\n' '|' | sed 's/|*$//') || SYSTEM_APP=""
- pm list packages -s | awk -F: '{print $2}' | grep -Ex "$SYSTEM_APP" 2>/dev/null || true
- `);
- const appEntries = result
- .split("\n")
- .map(line => {
- const packageName = line.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(`
- base_apk=$(pm path ${entry.packageName} | grep "base.apk" | awk -F: '{print $2}' | tr -d '\\r')
- [ -n "$base_apk" ] || base_apk=$(pm path ${entry.packageName} | grep ".apk" | awk -F: '{print $2}' | tr -d '\\r')
- echo "$base_apk"
- `);
- if (apkPath) {
- const appName = await execCommand(`${basePath}common/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";
+ // Get installed packages first
+ let appEntries = [], installedPackages = [];
+ try {
+ installedPackages = await execCommand(`
+ pm list packages -3 | awk -F: '{print $2}'
+ [ -s "/data/adb/tricky_store/system_app" ] && SYSTEM_APP=$(cat "/data/adb/tricky_store/system_app" | tr '\n' '|' | sed 's/|*$//') || SYSTEM_APP=""
+ [ -z "$SYSTEM_APP" ] || pm list packages -s | awk -F: '{print $2}' | grep -Ex "$SYSTEM_APP" 2>/dev/null || true
+ `)
+ installedPackages = installedPackages.split("\n").map(line => line.trim()).filter(Boolean);
+ appEntries = await Promise.all(installedPackages.map(async packageName => {
+ if (appNameMap[packageName]) {
+ return {
+ appName: appNameMap[packageName],
+ packageName
+ };
}
- }
+ const appName = await execCommand(`
+ base_apk=$(pm path ${packageName} | grep "base.apk" | awk -F: '{print $2}')
+ [ -n "$base_apk" ] || base_apk=$(pm path ${packageName} | grep ".apk" | awk -F: '{print $2}')
+ ${basePath}common/aapt dump badging $base_apk 2>/dev/null | grep "application-label:" | sed "s/application-label://; s/'//g"
+ `);
+ return {
+ appName: appName.trim() || packageName,
+ packageName
+ };
+ }));
+ } catch (error) {
+ appEntries = appList.map(app => ({
+ appName: app.app_name,
+ packageName: app.package_name
+ }));
}
// Sort
@@ -108,7 +99,12 @@ export async function fetchAppList() {
}
const nameElement = appElement.querySelector(".name");
- nameElement.innerHTML = `
${appName || "Unknown App"}${packageName}`;
+ nameElement.innerHTML = `
+
+
${appName}
+
${packageName}
+
+ `;
const checkbox = appElement.querySelector(".checkbox");
checkbox.checked = targetList.includes(packageName);
appListContainer.appendChild(appElement);