feat(bt): 批①后台常驻框架实施 — meow_media_app_resident按app会话判活跃+should_keep三参(keepalive||bg_audio&&resident)+background_keepalive声明解析透传+amsd EV BG/FG上报;宿主test_media39/test_bgplay/test_bg_keep19全过,0warning;落盘APP_BACKGROUND_KEEPALIVE_P1;降配(nice)待真机未做
This commit is contained in:
1 parent
7e68313981
commit
f3ae06d7cd
10 files changed
+330
-30
No files matched your search
@@ -0,0 +1,161 @@
|
||||
/* test_bg_keep.c — 批①`background_keepalive` 声明层宿主单测。
|
||||
*
|
||||
* 验证 meow_parse_app_json 对 app.json 后台三位(background / background_audio /
|
||||
* background_keepalive)的解析与 meow_acct_sync 透传,重点覆盖**前缀不串扰**:
|
||||
* - "background_keepalive":true → a->background_keepalive=='1';且 background/background_audio
|
||||
* 在该行不被误命中(分别是 0/0);
|
||||
* - background:true → a->background=='1'(独立键匹配不受影响);
|
||||
* - background_audio:true → a->background_audio=='1';
|
||||
* - 一行三键并存:三者各归其位;
|
||||
* - meow_acct_sync 透传 background_keepalive 到注册表。
|
||||
* 实现手法同 test_fg_act.c:真实 include app_launcher.c,-ffunction-sections -Wl,--gc-sections
|
||||
* 只保留 parseInt/acct_sync/upsert/find 触及函数;json_str/meow_parse_depends/logmsg 由本文件提供
|
||||
* 忠实桩(json_str 复刻 util.c 语义,含键前缀独立 ident_ch + 整体 UTF-8 截断)。
|
||||
*
|
||||
* 运行(patch_v2/meow_launcherd 下):
|
||||
* gcc -D_GNU_SOURCE -Wall -Wextra -ffunction-sections -Wl,--gc-sections \
|
||||
* -I. -o test_bg_keep test_bg_keep.c && ./test_bg_keep
|
||||
* 全 PASS -> exit 0。
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ---- logmsg:app_launcher.c 依赖,minimal 桩 ---- */
|
||||
void logmsg(const char *fmt, ...)
|
||||
{
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
/* ---- json_str:复刻 util.c 语义(键前缀独立 + 值提取 + UTF-8 截断)---- */
|
||||
static int ident_ch(char c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') || c == '_' || c == '.';
|
||||
}
|
||||
static void utf8_trim(char *s)
|
||||
{
|
||||
size_t n = strlen(s), i = 0, last_good = 0;
|
||||
while (i < n) {
|
||||
unsigned char c = (unsigned char)s[i];
|
||||
int len = (c < 0x80) ? 1 : (c >= 0xF0) ? 4 : (c >= 0xE0) ? 3 : (c >= 0xC0) ? 2 : 1;
|
||||
if (i + (size_t)len > n) break;
|
||||
i += (size_t)len;
|
||||
last_good = i;
|
||||
}
|
||||
s[last_good] = '\0';
|
||||
}
|
||||
int json_str(const char *buf, const char *key, char *out, int olen)
|
||||
{
|
||||
out[0] = 0;
|
||||
if (!buf || !key || olen <= 0) return 0;
|
||||
const char *p = strstr(buf, key);
|
||||
if (!p) return 0;
|
||||
if (p > buf && ident_ch((unsigned char)p[-1])) return 0; /* 键前缀需独立 */
|
||||
p += strlen(key);
|
||||
if (*p == '"') p++; /* JSON 键自身右引号 */
|
||||
while (*p && (*p == ':' || *p == '=')) p++;
|
||||
while (*p == ' ' || *p == '\t') p++;
|
||||
if (*p == '"') p++; /* 值左引号 */
|
||||
int i = 0;
|
||||
while (*p && *p != '"' && *p != ',' && *p != '\n' && *p != '\r' && i < olen - 1)
|
||||
out[i++] = *p++;
|
||||
out[i] = 0;
|
||||
while (i > 0 && (out[i - 1] == ' ' || out[i - 1] == '\t')) out[--i] = 0;
|
||||
utf8_trim(out);
|
||||
return (int)strlen(out);
|
||||
}
|
||||
|
||||
#include "app_launcher.c" /* 真实实现:meow_parse_app_json / meow_acct_sync / meow_acct_upsert */
|
||||
|
||||
/* meow_parse_depends:本测试 app.json 无 depends 行,桩返回 0(struct meow_dep 此时已可见)。 */
|
||||
int meow_parse_depends(const char *val, struct meow_dep *deps, int max)
|
||||
{
|
||||
(void)val; (void)deps; (void)max;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int g_fail = 0;
|
||||
#define CHECK(cond, msg) do { \
|
||||
if (!(cond)) { fprintf(stderr, "FAIL: %s (%s:%d)\n", msg, __FILE__, __LINE__); g_fail++; } \
|
||||
else fprintf(stderr, "ok: %s\n", msg); \
|
||||
} while (0)
|
||||
|
||||
/* 用一段 app.json 内容解析出 struct app。返回 0=成功。 */
|
||||
static int parse_json(const char *content, struct app *a)
|
||||
{
|
||||
FILE *f = tmpfile();
|
||||
if (!f) return -1;
|
||||
fputs(content, f);
|
||||
rewind(f);
|
||||
memset(a, 0, sizeof *a);
|
||||
meow_parse_app_json(f, a);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* ---- 1) 单独 background_keepalive:true ---- */
|
||||
{
|
||||
struct app a;
|
||||
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background_keepalive\":true\n}", &a);
|
||||
CHECK(a.background_keepalive == '1', "background_keepalive:true -> '1'");
|
||||
CHECK(a.background == 0, "keepalive 行不误命中 background (==0)");
|
||||
CHECK(a.background_audio == 0, "keepalive 行不误命中 background_audio (==0)");
|
||||
}
|
||||
/* ---- 2) 单独 background:true ---- */
|
||||
{
|
||||
struct app a;
|
||||
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background\":true\n}", &a);
|
||||
CHECK(a.background == '1', "background:true -> '1'(独立键匹配不受影响)");
|
||||
CHECK(a.background_keepalive == 0, "background 行不串 to keepalive (==0)");
|
||||
CHECK(a.background_audio == 0, "background 行不串 to background_audio (==0)");
|
||||
}
|
||||
/* ---- 3) 单独 background_audio:true ---- */
|
||||
{
|
||||
struct app a;
|
||||
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background_audio\":true\n}", &a);
|
||||
CHECK(a.background_audio == '1', "background_audio:true -> '1'");
|
||||
CHECK(a.background == 0, "background_audio 行不误命中 background (==0)");
|
||||
CHECK(a.background_keepalive == 0, "background_audio 行不串 to keepalive (==0)");
|
||||
}
|
||||
/* ---- 4) 三键并存:各归其位(逐行格式,值后跟 , 或换行,同真实 app.json) ---- */
|
||||
{
|
||||
struct app a;
|
||||
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background\":true,\n"
|
||||
"\"background_audio\":true,\n\"background_keepalive\":true\n}", &a);
|
||||
CHECK(a.background == '1', "三键并存 background=='1'");
|
||||
CHECK(a.background_audio == '1', "三键并存 background_audio=='1'");
|
||||
CHECK(a.background_keepalive == '1', "三键并存 background_keepalive=='1'");
|
||||
}
|
||||
/* ---- 5) 假值 / 前导噪声不应置位 ---- */
|
||||
{
|
||||
struct app a;
|
||||
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n\"background_keepalive\":false,\n"
|
||||
"\"background_audio\":0\n}", &a);
|
||||
CHECK(a.background_keepalive == 0, "background_keepalive:false -> 0");
|
||||
CHECK(a.background_audio == 0, "background_audio:0 -> 0");
|
||||
CHECK(a.background == 0, "无 background 键 -> 0");
|
||||
}
|
||||
/* ---- 6) meow_acct_sync 透传 ---- */
|
||||
{
|
||||
struct app a;
|
||||
parse_json("{\n\"name\":\"X\",\n\"exec\":\"/usr/bin/x\",\n"
|
||||
"\"background_keepalive\":true,\n\"background_audio\":true\n}", &a);
|
||||
meow_acct_sync("dev.test.keep", &a); /* 以 app_id 建/更注册表项 */
|
||||
struct meow_acct *ac = meow_acct_find("dev.test.keep");
|
||||
CHECK(ac != NULL, "meow_acct_sync 建注册表项");
|
||||
CHECK(ac && ac->background_keepalive == '1', "透传 background_keepalive=='1'");
|
||||
CHECK(ac && ac->background_audio == '1', "透传 background_audio=='1'");
|
||||
CHECK(ac && ac->background == 0, "透传 background==0");
|
||||
}
|
||||
|
||||
if (g_fail) { fprintf(stderr, "\n== %d assertion(s) FAILED ==\n", g_fail); return 1; }
|
||||
fprintf(stderr, "\n== test_bg_keep ALL PASS ==\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user