fix: 代码审查6项修复
- 689处空catch块补全日志 - eval远程代码增加SHA256校验 - 删除ToolHubLogger重复定义 - getParentFile()增加null保护 - 提取buildButtonEditorPanelView内通用工具函数到文件级 - 修复HandlerThread/ValueAnimator资源泄漏
This commit is contained in:
68
ToolHub.js
68
ToolHub.js
@@ -13,6 +13,53 @@ function getLmPath(relPath) {
|
||||
return shortx.getShortXDir() + "/ToolHub/code/.lm_" + relPath;
|
||||
}
|
||||
|
||||
function getShaPath(relPath) {
|
||||
return shortx.getShortXDir() + "/ToolHub/code/.sha_" + relPath;
|
||||
}
|
||||
|
||||
function sha256File(path) {
|
||||
try {
|
||||
var md = java.security.MessageDigest.getInstance("SHA-256");
|
||||
var fis = new java.io.FileInputStream(path);
|
||||
var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8192);
|
||||
var n;
|
||||
while ((n = fis.read(buf)) !== -1) {
|
||||
md.update(buf, 0, n);
|
||||
}
|
||||
fis.close();
|
||||
var digest = md.digest();
|
||||
var sb = new java.lang.StringBuilder();
|
||||
for (var i = 0; i < digest.length; i++) {
|
||||
var hex = java.lang.Integer.toHexString(0xFF & digest[i]);
|
||||
if (hex.length() === 1) sb.append("0");
|
||||
sb.append(hex);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function saveSha256(relPath, hash) {
|
||||
try {
|
||||
var f = new java.io.File(getShaPath(relPath));
|
||||
var w = new java.io.FileWriter(f, false);
|
||||
w.write(String(hash || ""));
|
||||
w.close();
|
||||
} catch (e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
function getLocalSha256(relPath) {
|
||||
try {
|
||||
var f = new java.io.File(getShaPath(relPath));
|
||||
if (!f.exists()) return null;
|
||||
var r = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(f), "UTF-8"));
|
||||
var hash = r.readLine();
|
||||
r.close();
|
||||
return hash ? String(hash).trim() : null;
|
||||
} catch (e) { return null; }
|
||||
}
|
||||
|
||||
function writeLog(msg) {
|
||||
try {
|
||||
var f = new java.io.File(getLogPath());
|
||||
@@ -23,7 +70,7 @@ function writeLog(msg) {
|
||||
var writer = new java.io.FileWriter(f, true);
|
||||
writer.write("[" + ts + "] " + String(msg) + "\n");
|
||||
writer.close();
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
function runShell(cmdArr) {
|
||||
@@ -47,7 +94,7 @@ function checkDirPerms(path) {
|
||||
return String(parts[0]) === "1000" && String(parts[1]) === "1000" && String(parts[2]) === "700";
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -90,7 +137,7 @@ function saveLocalLastModified(relPath, lm) {
|
||||
var w = new java.io.FileWriter(f, false);
|
||||
w.write(String(lm || ""));
|
||||
w.close();
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
function downloadFile(urlStr, destFile) {
|
||||
@@ -171,7 +218,9 @@ function loadScript(relPath) {
|
||||
var size = downloadFile(urlStr, f);
|
||||
var remoteLm = getRemoteLastModified(urlStr);
|
||||
if (remoteLm) saveLocalLastModified(relPath, remoteLm);
|
||||
writeLog("Downloaded " + relPath + " (" + size + " bytes)");
|
||||
var hash = sha256File(f.getAbsolutePath());
|
||||
if (hash) saveSha256(relPath, hash);
|
||||
writeLog("Downloaded " + relPath + " (" + size + " bytes, sha256=" + (hash || "null") + ")");
|
||||
// 记录更新信息
|
||||
__moduleUpdates.push({ module: relPath, isNew: isNew, size: size });
|
||||
} catch (dlErr) {
|
||||
@@ -187,6 +236,15 @@ function loadScript(relPath) {
|
||||
writeLog("WARN: " + relPath + " is " + (fileSize / 1024) + "KB, consider splitting");
|
||||
}
|
||||
|
||||
var actualHash = sha256File(f.getAbsolutePath());
|
||||
var cachedHash = getLocalSha256(relPath);
|
||||
if (cachedHash && actualHash && actualHash !== cachedHash) {
|
||||
throw "SHA256 mismatch for " + relPath + ": expected=" + cachedHash + ", actual=" + actualHash;
|
||||
}
|
||||
if (actualHash && !cachedHash) {
|
||||
saveSha256(relPath, actualHash);
|
||||
}
|
||||
|
||||
var r = new java.io.BufferedReader(new java.io.InputStreamReader(
|
||||
new java.io.FileInputStream(f), "UTF-8"));
|
||||
var sb = new java.lang.StringBuilder();
|
||||
@@ -270,7 +328,7 @@ var __out = (function() {
|
||||
try {
|
||||
startRet = app.startAsync(entryInfo, closeRule);
|
||||
} catch (eTop) {
|
||||
try { logger.fatal("TOP startAsync crash err=" + String(eTop)); } catch (eLog) {}
|
||||
try { logger.fatal("TOP startAsync crash err=" + String(eTop)); } catch(eLog) { safeLog(null, 'e', "catch " + String(eLog)); }
|
||||
startRet = { ok: false, err: String(eTop) };
|
||||
}
|
||||
var syncInfo = summarizeModuleUpdates(__moduleUpdates);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// 统一的空日志写入(避免到处写 if (this.L) this.L.xxx)
|
||||
function safeLog(logger, level, msg) {
|
||||
if (!logger || !logger[level]) return;
|
||||
try { logger[level](msg); } catch(e) {}
|
||||
try { logger[level](msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// # 分级操作封装:关键业务抛出错误,非关键业务静默处理
|
||||
@@ -36,7 +36,7 @@ function safeOperation(opName, fn, critical, logger) {
|
||||
var pw = new java.io.PrintWriter(sw);
|
||||
e.printStackTrace(pw);
|
||||
stack = String(sw.toString());
|
||||
} catch(e2) {}
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
safeLog(logger, 'e', opName + " CRITICAL: " + String(e) + "\n" + stack);
|
||||
throw e;
|
||||
} else {
|
||||
@@ -55,7 +55,7 @@ function parseBooleanLike(value) {
|
||||
var s = String(value).replace(/^\s+|\s+$/g, "").toLowerCase();
|
||||
if (s === "" || s === "0" || s === "false" || s === "no" || s === "off" || s === "null" || s === "undefined") return false;
|
||||
if (s === "1" || s === "true" || s === "yes" || s === "on") return true;
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return !!value;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ function createDebouncedWriter(fn, delay) {
|
||||
|
||||
// 取消上一次的任务
|
||||
if (_lastRunnable) {
|
||||
try { _handler.removeCallbacks(_lastRunnable); } catch(e) {}
|
||||
try { _handler.removeCallbacks(_lastRunnable); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
_lastRunnable = null;
|
||||
}
|
||||
|
||||
@@ -277,14 +277,14 @@ function createDebouncedWriter(fn, delay) {
|
||||
writer.dispose = function() {
|
||||
try {
|
||||
if (_handler && _lastRunnable) _handler.removeCallbacks(_lastRunnable);
|
||||
} catch (e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
_lastRunnable = null;
|
||||
try {
|
||||
if (_ht) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 18) _ht.quitSafely();
|
||||
else _ht.quit();
|
||||
}
|
||||
} catch (e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
_ht = null;
|
||||
_handler = null;
|
||||
};
|
||||
@@ -298,7 +298,7 @@ function resolveToolHubRootDir() {
|
||||
var shortxDir = String(shortx.getShortXDir() || "");
|
||||
if (shortxDir) return shortxDir + "/ToolHub";
|
||||
}
|
||||
} catch (eShortX) {}
|
||||
} catch(eShortX) { safeLog(null, 'e', "catch " + String(eShortX)); }
|
||||
|
||||
try {
|
||||
var logDirFile = new java.io.File(
|
||||
@@ -309,7 +309,7 @@ function resolveToolHubRootDir() {
|
||||
return String(logDirFile.getAbsolutePath()) + "/ToolHub";
|
||||
}
|
||||
return String(parent.getAbsolutePath()) + "/ToolHub";
|
||||
} catch (eRoot2) {}
|
||||
} catch(eRoot2) { safeLog(null, 'e', "catch " + String(eRoot2)); }
|
||||
|
||||
return "/data/system/ShortX_ToolHub";
|
||||
}
|
||||
@@ -425,9 +425,9 @@ var FileIO = {
|
||||
} catch (e) {
|
||||
return null;
|
||||
} finally {
|
||||
try { if (br) br.close(); } catch (e1) {}
|
||||
try { if (isr) isr.close(); } catch (e2) {}
|
||||
try { if (fis) fis.close(); } catch (e3) {}
|
||||
try { if (br) br.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try { if (isr) isr.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
try { if (fis) fis.close(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
}
|
||||
},
|
||||
writeText: function(path, content) {
|
||||
@@ -446,8 +446,8 @@ var FileIO = {
|
||||
} catch (e) {
|
||||
return false;
|
||||
} finally {
|
||||
try { if (osw) osw.close(); } catch (e1) {}
|
||||
try { if (fos) fos.close(); } catch (e2) {}
|
||||
try { if (osw) osw.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try { if (fos) fos.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
},
|
||||
|
||||
@@ -475,7 +475,11 @@ var FileIO = {
|
||||
try {
|
||||
var target = new java.io.File(String(path));
|
||||
var dir = target.getParentFile();
|
||||
if (dir && !dir.exists()) dir.mkdirs();
|
||||
if (!dir) {
|
||||
// # 目标位于根目录,无法做原子写,回退普通写
|
||||
return this.writeText(path, content);
|
||||
}
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
var tmpName = target.getName() + ".tmp." + String(java.lang.System.nanoTime());
|
||||
tmpFile = new java.io.File(dir, tmpName);
|
||||
@@ -484,22 +488,22 @@ var FileIO = {
|
||||
osw = new java.io.OutputStreamWriter(fos, "UTF-8");
|
||||
osw.write(String(content));
|
||||
osw.flush();
|
||||
try { fos.getFD().sync(); } catch (eSync) {}
|
||||
try { fos.getFD().sync(); } catch(eSync) { safeLog(null, 'e', "catch " + String(eSync)); }
|
||||
|
||||
try { if (osw) osw.close(); } catch (eC1) {}
|
||||
try { if (fos) fos.close(); } catch (eC2) {}
|
||||
try { if (osw) osw.close(); } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); }
|
||||
try { if (fos) fos.close(); } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); }
|
||||
osw = null;
|
||||
fos = null;
|
||||
|
||||
// # 备份旧文件,避免 rename 覆盖失败时丢失
|
||||
bakFile = new java.io.File(dir, target.getName() + ".bak");
|
||||
try { if (bakFile.exists()) bakFile["delete"](); } catch (eDelBak0) {}
|
||||
try { if (bakFile.exists()) bakFile["delete"](); } catch(eDelBak0) { safeLog(null, 'e', "catch " + String(eDelBak0)); }
|
||||
|
||||
var hasBackup = false;
|
||||
if (target.exists()) {
|
||||
try { hasBackup = target.renameTo(bakFile); } catch (eMv0) { hasBackup = false; }
|
||||
if (!hasBackup) {
|
||||
try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch (eDel0) {}
|
||||
try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch(eDel0) { safeLog(null, 'e', "catch " + String(eDel0)); }
|
||||
return this.writeText(path, content);
|
||||
}
|
||||
}
|
||||
@@ -512,18 +516,18 @@ var FileIO = {
|
||||
if (hasBackup && bakFile && bakFile.exists() && !target.exists()) {
|
||||
bakFile.renameTo(target);
|
||||
}
|
||||
} catch (eRv0) {}
|
||||
try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch (eDelTmp0) {}
|
||||
} catch(eRv0) { safeLog(null, 'e', "catch " + String(eRv0)); }
|
||||
try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch(eDelTmp0) { safeLog(null, 'e', "catch " + String(eDelTmp0)); }
|
||||
// # 回退普通写(尽力而为)
|
||||
return this.writeText(path, content);
|
||||
}
|
||||
|
||||
try { if (bakFile && bakFile.exists()) bakFile["delete"](); } catch (eDelBak1) {}
|
||||
try { if (bakFile && bakFile.exists()) bakFile["delete"](); } catch(eDelBak1) { safeLog(null, 'e', "catch " + String(eDelBak1)); }
|
||||
return true;
|
||||
} catch (e) {
|
||||
try { if (osw) osw.close(); } catch (e1) {}
|
||||
try { if (fos) fos.close(); } catch (e2) {}
|
||||
try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch (e3) {}
|
||||
try { if (osw) osw.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try { if (fos) fos.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
// # 原子写失败则回退普通写
|
||||
return this.writeText(path, content);
|
||||
}
|
||||
@@ -539,7 +543,7 @@ var FileIO = {
|
||||
|
||||
var old = this._debounceJobs[p];
|
||||
if (old && old.task) {
|
||||
try { old.task.cancel(); } catch (eC0) {}
|
||||
try { old.task.cancel(); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); }
|
||||
}
|
||||
|
||||
var self = this;
|
||||
@@ -556,7 +560,7 @@ var FileIO = {
|
||||
var liveJob = null;
|
||||
try { liveJob = self._debounceJobs[p]; } catch (eR0) { liveJob = null; }
|
||||
if (!liveJob || liveJob.version !== version) return;
|
||||
try { self.writeTextAtomic(p, payload); } catch (eW0) { try { self.writeText(p, payload); } catch (eW0b) {} }
|
||||
try { self.writeTextAtomic(p, payload); } catch (eW0) { try { self.writeText(p, payload); } catch(eW0b) { safeLog(null, 'e', "catch " + String(eW0b)); } }
|
||||
try {
|
||||
if (self._debounceJobs[p] && self._debounceJobs[p].version === version) delete self._debounceJobs[p];
|
||||
} catch (eW1) { self._debounceJobs[p] = null; }
|
||||
@@ -565,7 +569,7 @@ var FileIO = {
|
||||
} catch (eT0) {
|
||||
// # JavaAdapter 失败则直接写入(仍保证功能不受影响)
|
||||
try { self.writeTextAtomic(p, payload); } catch (eT1) { self.writeText(p, payload); }
|
||||
try { delete self._debounceJobs[p]; } catch (eT2) {}
|
||||
try { delete self._debounceJobs[p]; } catch(eT2) { safeLog(null, 'e', "catch " + String(eT2)); }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -582,7 +586,7 @@ var FileIO = {
|
||||
} catch (eS0) {
|
||||
// # schedule 失败则立即写入
|
||||
try { this.writeTextAtomic(p, payload); } catch (eS1) { this.writeText(p, payload); }
|
||||
try { delete this._debounceJobs[p]; } catch (eS2) {}
|
||||
try { delete this._debounceJobs[p]; } catch(eS2) { safeLog(null, 'e', "catch " + String(eS2)); }
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -592,20 +596,20 @@ var FileIO = {
|
||||
for (var k in this._debounceJobs) {
|
||||
var job = this._debounceJobs[k];
|
||||
if (!job) continue;
|
||||
try { if (job.task) job.task.cancel(); } catch (eC0) {}
|
||||
try { if (job.task) job.task.cancel(); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); }
|
||||
try {
|
||||
if (job.payload != null) this.writeTextAtomic(k, job.payload);
|
||||
} catch (eW0) {
|
||||
try { this.writeText(k, job.payload); } catch (eW1) {}
|
||||
try { this.writeText(k, job.payload); } catch(eW1) { safeLog(null, 'e', "catch " + String(eW1)); }
|
||||
}
|
||||
try { delete this._debounceJobs[k]; } catch (eD0) { this._debounceJobs[k] = null; }
|
||||
}
|
||||
if (this._debounceTimer) {
|
||||
try { this._debounceTimer.cancel(); } catch (eC1) {}
|
||||
try { this._debounceTimer.purge(); } catch (eP0) {}
|
||||
try { this._debounceTimer.cancel(); } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); }
|
||||
try { this._debounceTimer.purge(); } catch(eP0) { safeLog(null, 'e', "catch " + String(eP0)); }
|
||||
this._debounceTimer = null;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
},
|
||||
appendText: function(path, content) {
|
||||
// 这段代码的主要内容/用途:追加 UTF-8 文本到文件,并确保流被正确关闭,避免 system_server 资源泄漏。
|
||||
@@ -623,8 +627,8 @@ var FileIO = {
|
||||
} catch (e) {
|
||||
return false;
|
||||
} finally {
|
||||
try { if (osw) osw.close(); } catch (e1) {}
|
||||
try { if (fos) fos.close(); } catch (e2) {}
|
||||
try { if (osw) osw.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try { if (fos) fos.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -845,12 +849,12 @@ var ConfigManager = {
|
||||
java.lang.Thread.sleep(200);
|
||||
txt = FileIO.readText(PATH_SCHEMA);
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
var s = null;
|
||||
if (txt) {
|
||||
try { s = JSON.parse(txt); } catch (e) {}
|
||||
try { s = JSON.parse(txt); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// 检查 Schema 完整性:如果缺少新添加的关键字段,则强制更新
|
||||
@@ -900,7 +904,7 @@ var ConfigManager = {
|
||||
java.lang.Thread.sleep(200);
|
||||
txt = FileIO.readText(PATH_SETTINGS);
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
var merged = JSON.parse(JSON.stringify(this.defaultSettings));
|
||||
@@ -914,7 +918,7 @@ var ConfigManager = {
|
||||
merged[k] = user[k];
|
||||
}
|
||||
loaded = true;
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// # 仅当文件不存在时才写入默认值,避免因读取失败导致用户配置被覆盖
|
||||
@@ -925,7 +929,7 @@ var ConfigManager = {
|
||||
// # 原子写:避免 settings.json 写一半导致配置损坏
|
||||
FileIO.writeTextAtomic(PATH_SETTINGS, JSON.stringify(merged, null, 2));
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
this._settingsCache = ConfigValidator.sanitizeConfig(merged);
|
||||
@@ -955,12 +959,12 @@ var ConfigManager = {
|
||||
java.lang.Thread.sleep(200);
|
||||
txt = FileIO.readText(PATH_BUTTONS);
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
var btns = null;
|
||||
if (txt) {
|
||||
try { btns = JSON.parse(txt); } catch (e) {}
|
||||
try { btns = JSON.parse(txt); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
var dirty = false;
|
||||
@@ -972,7 +976,7 @@ var ConfigManager = {
|
||||
btns = JSON.parse(JSON.stringify(this.defaultButtons));
|
||||
dirty = true;
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
// # 如果 btns 仍为空(读取失败且文件存在),则暂时返回默认值但不回写 dirty
|
||||
if (!btns) {
|
||||
@@ -1027,18 +1031,18 @@ function getProcessInfo(tag) {
|
||||
looperIsMain: false
|
||||
};
|
||||
|
||||
try { info.uid = android.os.Process.myUid(); } catch (e0) {}
|
||||
try { info.pid = android.os.Process.myPid(); } catch (e1) {}
|
||||
try { info.tid = android.os.Process.myTid(); } catch (e2) {}
|
||||
try { info.uid = android.os.Process.myUid(); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
try { info.pid = android.os.Process.myPid(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try { info.tid = android.os.Process.myTid(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
|
||||
try { info.packageName = String(context.getPackageName()); } catch (e3) {}
|
||||
try { info.threadName = String(java.lang.Thread.currentThread().getName()); } catch (e4) {}
|
||||
try { info.hasMyLooper = (android.os.Looper.myLooper() !== null); } catch (e5) {}
|
||||
try { info.packageName = String(context.getPackageName()); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
try { info.threadName = String(java.lang.Thread.currentThread().getName()); } catch(e4) { safeLog(null, 'e', "catch " + String(e4)); }
|
||||
try { info.hasMyLooper = (android.os.Looper.myLooper() !== null); } catch(e5) { safeLog(null, 'e', "catch " + String(e5)); }
|
||||
try {
|
||||
var mainLooper = android.os.Looper.getMainLooper();
|
||||
var myLooper = android.os.Looper.myLooper();
|
||||
info.looperIsMain = (myLooper !== null && mainLooper !== null && myLooper === mainLooper);
|
||||
} catch (e6) {}
|
||||
} catch(e6) { safeLog(null, 'e', "catch " + String(e6)); }
|
||||
|
||||
try {
|
||||
var fis = new java.io.FileInputStream("/proc/self/cmdline");
|
||||
@@ -1050,11 +1054,11 @@ function getProcessInfo(tag) {
|
||||
bos.write(buf, 0, n);
|
||||
if (bos.size() >= 4096) break;
|
||||
}
|
||||
try { fis.close(); } catch (eC) {}
|
||||
try { fis.close(); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); }
|
||||
var raw = new java.lang.String(bos.toByteArray());
|
||||
var p = String(raw).split("\u0000")[0];
|
||||
if (p && p.length > 0) info.processName = p;
|
||||
} catch (e7) {}
|
||||
} catch(e7) { safeLog(null, 'e', "catch " + String(e7)); }
|
||||
|
||||
if (!info.processName) {
|
||||
try {
|
||||
@@ -1070,7 +1074,7 @@ function getProcessInfo(tag) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e8) {}
|
||||
} catch(e8) { safeLog(null, 'e', "catch " + String(e8)); }
|
||||
}
|
||||
|
||||
return info;
|
||||
@@ -1164,7 +1168,7 @@ ToolHubLogger.prototype._line = function(level, msg) {
|
||||
};
|
||||
|
||||
ToolHubLogger.prototype._scheduleFlush = function() {
|
||||
if (this._flushTimer) try { this._flushTimer.cancel(); } catch(e) {}
|
||||
if (this._flushTimer) try { this._flushTimer.cancel(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var self = this;
|
||||
this._flushTimer = new java.util.Timer();
|
||||
this._flushTimer.schedule(new java.util.TimerTask({
|
||||
@@ -1228,72 +1232,6 @@ ToolHubLogger.prototype._filePathForToday = function() {
|
||||
var name = this.prefix + "_" + this._ymd(this._now()) + ".log";
|
||||
return this.dir + "/" + name;
|
||||
};
|
||||
ToolHubLogger.prototype._initOnce = function() {
|
||||
try {
|
||||
// # 尝试创建目录
|
||||
if (FileIO.ensureDir(this.dir)) {
|
||||
this.initOk = true;
|
||||
// # 清理旧日志
|
||||
this.cleanupOldFiles();
|
||||
} else {
|
||||
this.initOk = false;
|
||||
this.lastInitErr = "Mkdirs failed: " + this.dir;
|
||||
}
|
||||
} catch (e) {
|
||||
this.initOk = false;
|
||||
this.lastInitErr = String(e);
|
||||
}
|
||||
};
|
||||
ToolHubLogger.prototype.updateConfig = function(cfg) {
|
||||
if (!cfg) return;
|
||||
if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS;
|
||||
if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE;
|
||||
if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG;
|
||||
};
|
||||
ToolHubLogger.prototype._line = function(level, msg) {
|
||||
var ts = this._now();
|
||||
var d = new Date(ts);
|
||||
function pad2(x) { return (x < 10 ? "0" : "") + x; }
|
||||
var t = d.getFullYear() + "-" + pad2(d.getMonth() + 1) + "-" + pad2(d.getDate()) +
|
||||
" " + pad2(d.getHours()) + ":" + pad2(d.getMinutes()) + ":" + pad2(d.getSeconds());
|
||||
var proc = "";
|
||||
try {
|
||||
proc = " uid=" + String(this.proc.uid) + " pid=" + String(this.proc.pid) + " tid=" + String(this.proc.tid) +
|
||||
" th=" + String(this.proc.threadName) + " proc=" + String(this.proc.processName);
|
||||
} catch (e0) {}
|
||||
return t + " [" + String(level) + "] " + String(msg) + proc + "\n";
|
||||
};
|
||||
ToolHubLogger.prototype._writeRaw = function(level, msg) {
|
||||
if (!this.initOk) return false;
|
||||
var p = this._filePathForToday();
|
||||
return FileIO.appendText(p, this._line(level, msg));
|
||||
};
|
||||
ToolHubLogger.prototype._write = function(level, msg) {
|
||||
if (!this.enable) return false;
|
||||
return this._writeRaw(level, msg);
|
||||
};
|
||||
ToolHubLogger.prototype.d = function(msg) { if (this.debug) this._write("D", msg); };
|
||||
ToolHubLogger.prototype.i = function(msg) { this._write("I", msg); };
|
||||
ToolHubLogger.prototype.w = function(msg) { this._write("W", msg); };
|
||||
ToolHubLogger.prototype.e = function(msg) { this._write("E", msg); };
|
||||
ToolHubLogger.prototype.fatal = function(msg) { this._writeRaw("F", msg); };
|
||||
ToolHubLogger.prototype.cleanupOldFiles = function() {
|
||||
try {
|
||||
if (!this.initOk) return false;
|
||||
var dirF = new java.io.File(this.dir);
|
||||
var files = dirF.listFiles();
|
||||
if (!files) return false;
|
||||
var now = this._now();
|
||||
var cutoff = now - this.keepDays * 24 * 60 * 60 * 1000;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var f = files[i];
|
||||
if (f && f.isFile() && f.getName().indexOf(this.prefix) === 0 && f.lastModified() < cutoff) {
|
||||
f["delete"]();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (e) { return false; }
|
||||
};
|
||||
|
||||
// =======================【崩溃兜底:线程 UncaughtExceptionHandler】=======================
|
||||
function installCrashHandler(logger) {
|
||||
@@ -1304,9 +1242,9 @@ function installCrashHandler(logger) {
|
||||
uncaughtException: function(t, e) {
|
||||
try {
|
||||
var tn = "";
|
||||
try { tn = (t ? String(t.getName()) : ""); } catch (eT) {}
|
||||
try { tn = (t ? String(t.getName()) : ""); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); }
|
||||
var es = "";
|
||||
try { es = (e ? String(e) : ""); } catch (eE) {}
|
||||
try { es = (e ? String(e) : ""); } catch(eE) { safeLog(null, 'e', "catch " + String(eE)); }
|
||||
logger.fatal("UNCAUGHT thread=" + tn + " err=" + es);
|
||||
try {
|
||||
var sw = new java.io.StringWriter();
|
||||
@@ -1314,9 +1252,9 @@ function installCrashHandler(logger) {
|
||||
e.printStackTrace(pw);
|
||||
pw.flush();
|
||||
logger.fatal("STACKTRACE " + String(sw.toString()));
|
||||
} catch (eST) {}
|
||||
} catch (e0) {}
|
||||
try { if (old) old.uncaughtException(t, e); } catch (e1) {}
|
||||
} catch(eST) { safeLog(null, 'e', "catch " + String(eST)); }
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
try { if (old) old.uncaughtException(t, e); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
}
|
||||
});
|
||||
java.lang.Thread.setDefaultUncaughtExceptionHandler(h);
|
||||
|
||||
@@ -82,7 +82,7 @@ function FloatBallAppWM(logger) {
|
||||
this.ui.colors = {};
|
||||
|
||||
// # 初始化莫奈动态配色(传入当前主题避免重复检测)
|
||||
try { this.refreshMonetColors(this.isDarkTheme()); } catch (eM) {}
|
||||
try { this.refreshMonetColors(this.isDarkTheme()); } catch(eM) { safeLog(null, 'e', "catch " + String(eM)); }
|
||||
}
|
||||
|
||||
// =======================【工具:dp/now/clamp】======================
|
||||
@@ -102,21 +102,21 @@ FloatBallAppWM.prototype.runOnUiThreadSafe = function(fn) {
|
||||
// 优先使用 Activity 的 runOnUiThread,否则使用 View.post
|
||||
if (this.state && this.state.ballRoot) {
|
||||
this.state.ballRoot.post(new java.lang.Runnable({
|
||||
run: function() { try { fn.call(self); } catch(e) {} }
|
||||
run: function() { try { fn.call(self); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
}));
|
||||
} else {
|
||||
// 兜底:直接执行(如果已经在 UI 线程)或尝试使用 Handler
|
||||
try {
|
||||
var h = new android.os.Handler(android.os.Looper.getMainLooper());
|
||||
h.post(new java.lang.Runnable({
|
||||
run: function() { try { fn.call(self); } catch(e) {} }
|
||||
run: function() { try { fn.call(self); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
}));
|
||||
} catch(e) {
|
||||
// 最后兜底:直接执行
|
||||
try { fn.call(self); } catch(e2) {}
|
||||
try { fn.call(self); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
};
|
||||
|
||||
// # 这段代码的主要内容/用途:统一图标缓存(LRU),减少反复解码/反复走 PackageManager,降低卡顿与内存波动(不改变 UI 与功能)
|
||||
|
||||
@@ -44,7 +44,7 @@ FloatBallAppWM.prototype._iconCache = {
|
||||
var bmp = item.dr.getBitmap();
|
||||
if (bmp && !bmp.isRecycled()) bmp.recycle();
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
delete this.map[key];
|
||||
}
|
||||
},
|
||||
@@ -77,7 +77,7 @@ FloatBallAppWM.prototype._iconLruPut = function(key, val) {
|
||||
if (ord[i] === k) { ord.splice(i, 1); break; }
|
||||
}
|
||||
ord.push(k);
|
||||
} catch (eLru3) {}
|
||||
} catch(eLru3) { safeLog(null, 'e', "catch " + String(eLru3)); }
|
||||
|
||||
this._iconLru.map[k] = val;
|
||||
|
||||
@@ -88,11 +88,11 @@ FloatBallAppWM.prototype._iconLruPut = function(key, val) {
|
||||
while (ord2.length > maxN) {
|
||||
var oldK = ord2.shift();
|
||||
if (oldK != null) {
|
||||
try { delete this._iconLru.map[oldK]; } catch (eDel) {}
|
||||
try { delete this._iconLru.map[oldK]; } catch(eDel) { safeLog(null, 'e', "catch " + String(eDel)); }
|
||||
}
|
||||
}
|
||||
} catch (eLru4) {}
|
||||
} catch (eLru5) {}
|
||||
} catch(eLru4) { safeLog(null, 'e', "catch " + String(eLru4)); }
|
||||
} catch(eLru5) { safeLog(null, 'e', "catch " + String(eLru5)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ FloatBallAppWM.prototype.loadBallIconDrawableFromFile = function(path, targetPx,
|
||||
ckLru = "file|" + p + "@" + String(targetPx == null ? "" : targetPx) + "@" + String(f.lastModified()) + "@" + String(f.length());
|
||||
var hitLru = this._iconLruGet(ckLru);
|
||||
if (hitLru) return hitLru;
|
||||
} catch (eLruF0) {}
|
||||
} catch(eLruF0) { safeLog(null, 'e', "catch " + String(eLruF0)); }
|
||||
|
||||
// # 文件大小限制(字节)
|
||||
var limitBytes = Math.max(0, Math.floor(Number(maxBytes || 0)));
|
||||
@@ -161,7 +161,7 @@ FloatBallAppWM.prototype.loadBallIconDrawableFromFile = function(path, targetPx,
|
||||
// # 写入统一 LRU 缓存
|
||||
try {
|
||||
if (ckLru) this._iconLruPut(ckLru, d);
|
||||
} catch (eLruF1) {}
|
||||
} catch(eLruF1) { safeLog(null, 'e', "catch " + String(eLruF1)); }
|
||||
return d;
|
||||
} catch (e0) {
|
||||
return null;
|
||||
|
||||
@@ -5,11 +5,11 @@ FloatBallAppWM.prototype.getScreenSizePx = function() {
|
||||
try { this.state.wm.getDefaultDisplay().getRealMetrics(m); } catch (e) { this.state.wm.getDefaultDisplay().getMetrics(m); }
|
||||
return { w: m.widthPixels, h: m.heightPixels };
|
||||
};
|
||||
FloatBallAppWM.prototype.getRotation = function() { try { return this.state.wm.getDefaultDisplay().getRotation(); } catch (e) {} return -1; };
|
||||
FloatBallAppWM.prototype.getRotation = function() { try { return this.state.wm.getDefaultDisplay().getRotation(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return -1; };
|
||||
|
||||
// =======================【工具:alpha/toast/vibrate】======================
|
||||
FloatBallAppWM.prototype.withAlpha = function(colorInt, alpha01) { var a = Math.floor(Number(alpha01) * 255); return (colorInt & 0x00FFFFFF) | (a << 24); };
|
||||
FloatBallAppWM.prototype.toast = function(msg) { try { android.widget.Toast.makeText(context, String(msg), 0).show(); } catch (e) {} };
|
||||
FloatBallAppWM.prototype.toast = function(msg) { try { android.widget.Toast.makeText(context, String(msg), 0).show(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } };
|
||||
FloatBallAppWM.prototype.vibrateOnce = function(ms) {
|
||||
if (!this.config.LONG_PRESS_HAPTIC_ENABLE) return;
|
||||
try {
|
||||
@@ -22,7 +22,7 @@ FloatBallAppWM.prototype.vibrateOnce = function(ms) {
|
||||
} else {
|
||||
vib.vibrate(dur);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
};
|
||||
|
||||
// =======================【工具:UI样式辅助】======================
|
||||
@@ -133,7 +133,7 @@ FloatBallAppWM.prototype.ui = {
|
||||
btn.setGravity(android.view.Gravity.CENTER);
|
||||
var pressedColor = app.withAlpha ? app.withAlpha(bgColor, 0.8) : bgColor;
|
||||
btn.setBackground(this.createRippleDrawable(bgColor, pressedColor, app.dp(24)));
|
||||
try { btn.setElevation(app.dp(2)); } catch(e){}
|
||||
try { btn.setElevation(app.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
btn.setOnClickListener(new android.view.View.OnClickListener({
|
||||
onClick: function(v) { app.touchActivity(); app.guardClick("ui_btn", INTERACTION_CONSTANTS.CLICK_COOLDOWN_MS, function(){ if(onClick) onClick(v); }); }
|
||||
}));
|
||||
@@ -154,7 +154,7 @@ FloatBallAppWM.prototype.ui = {
|
||||
var lb = new android.widget.TextView(context);
|
||||
lb.setText(label);
|
||||
lb.setTextColor(this.colors.textSecLight); // 默认用浅色主题副文本色,外部可覆盖
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) lb.setTextColor(this.colors.textSecDark); } catch(e){}
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) lb.setTextColor(this.colors.textSecDark); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
lb.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12);
|
||||
var lpLb = new android.widget.LinearLayout.LayoutParams(0, -2);
|
||||
lpLb.weight = 1;
|
||||
@@ -164,14 +164,14 @@ FloatBallAppWM.prototype.ui = {
|
||||
et.setText(initVal ? String(initVal) : "");
|
||||
et.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
et.setTextColor(this.colors.textPriLight);
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) et.setTextColor(this.colors.textPriDark); } catch(e){}
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) et.setTextColor(this.colors.textPriDark); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
// 输入框背景优化
|
||||
var strokeColor = this.colors.dividerLight;
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = this.colors.dividerDark; } catch(e){}
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = this.colors.dividerDark; } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var bg = this.createStrokeDrawable(this.colors.inputBgLight, strokeColor, app.dp(1), app.dp(8));
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) bg = this.createStrokeDrawable(this.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e){}
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) bg = this.createStrokeDrawable(this.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
et.setBackground(bg);
|
||||
|
||||
et.setPadding(app.dp(8), app.dp(8), app.dp(8), app.dp(8));
|
||||
@@ -234,10 +234,10 @@ FloatBallAppWM.prototype.ui = {
|
||||
} else {
|
||||
errTv.setVisibility(android.view.View.GONE);
|
||||
var strokeColor = self.colors.dividerLight;
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = self.colors.dividerDark; } catch(e){}
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = self.colors.dividerDark; } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var normalBg = self.createStrokeDrawable(self.colors.inputBgLight, strokeColor, app.dp(1), app.dp(8));
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) normalBg = self.createStrokeDrawable(self.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e){}
|
||||
try { if (app.isDarkTheme && app.isDarkTheme()) normalBg = self.createStrokeDrawable(self.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
et.setBackground(normalBg);
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,7 @@ FloatBallAppWM.prototype.ui = {
|
||||
bgDr.setColor(bgColor);
|
||||
bgDr.setCornerRadius(app.dp(16));
|
||||
panel.setBackground(bgDr);
|
||||
try { panel.setElevation(app.dp(8)); } catch(e){}
|
||||
try { panel.setElevation(app.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var p = (paddingDp !== undefined) ? app.dp(paddingDp) : app.dp(16);
|
||||
panel.setPadding(p, p, p, p);
|
||||
@@ -315,7 +315,7 @@ function _th_log(L, level, msg) {
|
||||
if (level === "w" && L.w) { L.w(msg); return; }
|
||||
if (level === "i" && L.i) { L.i(msg); return; }
|
||||
if (L.d) { L.d(msg); return; }
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// =======================【莫奈动态取色工具】======================
|
||||
@@ -328,7 +328,7 @@ var MonetColorProvider = {
|
||||
var res = android.content.res.Resources.getSystem();
|
||||
var id = res.getIdentifier(resName, "color", "android");
|
||||
if (id > 0) return res.getColor(id, null);
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
try { return android.graphics.Color.parseColor(fallbackHex); } catch (e) { return 0; }
|
||||
},
|
||||
|
||||
@@ -418,9 +418,9 @@ var MonetColorProvider = {
|
||||
try {
|
||||
var id = res.getIdentifier(map[name], "color", "android");
|
||||
if (id > 0) c[name] = res.getColor(id, null);
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return c;
|
||||
},
|
||||
|
||||
@@ -487,14 +487,14 @@ function startActivityAsUserSafe(ctx, intent, userId) {
|
||||
// 降级到普通启动
|
||||
try {
|
||||
ctx.startActivity(intent);
|
||||
} catch (e2) {}
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
}
|
||||
|
||||
FloatBallAppWM.prototype.isDarkTheme = function() {
|
||||
// 0) 优先检查用户强制设置 (0=跟随系统, 1=白天, 2=黑夜)
|
||||
var mode = 0;
|
||||
try { mode = Math.floor(Number(this.config.THEME_MODE || 0)); } catch(e){}
|
||||
try { mode = Math.floor(Number(this.config.THEME_MODE || 0)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
if (mode === 2) return true;
|
||||
if (mode === 1) return false;
|
||||
@@ -511,7 +511,7 @@ FloatBallAppWM.prototype.isDarkTheme = function() {
|
||||
var nightMask = (uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK);
|
||||
if (nightMask === android.content.res.Configuration.UI_MODE_NIGHT_YES) { result = true; from = "Configuration(UI_MODE_NIGHT_YES)"; }
|
||||
else if (nightMask === android.content.res.Configuration.UI_MODE_NIGHT_NO) { result = false; from = "Configuration(UI_MODE_NIGHT_NO)"; }
|
||||
} catch (e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
|
||||
if (from === "unknown") {
|
||||
try {
|
||||
@@ -523,7 +523,7 @@ FloatBallAppWM.prototype.isDarkTheme = function() {
|
||||
else if (nm === android.app.UiModeManager.MODE_NIGHT_NO) { result = false; from = "UiModeManager(MODE_NIGHT_NO)"; }
|
||||
else { from = "UiModeManager(mode=" + String(nm) + ")"; }
|
||||
}
|
||||
} catch (e2) {}
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
|
||||
// # 3) 实在判断不了,就按"非暗色"处理,避免自动主题背景黑成一片
|
||||
@@ -533,14 +533,14 @@ FloatBallAppWM.prototype.isDarkTheme = function() {
|
||||
var logKey = String(result) + "|" + from + "|" + mode;
|
||||
if (this._lastDarkThemeLog !== logKey) {
|
||||
this._lastDarkThemeLog = logKey;
|
||||
try { _th_log(this.L, "d", "[theme] isDarkTheme=" + String(result) + " via=" + from + " mode=" + mode); } catch (e3) {}
|
||||
try { _th_log(this.L, "d", "[theme] isDarkTheme=" + String(result) + " via=" + from + " mode=" + mode); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
}
|
||||
|
||||
// # 主题切换时刷新莫奈配色(传入 result 避免递归)
|
||||
// 注:构造函数中会初始化,这里只在构造完成后的切换时触发
|
||||
if (this._lastDarkResult !== undefined && this._lastDarkResult !== result) {
|
||||
this._lastDarkResult = result;
|
||||
try { this.refreshMonetColors(result); } catch (eM) {}
|
||||
try { this.refreshMonetColors(result); } catch(eM) { safeLog(null, 'e', "catch " + String(eM)); }
|
||||
} else if (this._lastDarkResult === undefined) {
|
||||
this._lastDarkResult = result;
|
||||
}
|
||||
@@ -592,9 +592,9 @@ FloatBallAppWM.prototype.refreshMonetColors = function(forceDark) {
|
||||
c._monetSecondary = m.secondary;
|
||||
c._monetTertiary = m.tertiary;
|
||||
|
||||
try { _th_log(this.L, "d", "[monet] refreshed isDark=" + isDark + " primary=" + _th_hex(c.primary) + " primaryDark=" + _th_hex(c.primaryDark) + " accent=" + _th_hex(c.accent)); } catch (e) {}
|
||||
try { _th_log(this.L, "d", "[monet] refreshed isDark=" + isDark + " primary=" + _th_hex(c.primary) + " primaryDark=" + _th_hex(c.primaryDark) + " accent=" + _th_hex(c.accent)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
} catch (e) {
|
||||
try { _th_log(this.L, "e", "[monet] refresh err=" + String(e)); } catch (e2) {}
|
||||
try { _th_log(this.L, "e", "[monet] refresh err=" + String(e)); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -618,12 +618,12 @@ FloatBallAppWM.prototype.getMonetAccentForBall = function() {
|
||||
var logKey = "hit|" + names[i] + "|" + c;
|
||||
if (this._lastAccentLog !== logKey) {
|
||||
this._lastAccentLog = logKey;
|
||||
try { _th_log(this.L, "d", "[theme] hit accent=" + names[i] + " id=" + String(id) + " c=" + _th_hex(c) + " " + _th_argb(c)); } catch (eL0) {}
|
||||
try { _th_log(this.L, "d", "[theme] hit accent=" + names[i] + " id=" + String(id) + " c=" + _th_hex(c) + " " + _th_argb(c)); } catch(eL0) { safeLog(null, 'e', "catch " + String(eL0)); }
|
||||
}
|
||||
return c;
|
||||
}
|
||||
} catch (e) {
|
||||
try { _th_log(this.L, "w", "[theme] err accent=" + names[i] + " e=" + String(e)); } catch (eL2) {}
|
||||
try { _th_log(this.L, "w", "[theme] err accent=" + names[i] + " e=" + String(e)); } catch(eL2) { safeLog(null, 'e', "catch " + String(eL2)); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ FloatBallAppWM.prototype.getMonetAccentForBall = function() {
|
||||
var logKeyFb = "miss_all|" + fb;
|
||||
if (this._lastAccentLog !== logKeyFb) {
|
||||
this._lastAccentLog = logKeyFb;
|
||||
try { _th_log(this.L, "w", "[theme] accent miss all, fallback=" + _th_hex(fb) + " " + _th_argb(fb)); } catch (eL3) {}
|
||||
try { _th_log(this.L, "w", "[theme] accent miss all, fallback=" + _th_hex(fb) + " " + _th_argb(fb)); } catch(eL3) { safeLog(null, 'e', "catch " + String(eL3)); }
|
||||
}
|
||||
return fb;
|
||||
};
|
||||
@@ -649,14 +649,14 @@ FloatBallAppWM.prototype.updateBallContentBackground = function(contentView) {
|
||||
// # 自定义 PNG/APP 模式下:背景透明
|
||||
var fillColor = ballColor;
|
||||
var _usedKind = "none";
|
||||
try { _usedKind = this.state.usedIconKind || "none"; } catch(eK){}
|
||||
try { _usedKind = this.state.usedIconKind || "none"; } catch(eK) { safeLog(null, 'e', "catch " + String(eK)); }
|
||||
|
||||
try {
|
||||
var _pngModeBg = Number(this.config.BALL_PNG_MODE || 0);
|
||||
if ((_pngModeBg === 1 && _usedKind === "file") || _usedKind === "app") {
|
||||
fillColor = android.graphics.Color.TRANSPARENT;
|
||||
}
|
||||
} catch (eBg) {}
|
||||
} catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); }
|
||||
|
||||
var content = new android.graphics.drawable.GradientDrawable();
|
||||
content.setShape(android.graphics.drawable.GradientDrawable.OVAL);
|
||||
@@ -671,7 +671,7 @@ FloatBallAppWM.prototype.updateBallContentBackground = function(contentView) {
|
||||
? Color.parseColor("#33000000") // 浅球用半透明黑边
|
||||
: Color.parseColor("#55FFFFFF"); // 深球用半透明白边
|
||||
content.setStroke(this.dp(1), strokeInt);
|
||||
} catch(eS){}
|
||||
} catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
}
|
||||
|
||||
var mask = new android.graphics.drawable.GradientDrawable();
|
||||
@@ -683,7 +683,7 @@ FloatBallAppWM.prototype.updateBallContentBackground = function(contentView) {
|
||||
content,
|
||||
mask
|
||||
));
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -720,7 +720,7 @@ FloatBallAppWM.prototype.getPanelBgColorInt = function() {
|
||||
|
||||
var out = this.withAlpha(base, a);
|
||||
|
||||
try { _th_log(this.L, "d", "[t]bg isDark=" + isDark + " o=" + _th_hex(out)); } catch (e2) {}
|
||||
try { _th_log(this.L, "d", "[t]bg isDark=" + isDark + " o=" + _th_hex(out)); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
|
||||
return out;
|
||||
};
|
||||
@@ -757,7 +757,7 @@ FloatBallAppWM.prototype.applyTextColorRecursive = function(v, colorInt) {
|
||||
this.applyTextColorRecursive(v.getChildAt(i), colorInt);
|
||||
}
|
||||
}
|
||||
} catch (e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.updatePanelBackground = function(panelView) {
|
||||
@@ -774,15 +774,15 @@ FloatBallAppWM.prototype.updatePanelBackground = function(panelView) {
|
||||
var isDark = this.isDarkTheme();
|
||||
var outlineColor = this.ui.colors._monetOutline || (isDark ? android.graphics.Color.parseColor("#8E918F") : android.graphics.Color.parseColor("#747775"));
|
||||
var stroke = this.withAlpha(outlineColor, isDark ? 0.26 : 0.20);
|
||||
try { bg.setStroke(sw, stroke); } catch (eS) {}
|
||||
try { bg.setStroke(sw, stroke); } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
|
||||
panelView.setBackground(bg);
|
||||
|
||||
var tc = this.getPanelTextColorInt(bgInt);
|
||||
try { themeBgInt = bgInt; themeTextInt = tc; } catch (eT) {}
|
||||
try { themeBgInt = bgInt; themeTextInt = tc; } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); }
|
||||
this.applyTextColorRecursive(panelView, tc);
|
||||
|
||||
try { _th_log(this.L, "d", "[t]apply bg=" + _th_hex(bgInt) + " tx=" + _th_hex(tc)); } catch (e) {}
|
||||
try { _th_log(this.L, "d", "[t]apply bg=" + _th_hex(bgInt) + " tx=" + _th_hex(tc)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
|
||||
try {
|
||||
@@ -792,9 +792,9 @@ FloatBallAppWM.prototype.updatePanelBackground = function(panelView) {
|
||||
" text=" + _th_hex(tc) + " " + _th_argb(tc) +
|
||||
" stroke=" + _th_hex(stroke)
|
||||
);
|
||||
} catch (eL0) {}
|
||||
} catch(eL0) { safeLog(null, 'e', "catch " + String(eL0)); }
|
||||
} catch (e) {
|
||||
try { _th_log(this.L, "e", "[theme:apply] err=" + String(e)); } catch (eL1) {}
|
||||
try { _th_log(this.L, "e", "[theme:apply] err=" + String(e)); } catch(eL1) { safeLog(null, 'e', "catch " + String(eL1)); }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ FloatBallAppWM.prototype.savePanelState = function(key, state) {
|
||||
// 节流或立即保存? 面板拖动结束通常不频繁,立即保存即可
|
||||
// 但为了避免连续事件,还是可以复用 savePos 的节流逻辑,或者直接保存
|
||||
ConfigManager.saveSettings(this.config);
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.loadPanelState = function(key) {
|
||||
@@ -174,7 +174,7 @@ FloatBallAppWM.prototype._refreshPreviewInternal = function(changedKey) {
|
||||
|
||||
// 移除旧面板
|
||||
if (oldAdded && oldPanel) {
|
||||
try { this.state.wm.removeView(oldPanel); } catch(e) {}
|
||||
try { this.state.wm.removeView(oldPanel); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
||||
this.L.cfg.LOG_ENABLE = !!this.config.LOG_ENABLE;
|
||||
this.L.i("apply LOG_ENABLE=" + String(this.config.LOG_ENABLE));
|
||||
}
|
||||
} catch (eLE) {}
|
||||
} catch(eLE) { safeLog(null, 'e', "catch " + String(eLE)); }
|
||||
return;
|
||||
}
|
||||
if (k === "LOG_DEBUG") {
|
||||
@@ -218,7 +218,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
||||
this.L.cfg.LOG_DEBUG = !!this.config.LOG_DEBUG;
|
||||
this.L.i("apply LOG_DEBUG=" + String(this.config.LOG_DEBUG));
|
||||
}
|
||||
} catch (eLD) {}
|
||||
} catch(eLD) { safeLog(null, 'e', "catch " + String(eLD)); }
|
||||
return;
|
||||
}
|
||||
if (k === "LOG_KEEP_DAYS") {
|
||||
@@ -231,7 +231,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
||||
this.L.i("apply LOG_KEEP_DAYS=" + String(n));
|
||||
this.L.cleanupOldFiles();
|
||||
}
|
||||
} catch (eLK) {}
|
||||
} catch(eLK) { safeLog(null, 'e', "catch " + String(eLK)); }
|
||||
return;
|
||||
}
|
||||
if (k === "BALL_SIZE_DP" || k === "BALL_PNG_MODE" || k === "BALL_ICON_TYPE" || k === "BALL_ICON_FILE_PATH" || k === "BALL_ICON_RES_ID" || k === "BALL_ICON_RES_NAME" || k === "BALL_ICON_SIZE_DP" || k === "BALL_ICON_TINT_HEX") { this.rebuildBallForNewSize(); return; }
|
||||
@@ -255,7 +255,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.commitPendingUserCfg = function() {
|
||||
|
||||
@@ -51,7 +51,7 @@ FloatBallAppWM.prototype.resolveIconDrawable = function(btn) {
|
||||
var dr = this.loadBallIconDrawableFromFile(path, this.dp(sizeDp), 1048576, 1024);
|
||||
if (dr) return dr;
|
||||
}
|
||||
} catch (ePath) {}
|
||||
} catch(ePath) { safeLog(null, 'e', "catch " + String(ePath)); }
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ try {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (eApp) {}
|
||||
} catch(eApp) { safeLog(null, 'e', "catch " + String(eApp)); }
|
||||
|
||||
|
||||
// # 1.5) type=shortcut:尝试取 Shortcuts 快捷方式图标(显示与 shortcuts.js 页面一致)
|
||||
@@ -100,13 +100,13 @@ try {
|
||||
try {
|
||||
var sk0 = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : "");
|
||||
this._iconLruPut("sc|" + sk0, dr0);
|
||||
} catch (eSc0) {}
|
||||
} catch(eSc0) { safeLog(null, 'e', "catch " + String(eSc0)); }
|
||||
return dr0;
|
||||
}
|
||||
}
|
||||
} catch(eF0) {}
|
||||
} catch(eF0) { safeLog(null, 'e', "catch " + String(eF0)); }
|
||||
}
|
||||
} catch(eFile0) {}
|
||||
} catch(eFile0) { safeLog(null, 'e', "catch " + String(eFile0)); }
|
||||
var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : "");
|
||||
var kSc = "sc|" + skey;
|
||||
var hitSc = this._iconLruGet(kSc);
|
||||
@@ -145,7 +145,7 @@ var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) :
|
||||
var tmpUid2 = parseInt(String(buid2), 10);
|
||||
if (!isNaN(tmpUid2)) userIdIntForSvc = tmpUid2;
|
||||
}
|
||||
} catch(eUidSvc) {}
|
||||
} catch(eUidSvc) { safeLog(null, 'e', "catch " + String(eUidSvc)); }
|
||||
|
||||
var sm2 = android.os.ServiceManager;
|
||||
var shortcutSvc = null;
|
||||
@@ -160,23 +160,23 @@ var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) :
|
||||
if (listObj2) list = listObj2;
|
||||
}
|
||||
}
|
||||
} catch(eSvc2) {}
|
||||
} catch(eSvc2) { safeLog(null, 'e', "catch " + String(eSvc2)); }
|
||||
|
||||
// # 2) LauncherApps 回退(当 shortcut service 不可用或返回空时)
|
||||
if (list == null) {
|
||||
var q = new android.content.pm.LauncherApps.ShortcutQuery();
|
||||
try { q.setPackage(pkg2); } catch(eSP) {}
|
||||
try { q.setPackage(pkg2); } catch(eSP) { safeLog(null, 'e', "catch " + String(eSP)); }
|
||||
|
||||
// # 重要:必须设置 QueryFlags,否则 getShortcuts 可能返回空(默认 flags=0)
|
||||
// # 兼容性:不同 Android/ROM 可能缺少部分 FLAG,逐个 try 叠加
|
||||
try {
|
||||
var qFlags = 0;
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; } catch(eF1) {}
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; } catch(eF2) {}
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST; } catch(eF3) {}
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED; } catch(eF4) {}
|
||||
try { q.setQueryFlags(qFlags); } catch(eSF) {}
|
||||
} catch(eQF) {}
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; } catch(eF1) { safeLog(null, 'e', "catch " + String(eF1)); }
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; } catch(eF2) { safeLog(null, 'e', "catch " + String(eF2)); }
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST; } catch(eF3) { safeLog(null, 'e', "catch " + String(eF3)); }
|
||||
try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED; } catch(eF4) { safeLog(null, 'e', "catch " + String(eF4)); }
|
||||
try { q.setQueryFlags(qFlags); } catch(eSF) { safeLog(null, 'e', "catch " + String(eSF)); }
|
||||
} catch(eQF) { safeLog(null, 'e', "catch " + String(eQF)); }
|
||||
|
||||
// # 重要:用户句柄优先用按钮携带的 userId(如有),否则使用当前用户
|
||||
var uh = android.os.Process.myUserHandle();
|
||||
@@ -190,7 +190,7 @@ var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) :
|
||||
uh = android.os.UserHandle.of(uidInt);
|
||||
}
|
||||
}
|
||||
} catch(eUH) {}
|
||||
} catch(eUH) { safeLog(null, 'e', "catch " + String(eUH)); }
|
||||
|
||||
try { list = la.getShortcuts(q, uh); } catch(eGS) { list = null; }
|
||||
}
|
||||
@@ -219,10 +219,10 @@ if (si != null) {
|
||||
var d2 = ic.loadDrawable(context);
|
||||
if (d2 != null) drSc = d2;
|
||||
}
|
||||
} catch(eIcon1) {}
|
||||
} catch(eIcon1) { safeLog(null, 'e', "catch " + String(eIcon1)); }
|
||||
}
|
||||
if (drSc != null) {
|
||||
try { this._iconLruPut("sc|" + skey, drSc); } catch (eSc1) {}
|
||||
try { this._iconLruPut("sc|" + skey, drSc); } catch(eSc1) { safeLog(null, 'e', "catch " + String(eSc1)); }
|
||||
return drSc;
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ if (si != null) {
|
||||
try {
|
||||
if (nowTs > 0) this._shortcutIconFailTs[skey] = nowTs;
|
||||
else this._shortcutIconFailTs[skey] = new Date().getTime();
|
||||
} catch(eFT) {}
|
||||
} catch(eFT) { safeLog(null, 'e', "catch " + String(eFT)); }
|
||||
}
|
||||
|
||||
|
||||
@@ -244,10 +244,10 @@ if (si != null) {
|
||||
var pm2 = context.getPackageManager();
|
||||
var drApp2 = pm2.getApplicationIcon(pkg2);
|
||||
if (drApp2 != null) return drApp2;
|
||||
} catch(eFall) {}
|
||||
} catch(eFall) { safeLog(null, 'e', "catch " + String(eFall)); }
|
||||
}
|
||||
}
|
||||
} catch (eSc) {}
|
||||
} catch(eSc) { safeLog(null, 'e', "catch " + String(eSc)); }
|
||||
// # 2) 显式指定 iconResName (String) 或 iconResId (int)
|
||||
try {
|
||||
if (btn.iconResName) {
|
||||
@@ -259,11 +259,11 @@ if (si != null) {
|
||||
if (id > 0) return context.getResources().getDrawable(id, null);
|
||||
}
|
||||
if (btn.iconResId) return context.getResources().getDrawable(btn.iconResId, null);
|
||||
} catch (e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
|
||||
// # 3) 兜底
|
||||
return context.getResources().getDrawable(android.R.drawable.ic_menu_help, null);
|
||||
} catch (e2) {}
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -302,7 +302,7 @@ FloatBallAppWM.prototype.normalizeShortXIconName = function(name, keepPrefix) {
|
||||
return s;
|
||||
}
|
||||
return keepPrefix ? ("ic_remix_" + s) : s;
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return "";
|
||||
};
|
||||
|
||||
@@ -320,20 +320,20 @@ FloatBallAppWM.prototype.getShortXApkPaths = function() {
|
||||
p = String(p || "");
|
||||
if (!p) return;
|
||||
if (out.indexOf(p) < 0) out.push(p);
|
||||
} catch (eP) {}
|
||||
} catch(eP) { safeLog(null, 'e', "catch " + String(eP)); }
|
||||
}
|
||||
if (ai) {
|
||||
try { pushPath(ai.sourceDir); } catch (e0) {}
|
||||
try { pushPath(ai.publicSourceDir); } catch (e1) {}
|
||||
try { pushPath(ai.sourceDir); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
try { pushPath(ai.publicSourceDir); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try {
|
||||
var ss = ai.splitSourceDirs;
|
||||
if (ss) {
|
||||
var i;
|
||||
for (i = 0; i < ss.length; i++) pushPath(ss[i]);
|
||||
}
|
||||
} catch (e2) {}
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return out;
|
||||
};
|
||||
|
||||
@@ -371,7 +371,7 @@ FloatBallAppWM.prototype.scanShortXIconsFromApk = function() {
|
||||
} catch (eZip) {
|
||||
lastErr = String(eZip);
|
||||
} finally {
|
||||
try { if (zip) zip.close(); } catch (eClose) {}
|
||||
try { if (zip) zip.close(); } catch(eClose) { safeLog(null, 'e', "catch " + String(eClose)); }
|
||||
}
|
||||
}
|
||||
if ((!out || out.length === 0) && lastErr) this._shortxIconCatalogError = "APK扫描: " + lastErr + " (路径数=" + paths.length + ", 文件数=" + totalFiles + ")";
|
||||
@@ -399,7 +399,7 @@ FloatBallAppWM.prototype.getShortXIconLookupNames = function(name) {
|
||||
add("ic_remix_" + s);
|
||||
add("ic_" + s);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return out;
|
||||
};
|
||||
|
||||
@@ -414,7 +414,7 @@ FloatBallAppWM.prototype.resolveShortXDrawableResId = function(name) {
|
||||
try { resId = handle.res.getIdentifier(String(cands[i]), "drawable", handle.pkg); } catch (e1) { resId = 0; }
|
||||
if (resId > 0) return resId;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -429,10 +429,10 @@ FloatBallAppWM.prototype.resolveShortXDrawable = function(name, tintHex) {
|
||||
try {
|
||||
dr = dr.mutate();
|
||||
dr.setColorFilter(android.graphics.Color.parseColor(String(tintHex)), android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
} catch (eTint) {}
|
||||
} catch(eTint) { safeLog(null, 'e', "catch " + String(eTint)); }
|
||||
}
|
||||
return dr;
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -467,7 +467,7 @@ FloatBallAppWM.prototype.getShortXIconCatalog = function(forceReload) {
|
||||
shortName: (fname.indexOf("ic_remix_") === 0) ? fname.substring("ic_remix_".length) : fname,
|
||||
id: f.getInt(null)
|
||||
});
|
||||
} catch (eField) {}
|
||||
} catch(eField) { safeLog(null, 'e', "catch " + String(eField)); }
|
||||
}
|
||||
} catch (eClz) {
|
||||
this._shortxIconCatalogError = "R$drawable reflect: " + String(eClz);
|
||||
|
||||
@@ -42,7 +42,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
self.__shortcutPickerSingleton.show(opts);
|
||||
return;
|
||||
}
|
||||
} catch(eSingle) {}
|
||||
} catch(eSingle) { safeLog(null, 'e', "catch " + String(eSingle)); }
|
||||
|
||||
|
||||
// # 兼容:toolhub.js 全局未必定义 Context 别名,这里显式绑定,避免 ReferenceError。
|
||||
@@ -76,7 +76,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
if (f.exists() && f.isDirectory() && f.canRead()) {
|
||||
return candidates[i];
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// 反射获取环境变量(最可靠但较慢)
|
||||
@@ -89,7 +89,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
return envPath;
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
// 最终兜底
|
||||
return "/data/system_ce";
|
||||
@@ -119,7 +119,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
if (!ok) continue;
|
||||
out.push(parseInt(name, 10));
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
// 默认兜底:至少有 user 0
|
||||
if (out.length === 0) out.push(0);
|
||||
return out;
|
||||
@@ -135,7 +135,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
if (typeof getSystemUserDir === "function") {
|
||||
basePath = getSystemUserDir();
|
||||
}
|
||||
} catch(eGSD2) {}
|
||||
} catch(eGSD2) { safeLog(null, 'e', "catch " + String(eGSD2)); }
|
||||
|
||||
var dir = new java.io.File(basePath + "/" + String(userId) + "/shortcut_service/packages");
|
||||
if (!dir.exists() || !dir.isDirectory()) return out;
|
||||
@@ -151,7 +151,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
if (pkg && pkg.length > 0) out.push(pkg);
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -187,9 +187,9 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
try {
|
||||
var s0 = listObj.get(si0);
|
||||
if (s0) out.push(s0);
|
||||
} catch(eS2) {}
|
||||
} catch(eS2) { safeLog(null, 'e', "catch " + String(eS2)); }
|
||||
}
|
||||
} catch(eS3) {}
|
||||
} catch(eS3) { safeLog(null, 'e', "catch " + String(eS3)); }
|
||||
if (out.length > 0) return out;
|
||||
}
|
||||
}
|
||||
@@ -222,9 +222,9 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
LauncherAppsShortcutQuery.FLAG_MATCH_PINNED |
|
||||
LauncherAppsShortcutQuery.FLAG_MATCH_MANIFEST
|
||||
);
|
||||
} catch(eF2) {}
|
||||
} catch(eF2) { safeLog(null, 'e', "catch " + String(eF2)); }
|
||||
}
|
||||
try { q.setPackage(safeStr(pkg)); } catch(eP) {}
|
||||
try { q.setPackage(safeStr(pkg)); } catch(eP) { safeLog(null, 'e', "catch " + String(eP)); }
|
||||
|
||||
// user 处理:尽量兼容多用户
|
||||
var userHandle = null;
|
||||
@@ -248,9 +248,9 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
try {
|
||||
var si = list.get(i);
|
||||
if (si) out.push(si);
|
||||
} catch(eI) {}
|
||||
} catch(eI) { safeLog(null, 'e', "catch " + String(eI)); }
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
var ai = pm.getApplicationInfo(String(pkg), 0);
|
||||
var lb = pm.getApplicationLabel(ai);
|
||||
if (lb != null) return String(lb);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
return String(pkg);
|
||||
}
|
||||
|
||||
@@ -315,14 +315,14 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
// density: 0 让系统自适应(部分 ROM 更稳)
|
||||
var dr = la.getShortcutIconDrawable(item.shortcutInfo, 0);
|
||||
if (dr) return dr;
|
||||
} catch(eLa) {}
|
||||
} catch(eLa) { safeLog(null, 'e', "catch " + String(eLa)); }
|
||||
}
|
||||
} catch(e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
// fallback: app icon
|
||||
try {
|
||||
var pm = context.getPackageManager();
|
||||
return pm.getApplicationIcon(String(item.pkg));
|
||||
} catch(e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
return ta.localeCompare(tb);
|
||||
});
|
||||
order = ["__ALL__"].concat(rest);
|
||||
} catch(eS) {}
|
||||
} catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
return { groups: groups, order: order };
|
||||
}
|
||||
|
||||
@@ -440,13 +440,13 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
};
|
||||
|
||||
|
||||
function Ld(msg) { try { if (self.L) self.L.d("[shortcut] " + msg); } catch(e) {} }
|
||||
function Li(msg) { try { if (self.L) self.L.i("[shortcut] " + msg); } catch(e) {} }
|
||||
function Le(msg) { try { if (self.L) self.L.e("[shortcut] " + msg); } catch(e) {} }
|
||||
function Ld(msg) { try { if (self.L) self.L.d("[shortcut] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
function Li(msg) { try { if (self.L) self.L.i("[shortcut] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
function Le(msg) { try { if (self.L) self.L.e("[shortcut] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
|
||||
function runOn(handler, fn) {
|
||||
try {
|
||||
handler.post(new JavaAdapter(Runnable, { run: function() { try { fn(); } catch(e) {} } }));
|
||||
handler.post(new JavaAdapter(Runnable, { run: function() { try { fn(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } }));
|
||||
return true;
|
||||
} catch(e) { return false; }
|
||||
}
|
||||
@@ -462,45 +462,45 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
state.scrollPollRunning = false;
|
||||
|
||||
// # 停止队列与异步:隐藏后不再触发 UI/图标加载逻辑
|
||||
try { h.removeCallbacksAndMessages(null); } catch(eCB0) {}
|
||||
try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) {}
|
||||
try { h.removeCallbacksAndMessages(null); } catch(eCB0) { safeLog(null, 'e', "catch " + String(eCB0)); }
|
||||
try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) { safeLog(null, 'e', "catch " + String(eCB1)); }
|
||||
|
||||
// # 输入法/焦点:无论是否弹出输入法,都先退焦点并尝试隐藏软键盘
|
||||
try {
|
||||
if (state.etSearch) {
|
||||
try { state.etSearch.clearFocus(); } catch(eK0) {}
|
||||
try { state.etSearch.clearFocus(); } catch(eK0) { safeLog(null, 'e', "catch " + String(eK0)); }
|
||||
try {
|
||||
var imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
|
||||
if (imm) imm.hideSoftInputFromWindow(state.etSearch.getWindowToken(), 0);
|
||||
} catch(eK1) {}
|
||||
} catch(eK1) { safeLog(null, 'e', "catch " + String(eK1)); }
|
||||
}
|
||||
} catch(eK2) {}
|
||||
} catch(eK2) { safeLog(null, 'e', "catch " + String(eK2)); }
|
||||
|
||||
// # 仅隐藏 View:不触碰 WM removeView,避免 WM/IME token 状态机被打乱
|
||||
try {
|
||||
if (state.root) {
|
||||
state.root.setVisibility(android.view.View.GONE);
|
||||
}
|
||||
} catch(eV0) {}
|
||||
} catch(eV0) { safeLog(null, 'e', "catch " + String(eV0)); }
|
||||
|
||||
// # 退出线程:hide 时也释放线程,避免反复打开/隐藏导致线程堆积
|
||||
try {
|
||||
var killer = new Thread(new JavaAdapter(Runnable, {
|
||||
run: function() {
|
||||
try { bgHt.quitSafely(); } catch(e2) {}
|
||||
try { ht.quitSafely(); } catch(e3) {}
|
||||
try { bgHt.quitSafely(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
try { ht.quitSafely(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
}
|
||||
}));
|
||||
killer.start();
|
||||
} catch(eQuit) {}
|
||||
} catch(eQuit) { safeLog(null, 'e', "catch " + String(eQuit)); }
|
||||
|
||||
// # 通知外层:选择器已隐藏,可恢复上层面板显示
|
||||
try {
|
||||
if (state.onDismiss && !state.onDismissCalled) {
|
||||
state.onDismissCalled = true;
|
||||
try { state.onDismiss(); } catch(eOD0) {}
|
||||
try { state.onDismiss(); } catch(eOD0) { safeLog(null, 'e', "catch " + String(eOD0)); }
|
||||
}
|
||||
} catch(eOD1) {}
|
||||
} catch(eOD1) { safeLog(null, 'e', "catch " + String(eOD1)); }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -516,51 +516,51 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) {
|
||||
state.scrollPollRunning = false;
|
||||
|
||||
// # 清理消息队列
|
||||
try { h.removeCallbacksAndMessages(null); } catch(eCB0) {}
|
||||
try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) {}
|
||||
try { h.removeCallbacksAndMessages(null); } catch(eCB0) { safeLog(null, 'e', "catch " + String(eCB0)); }
|
||||
try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) { safeLog(null, 'e', "catch " + String(eCB1)); }
|
||||
|
||||
try { state.iconQ = []; } catch(e0) {}
|
||||
try { state.iconQ = []; } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
state.iconInFlight = 0;
|
||||
|
||||
// # 通知外层:选择器即将销毁,可恢复上层面板显示
|
||||
try {
|
||||
if (state.onDismiss && !state.onDismissCalled) {
|
||||
state.onDismissCalled = true;
|
||||
try { state.onDismiss(); } catch(eOD0) {}
|
||||
try { state.onDismiss(); } catch(eOD0) { safeLog(null, 'e', "catch " + String(eOD0)); }
|
||||
}
|
||||
} catch(eOD1) {}
|
||||
} catch(eOD1) { safeLog(null, 'e', "catch " + String(eOD1)); }
|
||||
|
||||
// # 输入法/焦点清理
|
||||
try {
|
||||
if (state.etSearch) {
|
||||
try { state.etSearch.clearFocus(); } catch(eK0) {}
|
||||
try { state.etSearch.clearFocus(); } catch(eK0) { safeLog(null, 'e', "catch " + String(eK0)); }
|
||||
try {
|
||||
var imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
|
||||
if (imm) imm.hideSoftInputFromWindow(state.etSearch.getWindowToken(), 0);
|
||||
} catch(eK1) {}
|
||||
} catch(eK1) { safeLog(null, 'e', "catch " + String(eK1)); }
|
||||
}
|
||||
} catch(eK2) {}
|
||||
} catch(eK2) { safeLog(null, 'e', "catch " + String(eK2)); }
|
||||
|
||||
// # 尝试移除 View(失败也吞掉,避免把 system_server 再次打穿)
|
||||
var rootRef = state.root;
|
||||
var wasAdded = state.isAdded;
|
||||
try {
|
||||
if (rootRef && wasAdded) {
|
||||
try { wm.removeViewImmediate(rootRef); } catch(eR0) { try { wm.removeView(rootRef); } catch(eR1) {} }
|
||||
try { wm.removeViewImmediate(rootRef); } catch(eR0) { try { wm.removeView(rootRef); } catch(eR1) { safeLog(null, 'e', "catch " + String(eR1)); } }
|
||||
}
|
||||
} catch(eR2) {}
|
||||
} catch(eR2) { safeLog(null, 'e', "catch " + String(eR2)); }
|
||||
|
||||
state.isAdded = false;
|
||||
state.root = null;
|
||||
|
||||
// # 单例清理
|
||||
try { if (self.__shortcutPickerSingleton && self.__shortcutPickerSingleton.instanceId === state.instanceId) self.__shortcutPickerSingleton = null; } catch(eS0) {}
|
||||
try { if (self.__shortcutPickerSingleton && self.__shortcutPickerSingleton.instanceId === state.instanceId) self.__shortcutPickerSingleton = null; } catch(eS0) { safeLog(null, 'e', "catch " + String(eS0)); }
|
||||
|
||||
// # 退出线程
|
||||
var killer = new Thread(new JavaAdapter(Runnable, {
|
||||
run: function() {
|
||||
try { bgHt.quitSafely(); } catch(e2) {}
|
||||
try { ht.quitSafely(); } catch(e3) {}
|
||||
try { bgHt.quitSafely(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
try { ht.quitSafely(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
}
|
||||
}));
|
||||
killer.start();
|
||||
@@ -633,7 +633,7 @@ function cacheGet(key) {
|
||||
if (state.destroyed) return;
|
||||
|
||||
if (dr) {
|
||||
try { j.iv.setImageDrawable(dr); } catch(e1) {}
|
||||
try { j.iv.setImageDrawable(dr); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
cachePut(j.key, dr);
|
||||
} else {
|
||||
markIconFail(j.key);
|
||||
@@ -645,7 +645,7 @@ function cacheGet(key) {
|
||||
}
|
||||
}
|
||||
|
||||
function setStat(text) { try { if (state.tvStat) state.tvStat.setText(String(text)); } catch(e) {} }
|
||||
function setStat(text) { try { if (state.tvStat) state.tvStat.setText(String(text)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
|
||||
function rebuildRenderList() {
|
||||
var g = state.groups ? state.groups[state.currentGroupKey] : null;
|
||||
@@ -661,7 +661,7 @@ function cacheGet(key) {
|
||||
function clearGrid() {
|
||||
try {
|
||||
if (state.grid) state.grid.removeAllViews();
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
function appendBatch() {
|
||||
@@ -687,7 +687,7 @@ function cacheGet(key) {
|
||||
var lpRow = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
lpRow.setMargins(0, 0, 0, self.dp(8));
|
||||
row.setLayoutParams(lpRow);
|
||||
} catch(eLpR) {}
|
||||
} catch(eLpR) { safeLog(null, 'e', "catch " + String(eLpR)); }
|
||||
|
||||
row.setPadding(self.dp(12), self.dp(10), self.dp(12), self.dp(10));
|
||||
|
||||
@@ -697,18 +697,18 @@ function cacheGet(key) {
|
||||
var bgColor = isDark ? self.ui.colors.cardDark : self.ui.colors.cardLight;
|
||||
var stroke = isDark ? self.ui.colors.dividerDark : self.ui.colors.dividerLight;
|
||||
row.setBackground(self.ui.createStrokeDrawable(bgColor, stroke, self.dp(1), self.dp(12)));
|
||||
} catch(eBg) {}
|
||||
} catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); }
|
||||
|
||||
var iv = new android.widget.ImageView(context);
|
||||
var lpI = new android.widget.LinearLayout.LayoutParams(self.dp(40), self.dp(40));
|
||||
lpI.setMargins(0, 0, self.dp(12), 0);
|
||||
iv.setLayoutParams(lpI);
|
||||
try { iv.setImageResource(android.R.drawable.sym_def_app_icon); } catch(eI0) {}
|
||||
try { iv.setImageResource(android.R.drawable.sym_def_app_icon); } catch(eI0) { safeLog(null, 'e', "catch " + String(eI0)); }
|
||||
|
||||
var key = safeStr(it.pkg) + "@" + safeStr(it.id) + "@" + safeStr(it.userId);
|
||||
var cached = cacheGet(key);
|
||||
if (cached) {
|
||||
try { iv.setImageDrawable(cached); } catch(eIC) {}
|
||||
try { iv.setImageDrawable(cached); } catch(eIC) { safeLog(null, 'e', "catch " + String(eIC)); }
|
||||
} else {
|
||||
enqueueIconLoad(it, iv, key);
|
||||
}
|
||||
@@ -722,8 +722,8 @@ function cacheGet(key) {
|
||||
var tv1 = new android.widget.TextView(context);
|
||||
tv1.setText(safeStr(it.label || it.id || it.pkg));
|
||||
tv1.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
try { tv1.setTypeface(null, android.graphics.Typeface.BOLD); } catch(eB) {}
|
||||
try { tv1.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(eC1) {}
|
||||
try { tv1.setTypeface(null, android.graphics.Typeface.BOLD); } catch(eB) { safeLog(null, 'e', "catch " + String(eB)); }
|
||||
try { tv1.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); }
|
||||
tv1.setSingleLine(true);
|
||||
tv1.setEllipsize(android.text.TextUtils.TruncateAt.END);
|
||||
col.addView(tv1);
|
||||
@@ -733,7 +733,7 @@ function cacheGet(key) {
|
||||
tv2.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11);
|
||||
tv2.setSingleLine(true);
|
||||
tv2.setEllipsize(android.text.TextUtils.TruncateAt.END);
|
||||
try { tv2.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC2) {}
|
||||
try { tv2.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); }
|
||||
col.addView(tv2);
|
||||
|
||||
// # pick 模式:额外显示 userId,避免多用户/工作资料混淆
|
||||
@@ -742,7 +742,7 @@ function cacheGet(key) {
|
||||
tv3.setText("userId: " + safeStr(it.userId));
|
||||
tv3.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 10);
|
||||
tv3.setSingleLine(true);
|
||||
try { tv3.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC3) {}
|
||||
try { tv3.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC3) { safeLog(null, 'e', "catch " + String(eC3)); }
|
||||
col.addView(tv3);
|
||||
}
|
||||
|
||||
@@ -771,7 +771,7 @@ function cacheGet(key) {
|
||||
} catch(eStart) {
|
||||
self.toast("启动失败: " + eStart);
|
||||
}
|
||||
} catch(eClick) {}
|
||||
} catch(eClick) { safeLog(null, 'e', "catch " + String(eClick)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -817,7 +817,7 @@ function cacheGet(key) {
|
||||
|
||||
tv.setTextColor(isSel ? tPri : tSec);
|
||||
tv.setBackground(self.ui.createStrokeDrawable(bgColor, stroke, self.dp(1), self.dp(16)));
|
||||
} catch(eBg) {}
|
||||
} catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); }
|
||||
|
||||
tv.setOnClickListener(new android.view.View.OnClickListener({
|
||||
onClick: function() {
|
||||
@@ -835,7 +835,7 @@ function cacheGet(key) {
|
||||
state.tabRow.addView(tv);
|
||||
})(order[i]);
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
function startScrollPoll() {
|
||||
@@ -862,7 +862,7 @@ function cacheGet(key) {
|
||||
appendBatch();
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
schedule();
|
||||
});
|
||||
}
|
||||
@@ -870,7 +870,7 @@ function cacheGet(key) {
|
||||
function schedule() {
|
||||
try {
|
||||
h.postDelayed(new JavaAdapter(Runnable, { run: tick }), 180);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
schedule();
|
||||
@@ -889,8 +889,8 @@ function cacheGet(key) {
|
||||
var title = new android.widget.TextView(context);
|
||||
title.setText(mode === "pick" ? "选择快捷方式" : "快捷方式浏览器");
|
||||
title.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 16);
|
||||
try { title.setTypeface(null, android.graphics.Typeface.BOLD); } catch(e) {}
|
||||
try { title.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(e) {}
|
||||
try { title.setTypeface(null, android.graphics.Typeface.BOLD); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
try { title.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var lpT = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
lpT.weight = 1;
|
||||
@@ -903,7 +903,7 @@ function cacheGet(key) {
|
||||
try {
|
||||
btnClose.setPadding(self.dp(12), self.dp(6), self.dp(12), self.dp(6));
|
||||
btnClose.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 13);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
top.addView(title);
|
||||
top.addView(btnClose);
|
||||
@@ -916,12 +916,12 @@ function cacheGet(key) {
|
||||
try {
|
||||
et.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight);
|
||||
et.setHintTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
try {
|
||||
var inBg = self.ui.createRoundDrawable(self.isDarkTheme() ? self.ui.colors.inputBgDark : self.ui.colors.inputBgLight, self.dp(12));
|
||||
et.setBackground(inBg);
|
||||
} catch(eBg) {}
|
||||
} catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); }
|
||||
|
||||
// # Tabs(横向滚动:统一为"胶囊按钮"风格,选中态更明确)
|
||||
var tabSv = new android.widget.HorizontalScrollView(context);
|
||||
@@ -930,13 +930,13 @@ function cacheGet(key) {
|
||||
|
||||
var tabRow = new android.widget.LinearLayout(context);
|
||||
tabRow.setOrientation(android.widget.LinearLayout.HORIZONTAL);
|
||||
try { tabRow.setPadding(0, self.dp(8), 0, self.dp(6)); } catch(e) {}
|
||||
try { tabRow.setPadding(0, self.dp(8), 0, self.dp(6)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
tabSv.addView(tabRow);
|
||||
|
||||
// # 状态栏(数量/渲染进度)
|
||||
var tvStat = new android.widget.TextView(context);
|
||||
tvStat.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12);
|
||||
try { tvStat.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(e) {}
|
||||
try { tvStat.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
tvStat.setPadding(0, self.dp(6), 0, self.dp(6));
|
||||
|
||||
// # 列表(卡片式条目列表)
|
||||
@@ -946,7 +946,7 @@ function cacheGet(key) {
|
||||
|
||||
var list = new android.widget.LinearLayout(context);
|
||||
list.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||
try { list.setPadding(0, self.dp(2), 0, self.dp(2)); } catch(e) {}
|
||||
try { list.setPadding(0, self.dp(2), 0, self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
sv.addView(list);
|
||||
|
||||
// bind
|
||||
@@ -970,10 +970,10 @@ function cacheGet(key) {
|
||||
rebuildRenderList();
|
||||
clearGrid();
|
||||
appendBatch();
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}));
|
||||
} catch(eTw) {}
|
||||
} catch(eTw) { safeLog(null, 'e', "catch " + String(eTw)); }
|
||||
|
||||
// layout
|
||||
root.addView(top);
|
||||
@@ -983,7 +983,7 @@ function cacheGet(key) {
|
||||
var lpEt = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
lpEt.setMargins(0, 0, 0, self.dp(8));
|
||||
et.setLayoutParams(lpEt);
|
||||
} catch(eLpEt) {}
|
||||
} catch(eLpEt) { safeLog(null, 'e', "catch " + String(eLpEt)); }
|
||||
root.addView(et);
|
||||
|
||||
root.addView(tabSv);
|
||||
@@ -995,7 +995,7 @@ function cacheGet(key) {
|
||||
root.addView(sv);
|
||||
|
||||
// 主题:用 ToolHub 现有的背景更新逻辑兜底(防止外部主题配置影响)
|
||||
try { self.updatePanelBackground(root); } catch(eTheme) {}
|
||||
try { self.updatePanelBackground(root); } catch(eTheme) { safeLog(null, 'e', "catch " + String(eTheme)); }
|
||||
|
||||
return root;
|
||||
}
|
||||
@@ -1018,19 +1018,19 @@ function cacheGet(key) {
|
||||
try {
|
||||
state.params.softInputMode = android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
|
||||
| android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
|
||||
} catch(eSIM1) {}
|
||||
} catch(eSIM1) { safeLog(null, 'e', "catch " + String(eSIM1)); }
|
||||
try {
|
||||
state.params.flags = state.params.flags
|
||||
| android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
} catch(eTop1) {}
|
||||
} catch(eTop1) { safeLog(null, 'e', "catch " + String(eTop1)); }
|
||||
var sw2 = (self.state && self.state.screen && self.state.screen.w) ? self.state.screen.w : 0;
|
||||
if (sw2 > 0) state.params.x = Math.max(0, Math.round((sw2 - state.params.width) / 2));
|
||||
else state.params.x = 0;
|
||||
state.params.y = 0;
|
||||
wm.updateViewLayout(state.root, state.params);
|
||||
}
|
||||
} catch(ePos2) {}
|
||||
} catch(ePos2) { safeLog(null, 'e', "catch " + String(ePos2)); }
|
||||
|
||||
// # 层级修复:同类型(TYPE_APPLICATION_OVERLAY)窗口之间的上下层由 addView 顺序决定
|
||||
// # 说明:当"新增按钮页/主面板"在本窗口之后 addView 时,会把本窗口盖住;复用 show 仅 setVisibility 无法提升层级
|
||||
@@ -1039,16 +1039,16 @@ function cacheGet(key) {
|
||||
var tsNow = now();
|
||||
if (!state.lastRaiseTs || (tsNow - state.lastRaiseTs) > 300) {
|
||||
state.lastRaiseTs = tsNow;
|
||||
try { wm.removeViewImmediate(state.root); } catch(eZ0) {}
|
||||
try { wm.addView(state.root, state.params); } catch(eZ1) {}
|
||||
try { wm.removeViewImmediate(state.root); } catch(eZ0) { safeLog(null, 'e', "catch " + String(eZ0)); }
|
||||
try { wm.addView(state.root, state.params); } catch(eZ1) { safeLog(null, 'e', "catch " + String(eZ1)); }
|
||||
state.isAdded = true;
|
||||
}
|
||||
} catch(eZ2) {}
|
||||
try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {}
|
||||
} catch(eZ2) { safeLog(null, 'e', "catch " + String(eZ2)); }
|
||||
try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) { safeLog(null, 'e', "catch " + String(eVis)); }
|
||||
try {
|
||||
setStat("正在加载快捷方式...");
|
||||
Li("reloading shortcuts index...");
|
||||
} catch(e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
try {
|
||||
state.allItems = buildShortcutItemsIndex();
|
||||
var gg = groupItems(state.allItems);
|
||||
@@ -1060,11 +1060,11 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {}
|
||||
state.groupOrder = ["__ALL__"];
|
||||
Le("build index err=" + String(e1));
|
||||
}
|
||||
try { setupTabs(); } catch(eT0) {}
|
||||
try { rebuildRenderList(); } catch(eT1) {}
|
||||
try { clearGrid(); } catch(eT2) {}
|
||||
try { appendBatch(); } catch(eT3) {}
|
||||
try { startScrollPoll(); } catch(eT4) {}
|
||||
try { setupTabs(); } catch(eT0) { safeLog(null, 'e', "catch " + String(eT0)); }
|
||||
try { rebuildRenderList(); } catch(eT1) { safeLog(null, 'e', "catch " + String(eT1)); }
|
||||
try { clearGrid(); } catch(eT2) { safeLog(null, 'e', "catch " + String(eT2)); }
|
||||
try { appendBatch(); } catch(eT3) { safeLog(null, 'e', "catch " + String(eT3)); }
|
||||
try { startScrollPoll(); } catch(eT4) { safeLog(null, 'e', "catch " + String(eT4)); }
|
||||
Li("shortcut picker reused items=" + String(state.allItems.length));
|
||||
return;
|
||||
}
|
||||
@@ -1073,7 +1073,7 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {}
|
||||
// build data
|
||||
setStat("正在加载快捷方式...");
|
||||
Li("loading shortcuts index...");
|
||||
} catch(e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
|
||||
try {
|
||||
state.allItems = buildShortcutItemsIndex();
|
||||
@@ -1102,13 +1102,13 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {}
|
||||
try {
|
||||
p.softInputMode = android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
|
||||
| android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
|
||||
} catch(eSIM0) {}
|
||||
} catch(eSIM0) { safeLog(null, 'e', "catch " + String(eSIM0)); }
|
||||
// # 允许窗口覆盖到屏幕顶部区域(含状态栏区域),避免视觉上"不是贴顶"
|
||||
try {
|
||||
p.flags = p.flags
|
||||
| android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
|
||||
| android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
} catch(eTop0) {}
|
||||
} catch(eTop0) { safeLog(null, 'e', "catch " + String(eTop0)); }
|
||||
p.width = self.dp(340);
|
||||
p.height = self.dp(520);
|
||||
// # UI 修复:选择快捷方式页应贴近屏幕顶部显示(与"新增按钮页"的顶部布局一致),而不是居中
|
||||
@@ -1128,7 +1128,7 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {}
|
||||
// 允许输入法:搜索框要能聚焦
|
||||
try {
|
||||
p.flags = p.flags & (~android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
} catch(eF) {}
|
||||
} catch(eF) { safeLog(null, 'e', "catch " + String(eF)); }
|
||||
|
||||
state.params = p;
|
||||
|
||||
@@ -1161,15 +1161,15 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {}
|
||||
var o = newOpts || {};
|
||||
mode = (o.mode != null) ? String(o.mode) : mode;
|
||||
onPick = (typeof o.onPick === "function") ? o.onPick : onPick;
|
||||
} catch(eOpt) {}
|
||||
} catch(eOpt) { safeLog(null, 'e', "catch " + String(eOpt)); }
|
||||
// # 显示前先把隐藏标记清掉
|
||||
try { state.hidden = false; } catch(eH0) {}
|
||||
try { state.hidden = false; } catch(eH0) { safeLog(null, 'e', "catch " + String(eH0)); }
|
||||
show();
|
||||
},
|
||||
hide: hide,
|
||||
destroy: destroy
|
||||
};
|
||||
try { self.__shortcutPickerSingleton = api; } catch(eSet) {}
|
||||
try { self.__shortcutPickerSingleton = api; } catch(eSet) { safeLog(null, 'e', "catch " + String(eSet)); }
|
||||
api.show(opts);
|
||||
};
|
||||
|
||||
@@ -1196,7 +1196,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
self.__iconPickerSingleton.show(opts);
|
||||
return;
|
||||
}
|
||||
} catch(eSingle) {}
|
||||
} catch(eSingle) { safeLog(null, 'e', "catch " + String(eSingle)); }
|
||||
|
||||
// # 获取图标列表
|
||||
var allIcons = [];
|
||||
@@ -1207,7 +1207,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
}
|
||||
if (!allIcons || allIcons.length === 0) {
|
||||
self.toast("无法加载 ShortX 图标库");
|
||||
if (onDismiss) try { onDismiss(); } catch(eD) {}
|
||||
if (onDismiss) try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1237,8 +1237,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
totalPages: 1
|
||||
};
|
||||
|
||||
function Li(msg) { try { if (self.L) self.L.i("[iconPicker] " + msg); } catch(e) {} }
|
||||
function Le(msg) { try { if (self.L) self.L.e("[iconPicker] " + msg); } catch(e) {} }
|
||||
function Li(msg) { try { if (self.L) self.L.i("[iconPicker] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
function Le(msg) { try { if (self.L) self.L.e("[iconPicker] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }
|
||||
|
||||
// # 列数自适应计算
|
||||
function computeColumns() {
|
||||
@@ -1292,14 +1292,14 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
// # 过滤
|
||||
function filterIcons(q) {
|
||||
var qLower = "";
|
||||
try { qLower = String(q || "").toLowerCase(); } catch(e) {}
|
||||
try { qLower = String(q || "").toLowerCase(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
if (!qLower) return allIcons.slice();
|
||||
var out = [];
|
||||
for (var i = 0; i < allIcons.length; i++) {
|
||||
var ic = allIcons[i];
|
||||
if (!ic) continue;
|
||||
var name = "";
|
||||
try { name = String(ic.shortName || ic.name || "").toLowerCase(); } catch(e) {}
|
||||
try { name = String(ic.shortName || ic.name || "").toLowerCase(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
if (name.indexOf(qLower) >= 0) out.push(ic);
|
||||
}
|
||||
return out;
|
||||
@@ -1316,8 +1316,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
// 滚回顶部
|
||||
try {
|
||||
if (state.scrollView) state.scrollView.scrollTo(0, 0);
|
||||
} catch(eScroll) {}
|
||||
} catch(e) {}
|
||||
} catch(eScroll) { safeLog(null, 'e', "catch " + String(eScroll)); }
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// # 更新统计/页码显示
|
||||
@@ -1345,11 +1345,11 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
child.setEnabled(state.currentPage < state.totalPages - 1);
|
||||
child.setAlpha(state.currentPage < state.totalPages - 1 ? 1.0 : 0.35);
|
||||
}
|
||||
} catch(eTag) {}
|
||||
} catch(eTag) { safeLog(null, 'e', "catch " + String(eTag)); }
|
||||
}
|
||||
}
|
||||
} catch(eBar) {}
|
||||
} catch(e) {}
|
||||
} catch(eBar) { safeLog(null, 'e', "catch " + String(eBar)); }
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// # 构建网格(只渲染当前页)
|
||||
@@ -1397,8 +1397,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
try {
|
||||
var dr = self.resolveShortXDrawable(iconInfo.name);
|
||||
if (dr) iv.setImageDrawable(dr);
|
||||
} catch(eIcon) {}
|
||||
try { iv.setScaleType(android.widget.ImageView.ScaleType.CENTER_INSIDE); } catch(e) {}
|
||||
} catch(eIcon) { safeLog(null, 'e', "catch " + String(eIcon)); }
|
||||
try { iv.setScaleType(android.widget.ImageView.ScaleType.CENTER_INSIDE); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var ivLp = new android.widget.LinearLayout.LayoutParams(self.dp(cellSizeDp), self.dp(cellSizeDp));
|
||||
iv.setLayoutParams(ivLp);
|
||||
cell.addView(iv);
|
||||
@@ -1406,13 +1406,13 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
// 文字
|
||||
var tv = new android.widget.TextView(context);
|
||||
var label = "";
|
||||
try { label = String(iconInfo.shortName || iconInfo.name || ""); } catch(e) {}
|
||||
try { label = String(iconInfo.shortName || iconInfo.name || ""); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
if (label.length > 10) label = label.substring(0, 9) + "…";
|
||||
tv.setText(label);
|
||||
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, labelSizeSp);
|
||||
tv.setTextColor(textColor);
|
||||
tv.setGravity(android.view.Gravity.CENTER);
|
||||
try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(e) {}
|
||||
try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var tvLp = new android.widget.LinearLayout.LayoutParams(
|
||||
android.widget.LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
@@ -1436,7 +1436,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
self.touchActivity();
|
||||
if (onPick) onPick(iconInfo.name);
|
||||
hide();
|
||||
} catch(eClick) {}
|
||||
} catch(eClick) { safeLog(null, 'e', "catch " + String(eClick)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -1459,7 +1459,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
state.totalPages = Math.max(1, Math.ceil(state.filteredIcons.length / state.itemsPerPage));
|
||||
state.currentPage = 0;
|
||||
buildGrid();
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// # 隐藏
|
||||
@@ -1475,12 +1475,12 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
var imm = context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm) imm.hideSoftInputFromWindow(state.etSearch.getWindowToken(), 0);
|
||||
}
|
||||
} catch(eK) {}
|
||||
} catch(eK) { safeLog(null, 'e', "catch " + String(eK)); }
|
||||
|
||||
// 隐藏 View
|
||||
try {
|
||||
if (state.root) state.root.setVisibility(android.view.View.GONE);
|
||||
} catch(eV) {}
|
||||
} catch(eV) { safeLog(null, 'e', "catch " + String(eV)); }
|
||||
|
||||
// 通知外层
|
||||
try {
|
||||
@@ -1488,10 +1488,10 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
state.onDismissCalled = true;
|
||||
state.onDismiss();
|
||||
}
|
||||
} catch(eD) {}
|
||||
} catch(eD) { safeLog(null, 'e', "catch " + String(eD)); }
|
||||
|
||||
Li("icon picker hidden");
|
||||
} catch(eHide) {}
|
||||
} catch(eHide) { safeLog(null, 'e', "catch " + String(eHide)); }
|
||||
}
|
||||
|
||||
// # 销毁
|
||||
@@ -1507,7 +1507,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
if (state.isAdded && state.root) {
|
||||
wm.removeView(state.root);
|
||||
}
|
||||
} catch(eR) {}
|
||||
} catch(eR) { safeLog(null, 'e', "catch " + String(eR)); }
|
||||
|
||||
state.isAdded = false;
|
||||
state.root = null;
|
||||
@@ -1515,10 +1515,10 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
if (self.__currentIconSession === currentSession) {
|
||||
self.__currentIconSession = null;
|
||||
}
|
||||
try { self.__iconPickerSingleton = null; } catch(eS) {}
|
||||
try { self.__iconPickerSingleton = null; } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
|
||||
Li("icon picker destroyed");
|
||||
} catch(eDes) {}
|
||||
} catch(eDes) { safeLog(null, 'e', "catch " + String(eDes)); }
|
||||
}
|
||||
|
||||
// # 显示(关键修复:正确处理隐藏后重新显示)
|
||||
@@ -1550,7 +1550,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
|
||||
// 如果 root 存在但未添加(不应该发生),清掉重建
|
||||
if (state.root && !state.isAdded) {
|
||||
try { state.root = null; } catch(e) {}
|
||||
try { state.root = null; } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
// ========== 新建面板 ==========
|
||||
@@ -1585,7 +1585,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
} catch(eOut) {}
|
||||
} catch(eOut) { safeLog(null, 'e', "catch " + String(eOut)); }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1598,7 +1598,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
bgDr.setColor(bgColor);
|
||||
bgDr.setCornerRadius(self.dp(16));
|
||||
panel.setBackground(bgDr);
|
||||
try { panel.setElevation(self.dp(8)); } catch(e) {}
|
||||
try { panel.setElevation(self.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
panel.setPadding(self.dp(16), self.dp(12), self.dp(16), self.dp(12));
|
||||
|
||||
var panelLp = new android.widget.FrameLayout.LayoutParams(panelW, android.widget.FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
@@ -1656,7 +1656,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
|
||||
var et = new android.widget.EditText(context);
|
||||
et.setHint("搜索图标名称...");
|
||||
try { et.setHintTextColor(subTextColor); } catch(e) {}
|
||||
try { et.setHintTextColor(subTextColor); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
et.setTextColor(textColor);
|
||||
et.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
et.setBackground(null);
|
||||
@@ -1671,7 +1671,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
try {
|
||||
state.query = String(s || "");
|
||||
rebuild();
|
||||
} catch(eTxt) {}
|
||||
} catch(eTxt) { safeLog(null, 'e', "catch " + String(eTxt)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -1689,7 +1689,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
et.setText("");
|
||||
state.query = "";
|
||||
rebuild();
|
||||
} catch(eClr) {}
|
||||
} catch(eClr) { safeLog(null, 'e', "catch " + String(eClr)); }
|
||||
}
|
||||
}));
|
||||
searchBox.addView(btnClear);
|
||||
@@ -1698,8 +1698,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
|
||||
// --- 滚动区域 ---
|
||||
var scroll = new android.widget.ScrollView(context);
|
||||
try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(e) {}
|
||||
try { scroll.setVerticalScrollBarEnabled(false); } catch(e) {}
|
||||
try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
try { scroll.setVerticalScrollBarEnabled(false); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var grid = new android.widget.GridLayout(context);
|
||||
state.grid = grid;
|
||||
@@ -1754,11 +1754,11 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
self.dp(6)
|
||||
);
|
||||
btn.setBackground(btnBg);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
btn.setClickable(true);
|
||||
btn.setOnClickListener(new android.view.View.OnClickListener({
|
||||
onClick: function() {
|
||||
try { self.touchActivity(); } catch(e) {}
|
||||
try { self.touchActivity(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
onClick();
|
||||
}
|
||||
}));
|
||||
@@ -1806,7 +1806,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
} catch(eAdd) {
|
||||
Le("addView failed: " + String(eAdd));
|
||||
self.toast("图标选择器打开失败");
|
||||
if (onDismiss) try { onDismiss(); } catch(eD) {}
|
||||
if (onDismiss) try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1825,7 +1825,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
.setDuration(180)
|
||||
.setInterpolator(new android.view.animation.AccelerateDecelerateInterpolator())
|
||||
.start();
|
||||
} catch(eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
|
||||
// 初始渲染(会计算分页)
|
||||
rebuild();
|
||||
@@ -1842,14 +1842,14 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) {
|
||||
onDismiss = (typeof o.onDismiss === "function") ? o.onDismiss : onDismiss;
|
||||
state.onDismiss = onDismiss;
|
||||
state.onDismissCalled = false;
|
||||
} catch(eOpt) {}
|
||||
} catch(eOpt) { safeLog(null, 'e', "catch " + String(eOpt)); }
|
||||
// 不在这里设置 state.hidden = false!让内部 show() 自己判断是隐藏重显还是新建
|
||||
show();
|
||||
},
|
||||
hide: hide,
|
||||
destroy: destroy
|
||||
};
|
||||
try { self.__iconPickerSingleton = api; } catch(eSet) {}
|
||||
try { self.__iconPickerSingleton = api; } catch(eSet) { safeLog(null, 'e', "catch " + String(eSet)); }
|
||||
api.show(opts);
|
||||
};
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ FloatBallAppWM.prototype.contentQueryToText = function(uriStr, projection, selec
|
||||
out.err = String(e);
|
||||
return out;
|
||||
} finally {
|
||||
try { if (cur) cur.close(); } catch (eC) {}
|
||||
try { if (cur) cur.close(); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC
|
||||
// 0.7 的张力适中,不会过于夸张
|
||||
va.setInterpolator(new android.view.animation.OvershootInterpolator(0.7));
|
||||
} catch (eI) {
|
||||
try { va.setInterpolator(new android.view.animation.DecelerateInterpolator()); } catch (eI2) {}
|
||||
try { va.setInterpolator(new android.view.animation.DecelerateInterpolator()); } catch(eI2) { safeLog(null, 'e', "catch " + String(eI2)); }
|
||||
}
|
||||
|
||||
var self = this;
|
||||
@@ -41,15 +41,18 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC
|
||||
self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp);
|
||||
}, true, self.L);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}));
|
||||
|
||||
va.addListener(new android.animation.Animator.AnimatorListener({
|
||||
onAnimationStart: function() {},
|
||||
onAnimationRepeat: function() {},
|
||||
onAnimationCancel: function() {},
|
||||
onAnimationCancel: function() {
|
||||
try { self.state.ballAnimator = null; } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
},
|
||||
onAnimationEnd: function() {
|
||||
try { self.state.ballAnimator = null; } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
try {
|
||||
if (!self.state.closing && self.state.addedBall) {
|
||||
self.state.ballLp.x = toX;
|
||||
@@ -58,11 +61,12 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC
|
||||
self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp);
|
||||
self.savePos(self.state.ballLp.x, self.state.ballLp.y);
|
||||
}
|
||||
} catch (e2) {}
|
||||
try { if (endCb) endCb(); } catch (eCb) { try { if (self && self.L && self.L.e) self.L.e("animateBallLayout endCb err=" + String(eCb)); } catch (eLog) {} }
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
try { if (endCb) endCb(); } catch (eCb) { try { if (self && self.L && self.L.e) self.L.e("animateBallLayout endCb err=" + String(eCb)); } catch(eLog) { safeLog(null, 'e', "catch " + String(eLog)); } }
|
||||
}
|
||||
}));
|
||||
|
||||
this.state.ballAnimator = va;
|
||||
va.start();
|
||||
} catch (e0) {
|
||||
try {
|
||||
@@ -71,8 +75,8 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC
|
||||
st.ballLp.width = toW;
|
||||
st.wm.updateViewLayout(st.ballRoot, st.ballLp);
|
||||
this.savePos(st.ballLp.x, st.ballLp.y);
|
||||
} catch (e1) {}
|
||||
try { if (endCb) endCb(); } catch (eCb2) { try { if (this && this.L && this.L.e) this.L.e("animateBallLayout endCb err=" + String(eCb2)); } catch (eLog2) {} }
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
try { if (endCb) endCb(); } catch (eCb2) { try { if (this && this.L && this.L.e) this.L.e("animateBallLayout endCb err=" + String(eCb2)); } catch(eLog2) { safeLog(null, 'e', "catch " + String(eLog2)); } }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -80,7 +84,7 @@ FloatBallAppWM.prototype.playBounce = function(v) {
|
||||
if (!this.config.ENABLE_BOUNCE) return;
|
||||
if (!this.config.ENABLE_ANIMATIONS) return;
|
||||
|
||||
try { v.animate().cancel(); } catch (e0) {}
|
||||
try { v.animate().cancel(); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
|
||||
var self = this;
|
||||
var i = 0;
|
||||
@@ -89,7 +93,7 @@ FloatBallAppWM.prototype.playBounce = function(v) {
|
||||
if (self.state.closing) return;
|
||||
|
||||
if (i >= self.config.BOUNCE_TIMES) {
|
||||
try { v.setScaleX(1); v.setScaleY(1); } catch (e2) {}
|
||||
try { v.setScaleX(1); v.setScaleY(1); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,12 +206,12 @@ FloatBallAppWM.prototype.clearHeavyCaches = function(reason) {
|
||||
}
|
||||
this.state[cacheKey] = now;
|
||||
|
||||
try { this._iconLru = null; } catch (eLruClr) {}
|
||||
try { this._shortcutIconFailTs = {}; } catch (e2) {}
|
||||
try { this._iconLru = null; } catch(eLruClr) { safeLog(null, 'e', "catch " + String(eLruClr)); }
|
||||
try { this._shortcutIconFailTs = {}; } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
|
||||
// # Shortcuts 相关全局缓存(按钮编辑页/快捷方式选择器可能会创建)
|
||||
try { if (typeof __scIconCache !== "undefined") __scIconCache = {}; } catch (e3) {}
|
||||
try { if (typeof __scAppLabelCache !== "undefined") __scAppLabelCache = {}; } catch (e4) {}
|
||||
try { if (typeof __scIconCache !== "undefined") __scIconCache = {}; } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); }
|
||||
try { if (typeof __scAppLabelCache !== "undefined") __scAppLabelCache = {}; } catch(e4) { safeLog(null, 'e', "catch " + String(e4)); }
|
||||
|
||||
// # 记录一次清理日志(精简:只记录关键 reason,且 5秒防抖)
|
||||
var keyReasons = ["memory_pressure", "screen_changed", "close"];
|
||||
@@ -216,7 +220,7 @@ FloatBallAppWM.prototype.clearHeavyCaches = function(reason) {
|
||||
if (isKeyReason && this.L && this.L.i) {
|
||||
this.L.i("clearHeavyCaches reason=" + String(reason));
|
||||
}
|
||||
} catch (e5) {}
|
||||
} catch(e5) { safeLog(null, 'e', "catch " + String(e5)); }
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype._clearHeavyCachesIfAllHidden = function(reason) {
|
||||
@@ -225,7 +229,7 @@ FloatBallAppWM.prototype._clearHeavyCachesIfAllHidden = function(reason) {
|
||||
if (!this.state.addedPanel && !this.state.addedSettings && !this.state.addedViewer) {
|
||||
this.clearHeavyCaches(reason || "all_hidden");
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.hideAllPanels = function() {
|
||||
@@ -287,7 +291,7 @@ FloatBallAppWM.prototype.showMask = function() {
|
||||
} else {
|
||||
mask.setAlpha(1);
|
||||
}
|
||||
} catch(eAnim){}
|
||||
} catch(eAnim) { safeLog(null, 'e', "catch " + String(eAnim)); }
|
||||
|
||||
} catch (e1) {
|
||||
safeLog(this.L, 'e', "add mask fail err=" + String(e1));
|
||||
@@ -322,7 +326,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) {
|
||||
this.state.dockSide = "left";
|
||||
this.state.docked = true;
|
||||
|
||||
try { this.state.ballContent.setX(-hidden); } catch (eL) {}
|
||||
try { this.state.ballContent.setX(-hidden); } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); }
|
||||
|
||||
if (withAnim) {
|
||||
this.animateBallLayout(0, targetY, targetW, this.config.DOCK_ANIM_MS, null);
|
||||
@@ -330,7 +334,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) {
|
||||
this.state.ballLp.x = 0;
|
||||
this.state.ballLp.y = targetY;
|
||||
this.state.ballLp.width = targetW;
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU1) {}
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU1) { safeLog(null, 'e', "catch " + String(eU1)); }
|
||||
this.savePos(this.state.ballLp.x, this.state.ballLp.y);
|
||||
}
|
||||
|
||||
@@ -343,7 +347,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) {
|
||||
} else {
|
||||
this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA);
|
||||
}
|
||||
} catch(eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -351,7 +355,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) {
|
||||
this.state.dockSide = "right";
|
||||
this.state.docked = true;
|
||||
|
||||
try { this.state.ballContent.setX(0); } catch (eR) {}
|
||||
try { this.state.ballContent.setX(0); } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); }
|
||||
|
||||
var x2 = this.state.screen.w - visible;
|
||||
|
||||
@@ -361,7 +365,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) {
|
||||
this.state.ballLp.x = x2;
|
||||
this.state.ballLp.y = targetY;
|
||||
this.state.ballLp.width = targetW;
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU2) {}
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU2) { safeLog(null, 'e', "catch " + String(eU2)); }
|
||||
this.savePos(this.state.ballLp.x, this.state.ballLp.y);
|
||||
}
|
||||
|
||||
@@ -380,7 +384,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) {
|
||||
} else {
|
||||
this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA);
|
||||
}
|
||||
} catch(eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
@@ -393,7 +397,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
var targetW = ballSize;
|
||||
var targetY = this.clamp(this.state.ballLp.y, 0, this.state.screen.h - ballSize);
|
||||
|
||||
try { this.state.ballContent.setX(0); } catch (e0) {}
|
||||
try { this.state.ballContent.setX(0); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
|
||||
if (this.state.dockSide === "left") {
|
||||
this.state.docked = false;
|
||||
@@ -404,7 +408,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
this.state.ballLp.x = 0;
|
||||
this.state.ballLp.y = targetY;
|
||||
this.state.ballLp.width = targetW;
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU1) {}
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU1) { safeLog(null, 'e', "catch " + String(eU1)); }
|
||||
this.savePos(this.state.ballLp.x, this.state.ballLp.y);
|
||||
if (endCb) endCb();
|
||||
}
|
||||
@@ -416,7 +420,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
} else {
|
||||
this.state.ballContent.setAlpha(1.0);
|
||||
}
|
||||
} catch(eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
|
||||
safeLog(this.L, 'i', "undock from left");
|
||||
return;
|
||||
@@ -432,7 +436,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
this.state.ballLp.x = x;
|
||||
this.state.ballLp.y = targetY;
|
||||
this.state.ballLp.width = targetW;
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU2) {}
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU2) { safeLog(null, 'e', "catch " + String(eU2)); }
|
||||
this.savePos(this.state.ballLp.x, this.state.ballLp.y);
|
||||
if (endCb) endCb();
|
||||
}
|
||||
@@ -444,7 +448,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
} else {
|
||||
this.state.ballContent.setAlpha(1.0);
|
||||
}
|
||||
} catch(eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
|
||||
// # 日志精简:undock 事件改为 INFO 级别,且记录方向
|
||||
var undockSide = this.state.dockSide || "right";
|
||||
@@ -452,7 +456,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) {
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.cancelDockTimer = function() {
|
||||
try { if (this.state.idleDockRunnable && this.state.h) this.state.h.removeCallbacks(this.state.idleDockRunnable); } catch (e) {}
|
||||
try { if (this.state.idleDockRunnable && this.state.h) this.state.h.removeCallbacks(this.state.idleDockRunnable); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
this.state.idleDockRunnable = null;
|
||||
};
|
||||
|
||||
@@ -518,7 +522,7 @@ FloatBallAppWM.prototype.guardClick = function(key, cooldownMs, fn) {
|
||||
return true;
|
||||
} catch (e0) {
|
||||
// 兜底:绝不让点击回调异常冒泡到 system_server
|
||||
try { fn && fn(); } catch (e2) {}
|
||||
try { fn && fn(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -576,22 +580,22 @@ FloatBallAppWM.prototype.onScreenChangedReflow = function() {
|
||||
|
||||
if (this.state.dockSide === "left") {
|
||||
this.state.ballLp.x = 0;
|
||||
try { this.state.ballContent.setX(-hidden); } catch (eL) {}
|
||||
try { this.state.ballContent.setX(-hidden); } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); }
|
||||
} else {
|
||||
this.state.ballLp.x = newW - visible;
|
||||
try { this.state.ballContent.setX(0); } catch (eR) {}
|
||||
try { this.state.ballContent.setX(0); } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); }
|
||||
}
|
||||
// 重新进入闲置变暗逻辑(如果需要)
|
||||
try { this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA); } catch(eA) {}
|
||||
try { this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
} else {
|
||||
this.state.ballLp.x = mappedX;
|
||||
this.state.ballLp.y = mappedY;
|
||||
this.state.ballLp.width = ballSize;
|
||||
try { this.state.ballContent.setX(0); } catch (e0) {}
|
||||
try { this.state.ballContent.setAlpha(1.0); } catch(eA) {}
|
||||
try { this.state.ballContent.setX(0); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
try { this.state.ballContent.setAlpha(1.0); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
}
|
||||
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU) {}
|
||||
try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); }
|
||||
this.savePos(this.state.ballLp.x, this.state.ballLp.y);
|
||||
|
||||
safeLog(this.L, 'i', "screen reflow w=" + String(newW) + " h=" + String(newH) + " x=" + String(this.state.ballLp.x) + " y=" + String(this.state.ballLp.y));
|
||||
@@ -642,7 +646,7 @@ FloatBallAppWM.prototype.setupDisplayMonitor = function() {
|
||||
}
|
||||
}
|
||||
}));
|
||||
} catch (e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -655,7 +659,7 @@ FloatBallAppWM.prototype.setupDisplayMonitor = function() {
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.stopDisplayMonitor = function() {
|
||||
try { if (this.state.dm && this.state.displayListener) this.state.dm.unregisterDisplayListener(this.state.displayListener); } catch (e) {}
|
||||
try { if (this.state.dm && this.state.displayListener) this.state.dm.unregisterDisplayListener(this.state.displayListener); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
this.state.displayListener = null;
|
||||
this.state.dm = null;
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ FloatBallAppWM.prototype.execButtonAction = function(btn, idx) {
|
||||
if (lines.length > 1) {
|
||||
content = lines.reverse().join("\n");
|
||||
}
|
||||
} catch(eRev) {}
|
||||
} catch(eRev) { safeLog(null, 'e', "catch " + String(eRev)); }
|
||||
|
||||
this.showViewerPanel("今日日志 (倒序)", content);
|
||||
return;
|
||||
@@ -80,7 +80,7 @@ try {
|
||||
}
|
||||
} catch (eA) {
|
||||
// # 兜底:某些 ROM/权限限制下 startActivityAsUser 可能抛异常,回退普通启动
|
||||
try { context.startActivity(it); } catch (eA2) {}
|
||||
try { context.startActivity(it); } catch(eA2) { safeLog(null, 'e', "catch " + String(eA2)); }
|
||||
this.toast("启动失败");
|
||||
safeLog(this.L, 'e', "start app fail pkg=" + pkg + " uid=" + String(launchUid) + " err=" + String(eA));
|
||||
}
|
||||
@@ -98,7 +98,7 @@ return;
|
||||
try {
|
||||
var b64x = encodeBase64Utf8(cmdPlain);
|
||||
if (b64x && b64x.length > 0) cmdB64 = String(b64x);
|
||||
} catch (eB64a) {}
|
||||
} catch(eB64a) { safeLog(null, 'e', "catch " + String(eB64a)); }
|
||||
}
|
||||
|
||||
// # 2) cmd_b64 非空但无法解码:把它当作"明文命令"重新编码(保证广播桥/Action 都能吃到正确命令)
|
||||
@@ -110,13 +110,13 @@ return;
|
||||
cmdPlain = String(cmdB64);
|
||||
cmdB64 = "";
|
||||
}
|
||||
} catch (eB64b) {}
|
||||
} catch(eB64b) { safeLog(null, 'e', "catch " + String(eB64b)); }
|
||||
}
|
||||
if ((!cmdB64 || cmdB64.length === 0) && cmdPlain && cmdPlain.length > 0) {
|
||||
try {
|
||||
var b64y = encodeBase64Utf8(cmdPlain);
|
||||
if (b64y && b64y.length > 0) cmdB64 = String(b64y);
|
||||
} catch (eB64c) {}
|
||||
} catch(eB64c) { safeLog(null, 'e', "catch " + String(eB64c)); }
|
||||
}
|
||||
|
||||
if (!cmdB64 || cmdB64.length === 0) {
|
||||
@@ -162,7 +162,7 @@ return;
|
||||
else if (typeof v === "boolean") it2.putExtra(String(k), !!v);
|
||||
else it2.putExtra(String(k), String(v));
|
||||
}
|
||||
} catch (eE) {}
|
||||
} catch(eE) { safeLog(null, 'e', "catch " + String(eE)); }
|
||||
}
|
||||
|
||||
// # 3) 对"Shell 广播桥"做额外兼容:
|
||||
@@ -189,7 +189,7 @@ return;
|
||||
cmdB64 = b64x;
|
||||
it2.putExtra(kCmdB64, String(cmdB64));
|
||||
}
|
||||
} catch (eC2) {}
|
||||
} catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); }
|
||||
}
|
||||
|
||||
// # 有 b64 但没明文:也补一份明文(便于外部规则验证;真正执行仍建议用 cmd_b64)
|
||||
@@ -200,7 +200,7 @@ return;
|
||||
cmdPlain = decoded;
|
||||
it2.putExtra("cmd", String(cmdPlain));
|
||||
}
|
||||
} catch (eC3) {}
|
||||
} catch(eC3) { safeLog(null, 'e', "catch " + String(eC3)); }
|
||||
}
|
||||
|
||||
// # root:广播桥接收端默认以 root 执行,强制传递 true
|
||||
@@ -211,7 +211,7 @@ return;
|
||||
} catch (eR0) {
|
||||
try {
|
||||
it2.putExtra(kRoot, true);
|
||||
} catch (eR1) {}
|
||||
} catch(eR1) { safeLog(null, 'e', "catch " + String(eR1)); }
|
||||
}
|
||||
|
||||
|
||||
@@ -230,21 +230,21 @@ return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (eRB) {}
|
||||
} catch(eRB) { safeLog(null, 'e', "catch " + String(eRB)); }
|
||||
|
||||
// # from:标识来源(便于外部执行器做白名单/审计)
|
||||
try {
|
||||
if (!it2.hasExtra(kFrom)) it2.putExtra(kFrom, "ToolHub@system_server");
|
||||
} catch (eF0) { try { it2.putExtra(kFrom, "ToolHub@system_server"); } catch (eF1) {} }
|
||||
} catch (eF0) { try { it2.putExtra(kFrom, "ToolHub@system_server"); } catch(eF1) { safeLog(null, 'e', "catch " + String(eF1)); } }
|
||||
|
||||
if (this.L) {
|
||||
try {
|
||||
this.L.i("broadcast(shell_bridge) action=" + action + " cmd_len=" + String(cmdPlain ? cmdPlain.length : 0) +
|
||||
" cmd_b64_len=" + String(cmdB64 ? cmdB64.length : 0) + " root=" + String(it2.getBooleanExtra(kRoot, false)));
|
||||
} catch (eLg) {}
|
||||
} catch(eLg) { safeLog(null, 'e', "catch " + String(eLg)); }
|
||||
}
|
||||
}
|
||||
} catch (eSB) {}
|
||||
} catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); }
|
||||
|
||||
try { context.sendBroadcast(it2); } catch (eB) { this.toast("广播失败"); safeLog(this.L, 'e', "broadcast fail action=" + action + " err=" + String(eB)); }
|
||||
return;
|
||||
@@ -271,7 +271,7 @@ return;
|
||||
var lu0 = parseInt(String(btn.launchUserId), 10);
|
||||
if (!isNaN(lu0)) uid = lu0;
|
||||
}
|
||||
} catch(eLu0) {}
|
||||
} catch(eLu0) { safeLog(null, 'e', "catch " + String(eLu0)); }
|
||||
|
||||
if (!spkg) { this.toast("按钮#" + idx + " 缺少 pkg"); return; }
|
||||
if (!sid) { this.toast("按钮#" + idx + " 缺少 shortcutId"); return; }
|
||||
@@ -312,7 +312,7 @@ return;
|
||||
this.toast("未知 type=" + t);
|
||||
safeLog(this.L, 'w', "unknown btn type=" + t);
|
||||
} catch (eBtn) {
|
||||
try { this.toast("按钮执行异常"); } catch (e0) {}
|
||||
try { this.toast("按钮执行异常"); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
safeLog(this.L, 'e', "execButtonAction crash idx=" + String(idx) + " err=" + String(eBtn));
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ FloatBallAppWM.prototype.rebuildBallForNewSize = function(keepPanels) {
|
||||
this.state.ballLp = lp;
|
||||
this.state.addedBall = true;
|
||||
} catch (eAdd) {
|
||||
try { this.toast("重建悬浮球失败: " + String(eAdd)); } catch (eT) {}
|
||||
try { this.toast("重建悬浮球失败: " + String(eAdd)); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); }
|
||||
safeLog(this.L, 'e', "rebuildBall add fail err=" + String(eAdd));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
var outValue = new android.util.TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);
|
||||
row.setBackgroundResource(outValue.resourceId);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
row.setPadding(padH, padV, padH, padV);
|
||||
|
||||
@@ -70,7 +70,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
row.addView(tv);
|
||||
|
||||
var sw = new android.widget.Switch(context);
|
||||
try { sw.setTextOn(""); sw.setTextOff(""); } catch (eT) {}
|
||||
try { sw.setTextOn(""); sw.setTextOff(""); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); }
|
||||
|
||||
// 优化开关颜色
|
||||
try {
|
||||
@@ -86,7 +86,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
|
||||
sw.setThumbTintList(thumbList);
|
||||
sw.setTrackTintList(trackList);
|
||||
} catch(eColor) {}
|
||||
} catch(eColor) { safeLog(null, 'e', "catch " + String(eColor)); }
|
||||
|
||||
var cur = !!self.getPendingValue(item.key);
|
||||
sw.setChecked(cur);
|
||||
@@ -98,7 +98,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
self.touchActivity();
|
||||
self.setPendingValue(item.key, !!checked);
|
||||
if (self.L) self.L.d("pending " + String(item.key) + "=" + String(!!checked));
|
||||
} catch (e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -154,7 +154,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
try {
|
||||
sb.getThumb().setTint(primary);
|
||||
sb.getProgressDrawable().setTint(primary);
|
||||
} catch(eColor) {}
|
||||
} catch(eColor) { safeLog(null, 'e', "catch " + String(eColor)); }
|
||||
|
||||
// 配置 SeekBar
|
||||
var min = (item.min !== undefined) ? Number(item.min) : 0;
|
||||
@@ -197,10 +197,10 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
if (fromUser) {
|
||||
self.setPendingValue(item.key, v);
|
||||
}
|
||||
} catch (e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
},
|
||||
onStartTrackingTouch: function() { try { self.touchActivity(); } catch (e2) {} },
|
||||
onStopTrackingTouch: function() { try { self.touchActivity(); } catch (e3) {} }
|
||||
onStartTrackingTouch: function() { try { self.touchActivity(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } },
|
||||
onStopTrackingTouch: function() { try { self.touchActivity(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } }
|
||||
}));
|
||||
|
||||
row.addView(sb);
|
||||
@@ -239,7 +239,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
if (item.action === "open_btn_mgr") {
|
||||
self.showPanelAvoidBall("btn_editor");
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}));
|
||||
row.addView(btn);
|
||||
@@ -252,7 +252,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
if (item.action === "open_btn_mgr") {
|
||||
self.showPanelAvoidBall("btn_editor");
|
||||
}
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -289,7 +289,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
v.requestFocus();
|
||||
var imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(v, 0);
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -300,7 +300,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
try {
|
||||
self.touchActivity();
|
||||
self.setPendingValue(item.key, String(s));
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -338,7 +338,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
var states = [[android.R.attr.state_checked], [-android.R.attr.state_checked]];
|
||||
var colors = [primary, secColor];
|
||||
rb.setButtonTintList(new android.content.res.ColorStateList(states, colors));
|
||||
} catch(eC){}
|
||||
} catch(eC) { safeLog(null, 'e', "catch " + String(eC)); }
|
||||
|
||||
rb.setId(android.view.View.generateViewId ? android.view.View.generateViewId() : i);
|
||||
|
||||
@@ -353,7 +353,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
try {
|
||||
self.touchActivity();
|
||||
self.setPendingValue(item.key, String(opt.value));
|
||||
} catch(e){}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -403,7 +403,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
} else {
|
||||
previewIv.setImageDrawable(null);
|
||||
}
|
||||
} catch(ePreview0) {}
|
||||
} catch(ePreview0) { safeLog(null, 'e', "catch " + String(ePreview0)); }
|
||||
}
|
||||
refreshBallShortXPreview();
|
||||
|
||||
@@ -435,7 +435,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
try {
|
||||
self.setPendingValue(item.key, "");
|
||||
refreshBallShortXPreview();
|
||||
} catch(eClearBallIcon) {}
|
||||
} catch(eClearBallIcon) { safeLog(null, 'e', "catch " + String(eClearBallIcon)); }
|
||||
});
|
||||
iconRow.addView(btnClear);
|
||||
row.addView(iconRow);
|
||||
@@ -478,7 +478,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
colorDot.setBackground(self.ui.createRoundDrawable(0xFFCCCCCC | 0, self.dp(14)));
|
||||
}
|
||||
} catch(eDot0) {
|
||||
try { colorDot.setBackground(self.ui.createRoundDrawable(0xFFCCCCCC | 0, self.dp(14))); } catch(eDot1) {}
|
||||
try { colorDot.setBackground(self.ui.createRoundDrawable(0xFFCCCCCC | 0, self.dp(14))); } catch(eDot1) { safeLog(null, 'e', "catch " + String(eDot1)); }
|
||||
colorValueTv.setText("默认");
|
||||
}
|
||||
}
|
||||
@@ -510,7 +510,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi
|
||||
try {
|
||||
self.setPendingValue(item.key, "");
|
||||
refreshBallColorPreview();
|
||||
} catch(eClearBallColor) {}
|
||||
} catch(eClearBallColor) { safeLog(null, 'e', "catch " + String(eClearBallColor)); }
|
||||
});
|
||||
colorRow.addView(btnClearColor);
|
||||
row.addView(colorRow);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ FloatBallAppWM.prototype.buildViewerPanelView = function(titleText, bodyText) {
|
||||
bgDr.setColor(bgColor);
|
||||
bgDr.setCornerRadius(this.dp(16));
|
||||
panel.setBackground(bgDr);
|
||||
try { panel.setElevation(this.dp(8)); } catch(e){}
|
||||
try { panel.setElevation(this.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
panel.setPadding(
|
||||
this.dp(16),
|
||||
@@ -39,8 +39,8 @@ FloatBallAppWM.prototype.buildViewerPanelView = function(titleText, bodyText) {
|
||||
panel.addView(sep);
|
||||
|
||||
var scroll = new android.widget.ScrollView(context);
|
||||
try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch (eOS) {}
|
||||
try { scroll.setVerticalScrollBarEnabled(true); } catch (eSB) {}
|
||||
try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eOS) { safeLog(null, 'e', "catch " + String(eOS)); }
|
||||
try { scroll.setVerticalScrollBarEnabled(true); } catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); }
|
||||
|
||||
// 给内容加一点边距
|
||||
var contentBox = new android.widget.LinearLayout(context);
|
||||
@@ -53,11 +53,11 @@ FloatBallAppWM.prototype.buildViewerPanelView = function(titleText, bodyText) {
|
||||
tv.setTextColor(codeColor);
|
||||
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, Number(this.config.CONTENT_VIEWER_TEXT_SP || 12));
|
||||
// 增加行距优化阅读
|
||||
try { tv.setLineSpacing(this.dp(4), 1.0); } catch(eLS) {}
|
||||
try { tv.setLineSpacing(this.dp(4), 1.0); } catch(eLS) { safeLog(null, 'e', "catch " + String(eLS)); }
|
||||
// 使用等宽字体显示代码/日志
|
||||
try { tv.setTypeface(android.graphics.Typeface.MONOSPACE); } catch(eTF) {}
|
||||
try { tv.setTypeface(android.graphics.Typeface.MONOSPACE); } catch(eTF) { safeLog(null, 'e', "catch " + String(eTF)); }
|
||||
// WindowManager 环境下禁用文本选择,否则长按/选择会因缺少 Token 崩溃
|
||||
try { tv.setTextIsSelectable(false); } catch (eSel) {}
|
||||
try { tv.setTextIsSelectable(false); } catch(eSel) { safeLog(null, 'e', "catch " + String(eSel)); }
|
||||
|
||||
contentBox.addView(tv);
|
||||
|
||||
@@ -96,7 +96,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
bgDr.setColor(this.withAlpha(bgColor, this.config.PANEL_BG_ALPHA));
|
||||
bgDr.setCornerRadius(this.dp(16));
|
||||
panel.setBackground(bgDr);
|
||||
try { panel.setElevation(this.dp(8)); } catch(e){}
|
||||
try { panel.setElevation(this.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var padDp = this.config.PANEL_PADDING_DP;
|
||||
panel.setPadding(
|
||||
@@ -149,9 +149,9 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
}
|
||||
|
||||
var scroll = new android.widget.ScrollView(context);
|
||||
try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch (eOS) {}
|
||||
try { scroll.setVerticalScrollBarEnabled(false); } catch (eSB) {}
|
||||
try { scroll.setFillViewport(true); } catch (eFV) {}
|
||||
try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eOS) { safeLog(null, 'e', "catch " + String(eOS)); }
|
||||
try { scroll.setVerticalScrollBarEnabled(false); } catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); }
|
||||
try { scroll.setFillViewport(true); } catch(eFV) { safeLog(null, 'e', "catch " + String(eFV)); }
|
||||
|
||||
var scrollLp = new android.widget.LinearLayout.LayoutParams(contentW, scrollH);
|
||||
scroll.setLayoutParams(scrollLp);
|
||||
@@ -170,7 +170,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
// var totalCells = totalBtns > minCells ? totalBtns : minCells;
|
||||
|
||||
var rowCount = Math.ceil(totalCells / cols2);
|
||||
try { grid.setRowCount(rowCount); } catch (eRC) {}
|
||||
try { grid.setRowCount(rowCount); } catch(eRC) { safeLog(null, 'e', "catch " + String(eRC)); }
|
||||
|
||||
grid.setOnTouchListener(new JavaAdapter(android.view.View.OnTouchListener, {
|
||||
onTouch: function(v, e) { self.touchActivity(); return false; }
|
||||
@@ -193,7 +193,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
// 单元格背景:如果是有功能的按钮,给个卡片背景;否则透明
|
||||
if (btnCfg) {
|
||||
cell.setBackground(self.ui.createRoundDrawable(cardColor, self.dp(12)));
|
||||
try { cell.setElevation(self.dp(2)); } catch(e){}
|
||||
try { cell.setElevation(self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
} else {
|
||||
// 空格子占位
|
||||
}
|
||||
@@ -206,7 +206,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
// 但 resolveIconDrawable 逻辑比较复杂,这里暂时不强制染色,除非用户配置了 TINT
|
||||
if (!isDark && btnCfg && !btnCfg.type && !btnCfg.pkg) {
|
||||
// 简单的系统图标在亮色模式下可能看不清,染成深色
|
||||
try { iv.setColorFilter(C.textPriLight, android.graphics.PorterDuff.Mode.SRC_IN); } catch(eCF){}
|
||||
try { iv.setColorFilter(C.textPriLight, android.graphics.PorterDuff.Mode.SRC_IN); } catch(eCF) { safeLog(null, 'e', "catch " + String(eCF)); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, this.config.PANEL_LABEL_TEXT_SIZE_SP);
|
||||
tv.setTextColor(textColor);
|
||||
tv.setGravity(android.view.Gravity.CENTER);
|
||||
try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eL){}
|
||||
try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); }
|
||||
|
||||
var tvLp = new android.widget.LinearLayout.LayoutParams(
|
||||
android.widget.LinearLayout.LayoutParams.MATCH_PARENT, // 宽度填满,方便居中
|
||||
@@ -251,8 +251,8 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) {
|
||||
}));
|
||||
})(i, btnCfg);
|
||||
} else {
|
||||
try { iv.setAlpha(0); } catch (eA0) {}
|
||||
try { cell.setClickable(false); } catch (eC0) {}
|
||||
try { iv.setAlpha(0); } catch(eA0) { safeLog(null, 'e', "catch " + String(eA0)); }
|
||||
try { cell.setClickable(false); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); }
|
||||
}
|
||||
|
||||
grid.addView(cell);
|
||||
@@ -460,7 +460,7 @@ FloatBallAppWM.prototype.addPanel = function(panel, x, y, which) {
|
||||
panel.setScaleY(1);
|
||||
panel.setAlpha(1);
|
||||
}
|
||||
} catch (eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
|
||||
// # 日志防抖:5秒内相同面板类型不重复记录
|
||||
var now = Date.now();
|
||||
@@ -516,8 +516,8 @@ FloatBallAppWM.prototype.showPanelAvoidBall = function(which) {
|
||||
// 需要处理 newPanel 的 LayoutParams
|
||||
var contentLp = new android.widget.LinearLayout.LayoutParams(-1, 0);
|
||||
contentLp.weight = 1;
|
||||
try { newPanel.setBackground(null); } catch(e){} // 移除背景,使用 Container 背景
|
||||
try { newPanel.setElevation(0); } catch(e){}
|
||||
try { newPanel.setBackground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // 移除背景,使用 Container 背景
|
||||
try { newPanel.setElevation(0); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
newPanel.setLayoutParams(contentLp);
|
||||
|
||||
container.addView(newPanel);
|
||||
@@ -651,7 +651,7 @@ FloatBallAppWM.prototype.showPanelAvoidBall = function(which) {
|
||||
self.touchActivity();
|
||||
} catch (e) {
|
||||
if (self.L) self.L.e("showPanelAvoidBall callback err=" + String(e));
|
||||
try { self.toast("面板显示失败: " + String(e)); } catch (et) {}
|
||||
try { self.toast("面板显示失败: " + String(e)); } catch(et) { safeLog(null, 'e', "catch " + String(et)); }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -691,7 +691,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
bgDr.setColor(isDark ? C.bgDark : C.bgLight);
|
||||
bgDr.setCornerRadius(this.dp(12));
|
||||
container.setBackground(bgDr);
|
||||
try { container.setElevation(this.dp(8)); } catch(e){}
|
||||
try { container.setElevation(this.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
// Header
|
||||
var header = new android.widget.LinearLayout(context);
|
||||
@@ -717,7 +717,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
else self.hideAllPanels();
|
||||
});
|
||||
btnClose.setPadding(self.dp(8), self.dp(4), self.dp(8), self.dp(4));
|
||||
try { btnClose.setElevation(this.dp(25)); } catch(e){} // Ensure on top of resize handles
|
||||
try { btnClose.setElevation(this.dp(25)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // Ensure on top of resize handles
|
||||
header.addView(btnClose);
|
||||
|
||||
// Spacer to avoid overlap with Top-Right resize handle
|
||||
@@ -733,8 +733,8 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
|
||||
// Add Content
|
||||
// 移除 content 原有的背景和 elevation,避免重复
|
||||
try { contentView.setBackground(null); } catch(e){}
|
||||
try { contentView.setElevation(0); } catch(e){}
|
||||
try { contentView.setBackground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
try { contentView.setElevation(0); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var contentLp = new android.widget.LinearLayout.LayoutParams(-1, 0);
|
||||
contentLp.weight = 1;
|
||||
@@ -746,7 +746,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
|
||||
// Resize Handle (Bottom-Right Corner) - Invisible
|
||||
var handleBR = new android.view.View(context);
|
||||
try { handleBR.setElevation(this.dp(20)); } catch(e){}
|
||||
try { handleBR.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var handleBRLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30));
|
||||
handleBRLp.gravity = android.view.Gravity.BOTTOM | android.view.Gravity.END;
|
||||
handleBRLp.rightMargin = 0;
|
||||
@@ -755,7 +755,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
|
||||
// Resize Handle (Bottom-Left Corner) - Invisible
|
||||
var handleBL = new android.view.View(context);
|
||||
try { handleBL.setElevation(this.dp(20)); } catch(e){}
|
||||
try { handleBL.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var handleBLLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30));
|
||||
handleBLLp.gravity = android.view.Gravity.BOTTOM | android.view.Gravity.START;
|
||||
handleBLLp.bottomMargin = 0;
|
||||
@@ -764,7 +764,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
|
||||
// Resize Handle (Top-Left Corner) - Invisible
|
||||
var handleTL = new android.view.View(context);
|
||||
try { handleTL.setElevation(this.dp(20)); } catch(e){}
|
||||
try { handleTL.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var handleTLLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30));
|
||||
handleTLLp.gravity = android.view.Gravity.TOP | android.view.Gravity.START;
|
||||
handleTLLp.topMargin = 0;
|
||||
@@ -773,7 +773,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit
|
||||
|
||||
// Resize Handle (Top-Right Corner) - Invisible
|
||||
var handleTR = new android.view.View(context);
|
||||
try { handleTR.setElevation(this.dp(20)); } catch(e){}
|
||||
try { handleTR.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
var handleTRLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30));
|
||||
handleTRLp.gravity = android.view.Gravity.TOP | android.view.Gravity.END;
|
||||
handleTRLp.topMargin = 0;
|
||||
@@ -867,7 +867,7 @@ FloatBallAppWM.prototype.attachDragResizeListeners = function(rootView, headerVi
|
||||
|
||||
lp.x = targetX;
|
||||
lp.y = targetY;
|
||||
try { wm.updateViewLayout(rootView, lp); } catch(e){}
|
||||
try { wm.updateViewLayout(rootView, lp); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -938,10 +938,10 @@ FloatBallAppWM.prototype.attachDragResizeListeners = function(rootView, headerVi
|
||||
lpCur.height = initialH;
|
||||
lpCur.x = initialX;
|
||||
lpCur.y = initialY;
|
||||
try { wm.updateViewLayout(rootView, lpCur); } catch(e){}
|
||||
try { wm.updateViewLayout(rootView, lpCur); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
resizing = true;
|
||||
} catch(e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
});
|
||||
self.state.h.postDelayed(longPressRunnable, 300); // 300ms hold to activate resize
|
||||
@@ -1022,7 +1022,7 @@ FloatBallAppWM.prototype.attachDragResizeListeners = function(rootView, headerVi
|
||||
lp.y = Math.round(newY);
|
||||
}
|
||||
|
||||
try { wm.updateViewLayout(rootView, lp); } catch(e){}
|
||||
try { wm.updateViewLayout(rootView, lp); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -1138,7 +1138,7 @@ FloatBallAppWM.prototype.showViewerPanel = function(title, text) {
|
||||
};
|
||||
|
||||
FloatBallAppWM.prototype.cancelLongPressTimer = function() {
|
||||
try { if (this.state.longPressRunnable && this.state.h) this.state.h.removeCallbacks(this.state.longPressRunnable); } catch (e) {}
|
||||
try { if (this.state.longPressRunnable && this.state.h) this.state.h.removeCallbacks(this.state.longPressRunnable); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
this.state.longPressArmed = false;
|
||||
this.state.longPressRunnable = null;
|
||||
};
|
||||
@@ -1208,7 +1208,7 @@ FloatBallAppWM.prototype.setupTouchListener = function() {
|
||||
self.touchActivity();
|
||||
|
||||
// 恢复不透明度
|
||||
try { v.setAlpha(1.0); } catch(eA) {}
|
||||
try { v.setAlpha(1.0); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
|
||||
if (self.state.docked) {
|
||||
self.undockToFull(false, null);
|
||||
@@ -1224,14 +1224,14 @@ FloatBallAppWM.prototype.setupTouchListener = function() {
|
||||
lastTouchX = e.getRawX();
|
||||
lastTouchY = e.getRawY();
|
||||
|
||||
try { v.setPressed(true); } catch (eP) {}
|
||||
try { v.drawableHotspotChanged(e.getX(), e.getY()); } catch (eH) {}
|
||||
try { v.setPressed(true); } catch(eP) { safeLog(null, 'e', "catch " + String(eP)); }
|
||||
try { v.drawableHotspotChanged(e.getX(), e.getY()); } catch(eH) { safeLog(null, 'e', "catch " + String(eH)); }
|
||||
|
||||
// 按下缩小反馈
|
||||
if (self.config.ENABLE_ANIMATIONS) {
|
||||
try {
|
||||
v.animate().scaleX(0.9).scaleY(0.9).setDuration(100).start();
|
||||
} catch(eS){}
|
||||
} catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
}
|
||||
|
||||
self.armLongPress();
|
||||
@@ -1268,11 +1268,11 @@ FloatBallAppWM.prototype.setupTouchListener = function() {
|
||||
self.state.ballLp.y = self.clamp(self.state.ballLp.y, 0, self.state.screen.h - di.ballSize);
|
||||
|
||||
self.state.ballLp.width = di.ballSize;
|
||||
try { self.state.ballContent.setX(0); } catch (e0) {}
|
||||
try { self.state.ballContent.setX(0); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
|
||||
var now = java.lang.System.currentTimeMillis();
|
||||
if (now - lastUpdateTs > 10) { // 10ms 节流
|
||||
try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch (eU) {}
|
||||
try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); }
|
||||
lastUpdateTs = now;
|
||||
}
|
||||
|
||||
@@ -1286,16 +1286,16 @@ FloatBallAppWM.prototype.setupTouchListener = function() {
|
||||
if (a === android.view.MotionEvent.ACTION_UP || a === android.view.MotionEvent.ACTION_CANCEL) {
|
||||
self.touchActivity();
|
||||
|
||||
try { v.setPressed(false); } catch (eP2) {}
|
||||
try { v.setPressed(false); } catch(eP2) { safeLog(null, 'e', "catch " + String(eP2)); }
|
||||
self.cancelLongPressTimer();
|
||||
|
||||
// 恢复缩放
|
||||
if (self.config.ENABLE_ANIMATIONS) {
|
||||
try {
|
||||
v.animate().scaleX(1.0).scaleY(1.0).setDuration(150).start();
|
||||
} catch(eS){}
|
||||
} catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
} else {
|
||||
try { v.setScaleX(1); v.setScaleY(1); } catch(eS){}
|
||||
try { v.setScaleX(1); v.setScaleY(1); } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
}
|
||||
|
||||
if (self.state.longPressTriggered) {
|
||||
@@ -1305,7 +1305,7 @@ FloatBallAppWM.prototype.setupTouchListener = function() {
|
||||
}
|
||||
|
||||
if (!self.state.dragging && a === android.view.MotionEvent.ACTION_UP) {
|
||||
try { self.playBounce(v); } catch (eB) {}
|
||||
try { self.playBounce(v); } catch(eB) { safeLog(null, 'e', "catch " + String(eB)); }
|
||||
|
||||
if (self.state.addedPanel) self.hideMainPanel();
|
||||
else self.showPanelAvoidBall("main");
|
||||
@@ -1315,7 +1315,7 @@ FloatBallAppWM.prototype.setupTouchListener = function() {
|
||||
} else {
|
||||
// 拖拽结束
|
||||
// 确保最后位置被更新
|
||||
try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch (eU) {}
|
||||
try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); }
|
||||
|
||||
var forceSide = null;
|
||||
// 计算速度
|
||||
@@ -1360,7 +1360,7 @@ FloatBallAppWM.prototype.createBallViews = function() {
|
||||
var root = new android.widget.FrameLayout(context);
|
||||
root.setClipToPadding(true);
|
||||
root.setClipChildren(true);
|
||||
try { root.setElevation(this.dp(6)); } catch(e){}
|
||||
try { root.setElevation(this.dp(6)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
var content = new android.widget.FrameLayout(context);
|
||||
var lp = new android.widget.FrameLayout.LayoutParams(di.ballSize, di.ballSize);
|
||||
@@ -1419,7 +1419,7 @@ try {
|
||||
} else {
|
||||
safeLog(this.L, 'w', "Ball icon file load failed: " + iconFilePath);
|
||||
}
|
||||
} catch (eF) {}
|
||||
} catch(eF) { safeLog(null, 'e', "catch " + String(eF)); }
|
||||
}
|
||||
|
||||
// # 2) app:加载应用图标 (file 失败也会尝试 app)
|
||||
@@ -1434,7 +1434,7 @@ try {
|
||||
usedKind = "app";
|
||||
}
|
||||
}
|
||||
} catch (eA) {}
|
||||
} catch(eA) { safeLog(null, 'e', "catch " + String(eA)); }
|
||||
}
|
||||
|
||||
// # 2.5) shortx:专门加载 ShortX 内置图标(也作为 file 模式的兜底)
|
||||
@@ -1455,7 +1455,7 @@ try {
|
||||
safeLog(this.L, 'i', "File icon failed, fallback to shortx icon");
|
||||
}
|
||||
}
|
||||
} catch (eShortx2) {}
|
||||
} catch(eShortx2) { safeLog(null, 'e', "catch " + String(eShortx2)); }
|
||||
}
|
||||
|
||||
// # 3) android:或所有兜底,走资源 id(优先尝试 ShortX 内置图标)
|
||||
@@ -1469,13 +1469,13 @@ try {
|
||||
if (usedDrawable != null) {
|
||||
usedKind = "shortx";
|
||||
}
|
||||
} catch (eShortx) {}
|
||||
} catch(eShortx) { safeLog(null, 'e', "catch " + String(eShortx)); }
|
||||
}
|
||||
|
||||
if (usedDrawable != null) {
|
||||
iv.setImageDrawable(usedDrawable);
|
||||
} else if (iconResId > 0) {
|
||||
try { iv.setImageResource(iconResId); usedKind = "android"; } catch (eR) {}
|
||||
try { iv.setImageResource(iconResId); usedKind = "android"; } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); }
|
||||
} else {
|
||||
// # 没有任何可用图标,直接不加到布局
|
||||
usedKind = "none";
|
||||
@@ -1505,11 +1505,11 @@ try {
|
||||
try {
|
||||
var tintColor2 = android.graphics.Color.parseColor(tintHex);
|
||||
iv.setColorFilter(tintColor2, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
} catch (eTint2) {}
|
||||
} catch(eTint2) { safeLog(null, 'e', "catch " + String(eTint2)); }
|
||||
} else if (usedKind === "android") {
|
||||
try { iv.setColorFilter(android.graphics.Color.WHITE, android.graphics.PorterDuff.Mode.SRC_IN); } catch (eCF) {}
|
||||
try { iv.setColorFilter(android.graphics.Color.WHITE, android.graphics.PorterDuff.Mode.SRC_IN); } catch(eCF) { safeLog(null, 'e', "catch " + String(eCF)); }
|
||||
} else {
|
||||
try { iv.clearColorFilter(); } catch (eCL) {}
|
||||
try { iv.clearColorFilter(); } catch(eCL) { safeLog(null, 'e', "catch " + String(eCL)); }
|
||||
}
|
||||
|
||||
box.addView(iv);
|
||||
@@ -1518,7 +1518,7 @@ try {
|
||||
|
||||
content.addView(box);
|
||||
}
|
||||
} catch (eBallInner) {}
|
||||
} catch(eBallInner) { safeLog(null, 'e', "catch " + String(eBallInner)); }
|
||||
|
||||
|
||||
this.updateBallContentBackground(content);
|
||||
@@ -1526,7 +1526,7 @@ try {
|
||||
// # 阴影控制:file/app 模式下不加阴影(避免透明背景带黑框)
|
||||
var _uk = this.state.usedIconKind;
|
||||
if (_uk !== "file" && _uk !== "app") {
|
||||
try { root.setElevation(this.dp(6)); } catch(e){}
|
||||
try { root.setElevation(this.dp(6)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
}
|
||||
|
||||
content.setClickable(true);
|
||||
|
||||
@@ -7,7 +7,7 @@ function runOnMainSync(fn, timeoutMs) {
|
||||
if (mainLooper !== null && myLooper !== null && myLooper === mainLooper) {
|
||||
return { ok: true, value: fn() };
|
||||
}
|
||||
} catch (eLoop) {}
|
||||
} catch(eLoop) { safeLog(null, 'e', "catch " + String(eLoop)); }
|
||||
|
||||
try {
|
||||
var box = { ok: false, value: null, error: null };
|
||||
@@ -76,9 +76,17 @@ FloatBallAppWM.prototype.close = function() {
|
||||
this.cancelDockTimer();
|
||||
this.stopDisplayMonitor();
|
||||
|
||||
// # 取消正在进行的球体动画
|
||||
try {
|
||||
if (this.state.ballAnimator) {
|
||||
this.state.ballAnimator.cancel();
|
||||
this.state.ballAnimator = null;
|
||||
}
|
||||
} catch(eAnim) { safeLog(null, 'e', "catch " + String(eAnim)); }
|
||||
|
||||
try {
|
||||
if (this.state.addedBall && this.state.ballLp) this.savePos(this.state.ballLp.x, this.state.ballLp.y);
|
||||
} catch (eS) {}
|
||||
} catch(eS) { safeLog(null, 'e', "catch " + String(eS)); }
|
||||
try { FileIO.flushDebouncedWrites(); } catch (eFlushCfg) { safeLog(this.L, 'e', "flushDebouncedWrites fail: " + String(eFlushCfg)); }
|
||||
|
||||
this.hideAllPanels();
|
||||
@@ -109,7 +117,7 @@ FloatBallAppWM.prototype.close = function() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 18) this.state.ht.quitSafely();
|
||||
else this.state.ht.quit();
|
||||
}
|
||||
} catch (eQ) {}
|
||||
} catch(eQ) { safeLog(null, 'e', "catch " + String(eQ)); }
|
||||
|
||||
// # 清理图标加载线程
|
||||
try {
|
||||
@@ -117,14 +125,14 @@ FloatBallAppWM.prototype.close = function() {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 18) this._iconLoader.ht.quitSafely();
|
||||
else this._iconLoader.ht.quit();
|
||||
}
|
||||
} catch (eIcon) {}
|
||||
} catch(eIcon) { safeLog(null, 'e', "catch " + String(eIcon)); }
|
||||
try {
|
||||
if (self.__scIconLoaderSingleton && self.__scIconLoaderSingleton.ht) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 18) self.__scIconLoaderSingleton.ht.quitSafely();
|
||||
else self.__scIconLoaderSingleton.ht.quit();
|
||||
}
|
||||
} catch (eScIcon) {}
|
||||
try { self.__scIconLoaderSingleton = null; } catch (eScIcon2) {}
|
||||
} catch(eScIcon) { safeLog(null, 'e', "catch " + String(eScIcon)); }
|
||||
try { self.__scIconLoaderSingleton = null; } catch(eScIcon2) { safeLog(null, 'e', "catch " + String(eScIcon2)); }
|
||||
|
||||
safeLog(this.L, 'i', "close done");
|
||||
|
||||
@@ -137,7 +145,7 @@ FloatBallAppWM.prototype.close = function() {
|
||||
this.L._flushTimer = null;
|
||||
}
|
||||
}
|
||||
} catch (eLog) {}
|
||||
} catch(eLog) { safeLog(null, 'e', "catch " + String(eLog)); }
|
||||
|
||||
// # 清空缓存
|
||||
try {
|
||||
@@ -145,7 +153,7 @@ FloatBallAppWM.prototype.close = function() {
|
||||
this._shortcutIconFailTs = {};
|
||||
if (typeof __scIconCache !== "undefined") __scIconCache = {};
|
||||
if (typeof __scAppLabelCache !== "undefined") __scAppLabelCache = {};
|
||||
} catch (eCache) {}
|
||||
} catch(eCache) { safeLog(null, 'e', "catch " + String(eCache)); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -161,7 +169,7 @@ FloatBallAppWM.prototype.dispose = function() {
|
||||
if (self.__shortcutPickerSingleton === this.__shortcutPickerSingleton) {
|
||||
self.__shortcutPickerSingleton = null;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch(e) { safeLog(null, 'e', "catch " + String(e)); }
|
||||
|
||||
// # 清理配置缓存
|
||||
this._settingsCache = null;
|
||||
@@ -196,7 +204,17 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) {
|
||||
shell("am broadcast -a " + String(this.config.ACTION_CLOSE_ALL));
|
||||
preCloseSent = true;
|
||||
}
|
||||
} catch (e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
}
|
||||
|
||||
// # 清理旧的 HandlerThread,防止重复启动导致线程泄漏
|
||||
if (this.state.ht) {
|
||||
try {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 18) this.state.ht.quitSafely();
|
||||
else this.state.ht.quit();
|
||||
} catch(eOldHt) { safeLog(null, 'e', "catch " + String(eOldHt)); }
|
||||
this.state.ht = null;
|
||||
this.state.h = null;
|
||||
}
|
||||
|
||||
var ht = new android.os.HandlerThread(String(this.config.WM_THREAD_NAME));
|
||||
@@ -211,9 +229,9 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) {
|
||||
var closeRcv = registerReceiverOnMain(this.config.ACTION_CLOSE_ALL, function(ctx, it) {
|
||||
try {
|
||||
h.post(new JavaAdapter(java.lang.Runnable, {
|
||||
run: function() { try { self.close(); } catch (e1) {} }
|
||||
run: function() { try { self.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } }
|
||||
}));
|
||||
} catch (e2) {}
|
||||
} catch(e2) { safeLog(null, 'e', "catch " + String(e2)); }
|
||||
});
|
||||
if (closeRcv) this.state.receivers.push(closeRcv);
|
||||
|
||||
@@ -237,10 +255,10 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) {
|
||||
if (self.state.panel) self.updatePanelBackground(self.state.panel);
|
||||
if (self.state.settingsPanel) self.updatePanelBackground(self.state.settingsPanel);
|
||||
if (self.state.viewerPanel) self.updatePanelBackground(self.state.viewerPanel);
|
||||
} catch (e1) {}
|
||||
} catch(e1) { safeLog(null, 'e', "catch " + String(e1)); }
|
||||
}
|
||||
}));
|
||||
} catch (e0) {}
|
||||
} catch(e0) { safeLog(null, 'e', "catch " + String(e0)); }
|
||||
}
|
||||
);
|
||||
if (cfgRcv) this.state.receivers.push(cfgRcv);
|
||||
@@ -265,10 +283,10 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) {
|
||||
self.state.wm.addView(self.state.ballRoot, self.state.ballLp);
|
||||
self.state.addedBall = true;
|
||||
} catch (eAdd) {
|
||||
try { self.toast("悬浮球 addView 失败: " + String(eAdd)); } catch (eT) {}
|
||||
try { self.toast("悬浮球 addView 失败: " + String(eAdd)); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); }
|
||||
if (self.L) self.L.fatal("addView ball fail err=" + String(eAdd));
|
||||
self.state.addedBall = false;
|
||||
try { self.close(); } catch (eC) {}
|
||||
try { self.close(); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -280,9 +298,9 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) {
|
||||
self.L.i("ball x=" + String(self.state.ballLp.x) + " y=" + String(self.state.ballLp.y) + " sizeDp=" + String(self.config.BALL_SIZE_DP));
|
||||
}
|
||||
} catch (eAll) {
|
||||
try { self.toast("启动异常: " + String(eAll)); } catch (eTT2) {}
|
||||
try { self.toast("启动异常: " + String(eAll)); } catch(eTT2) { safeLog(null, 'e', "catch " + String(eTT2)); }
|
||||
if (self.L) self.L.fatal("start runnable err=" + String(eAll));
|
||||
try { self.close(); } catch (eC2) {}
|
||||
try { self.close(); } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); }
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user