Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e3dc034
feat: optimize QQ Music cross-device performance
Jul 25, 2026
a8e95d7
fix: select available iOS simulator in CI
Jul 25, 2026
3174e61
perf: reduce BLE media latency and reconnect stalls
Jul 26, 2026
64c7df0
perf: reduce lyric and artwork latency
Jul 26, 2026
5dac153
fix: harden album art and Sony BLE stability
Jul 30, 2026
4b5f5dd
feat: rebuild Android controller with Sony BLE V2
Jul 30, 2026
747cef5
test: stabilize asynchronous artwork XCTest
Jul 30, 2026
ca76c0f
ci: retry transient iOS simulator failures
Jul 30, 2026
1bf5704
feat: complete Android controller media synchronization
Jul 31, 2026
c2c89f9
Improve multi-controller sync and karaoke lyrics
Aug 1, 2026
fd90d78
Improve iOS reconnect stability and Sony media sync
Aug 8, 2026
72f781e
Complete BLE V3 integration and app updates
Aug 23, 2026
8a79748
Complete V4 phase-one product UI refactor
Aug 23, 2026
d6788e4
fix(ci): restore cross-platform build baseline
Aug 23, 2026
bc4eee2
feat(trace): add realtime latency observability
Aug 24, 2026
c89acc7
fix(realtime): stabilize media handoff correctness
Aug 24, 2026
7fadc10
feat(predictive): add bounded next-track prewarm engine
Aug 24, 2026
4dcee5b
perf(lyrics): validate cached lyrics before full transfer
Aug 24, 2026
b97d7b8
test(perf): add predictive handoff SLO suite
Aug 24, 2026
610ed7a
fix(test): distinguish fast controls from track transitions
Aug 24, 2026
f758a0d
fix(media): align generations and preserve control headroom
Aug 25, 2026
157a4ae
fix(test): dispatch auto scenario through media session
Aug 25, 2026
c991c5a
fix(audit): harden phase-three media handoff invariants
Aug 27, 2026
09063b7
test(trace): add cold-path handoff and currentword coverage
Aug 27, 2026
3aa56f2
fix(test): align normal realtime collection window
Aug 27, 2026
1e6c1f5
fix(test): require complete handoff samples for slo runs
Aug 27, 2026
3d1a10d
fix(trace): preserve complete handoff correlation on devices
Aug 28, 2026
7f14213
fix(test): sample handoffs with untrusted clock sync
Aug 28, 2026
33067f2
fix(trace): record now playing slice consumption
Aug 28, 2026
3ad6384
fix(trace): correlate handoff stages by accepted identity
Aug 28, 2026
ea07618
fix(test): keep automatic handoff sampling foreground
Aug 28, 2026
0771ecb
fix(test): correlate automatic handoff traces
Aug 28, 2026
0f72e09
perf(handoff): prioritize current lyric and currentword
Aug 28, 2026
fab6431
fix(test): correlate first valid lyric publication
Aug 28, 2026
140b114
fix(test): separate fast pressure from settled handoffs
Aug 28, 2026
2d2f4ef
fix(test): anchor media SLO at accepted track
Aug 28, 2026
dde1c3a
perf(currentword): replace switch holdoff with event barrier
Aug 28, 2026
10891fb
fix(test): reject clock sync across reconnect
Aug 28, 2026
3596804
fix(ble): serialize command response after notify
Aug 28, 2026
4f887d1
fix(test): exclude refreshed tracks from autoplay samples
Aug 28, 2026
4f2d4e9
docs(perf): record phase-four cold-path evidence
Aug 28, 2026
1154397
revert: restore immediate Sony GATT responses
Aug 29, 2026
17f6734
perf(handoff): prioritize control over stale media refresh
Aug 30, 2026
d1901f7
feat(ios): refine volume and progress sliders
Sep 4, 2026
48749e5
fix(ios): defer clock sync during media transfers
Sep 4, 2026
064d381
test(perf): classify cold-path lyric wait reasons
Sep 4, 2026
80222a5
perf(handoff): keep track identity on realtime queue
Sep 4, 2026
3f706b4
fix(trace): correlate repeated notification metadata
Sep 4, 2026
3a54429
docs(perf): record phase-four handoff validation
Sep 4, 2026
8c55cd4
perf(handoff): publish confirmed track identity before media work
Sep 5, 2026
8062b63
docs(v4): record milestone merge acceptance gaps
Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Cross-platform build and tests

on:
push:
branches:
- main
- master
- "codex/**"
pull_request:

concurrency:
group: cross-platform-${{ github.ref }}
cancel-in-progress: true

jobs:
android:
name: Android unit tests and debug APK
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
cache: gradle
- name: Test and assemble PlayerAgent
run: bash ./gradlew :PlayerAgentApp:testDebugUnitTest :PlayerAgentApp:assembleDebug
- name: Test and assemble Android Controller
run: bash ./gradlew :ControllerApp:testDebugUnitTest :ControllerApp:assembleDebug
- uses: actions/upload-artifact@v4
with:
name: PlayerAgent-debug-apk
path: PlayerAgentApp/build/outputs/apk/debug/*.apk
- uses: actions/upload-artifact@v4
with:
name: Controller-debug-apk
path: ControllerApp/build/outputs/apk/debug/*.apk

ios:
name: iOS simulator XCTest
runs-on: macos-15
timeout-minutes: 35
steps:
- uses: actions/checkout@v4
- name: Inspect Xcode and available simulators
run: |
xcodebuild -version
xcrun simctl list devices available
- name: Run unsigned simulator tests
run: |
set -euo pipefail
simulator_udid="$(
xcrun simctl list devices available -j |
python3 -c '
import json
import sys

runtimes = json.load(sys.stdin).get("devices", {})
devices = (
device
for runtime_devices in runtimes.values()
for device in runtime_devices
)
print(next(
device["udid"]
for device in devices
if device.get("isAvailable") and device.get("name", "").startswith("iPhone")
))
'
)"
echo "Using iOS simulator: ${simulator_udid}"
run_ios_tests() {
local attempt="$1"
xcodebuild \
-project IOSBleFeasibility/IOSBleFeasibility.xcodeproj \
-scheme sonyMusic \
-destination "platform=iOS Simulator,id=${simulator_udid}" \
-derivedDataPath "${RUNNER_TEMP}/IOSBleFeasibilityDerivedData-${attempt}" \
-parallel-testing-enabled NO \
CODE_SIGNING_ALLOWED=NO \
test
}
if ! run_ios_tests 1; then
echo "::warning::iOS simulator test attempt 1 failed; restarting the simulator and retrying once"
xcrun simctl shutdown "${simulator_udid}" || true
run_ios_tests 2
fi
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Thumbs.db

# Logs
*.log
*.hprof

# Local deploy state
tools/deploy/last_deploy.json
tools/deploy/last_successful_deploy.json
23 changes: 23 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Codebase Memory 工作约定

本仓库已使用 `codebase-memory-mcp` 建立本地代码知识图谱。当前索引项目名为
`Volumes-e99bb7e794b5-project-MusicBleController`。

## 修改前先查索引

对代码进行修改、重构、性能优化或缺陷排查前:

1. 先调用 `list_projects`,并用 `index_status` 确认当前仓库索引可用。
2. 索引不存在、状态异常或结果明显陈旧时,调用 `index_repository`,对当前仓库执行完整索引;除非用户明确要求,不生成仓库内持久化图谱文件。
3. 使用 `get_architecture` 或 `search_graph` 定位模块、类型和符号。
4. 涉及调用关系、数据流或影响范围时,使用 `trace_path` 和 `detect_changes`。
5. 使用 `get_code_snippet` 获取精确符号位置,然后必须读取真实源文件再编辑。

## 验证原则

- 图谱用于结构化发现,不是编译器或测试结果的替代品。
- 反射、依赖注入、系统回调、动态分派和生成代码可能无法完整建图;重要结论必须用源码、`rg`、构建和测试验证。
- 字符串、错误信息、配置、脚本和非代码文件可直接使用 `rg`/文件读取工具搜索。
- 不得仅凭空结果断言“没有调用者”“未使用”或“无影响”;这类结论必须补充源码搜索。
- 编辑后使用 `detect_changes` 检查结构影响,并运行与改动相关的测试或构建。
- 如果编辑后的图谱结果仍显示旧代码,重新运行 `index_repository` 后再继续分析。
56 changes: 54 additions & 2 deletions ControllerApp/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
apply plugin: 'kotlin-kapt'

android {
namespace 'com.example.controllerapp'
Expand All @@ -9,8 +10,10 @@ android {
applicationId 'com.example.controllerapp'
minSdk 23
targetSdk 35
versionCode 1
versionName '1.0'
versionCode 2
versionName '2.0'

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

compileOptions {
Expand All @@ -21,4 +24,53 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}

buildFeatures {
compose true
}

composeOptions {
kotlinCompilerExtensionVersion '1.5.14'
}

packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}

dependencies {
def composeBom = platform("androidx.compose:compose-bom:2024.06.00")
implementation composeBom
androidTestImplementation composeBom

implementation "androidx.core:core-ktx:1.13.1"
implementation "androidx.activity:activity-compose:1.9.0"
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-tooling-preview"
implementation "androidx.compose.material3:material3"
implementation "androidx.compose.material:material-icons-extended"
implementation "androidx.navigation:navigation-compose:2.7.7"
implementation "androidx.lifecycle:lifecycle-runtime-compose:2.8.3"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3"
implementation "androidx.datastore:datastore-preferences:1.1.1"
implementation "androidx.room:room-runtime:2.6.1"
implementation "androidx.room:room-ktx:2.6.1"
implementation "androidx.media:media:1.7.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"
kapt "androidx.room:room-compiler:2.6.1"

debugImplementation "androidx.compose.ui:ui-tooling"
debugImplementation "androidx.compose.ui:ui-test-manifest"

testImplementation "junit:junit:4.13.2"
testImplementation "org.json:json:20240303"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1"

androidTestImplementation "androidx.test:core:1.7.0"
androidTestImplementation "androidx.test:runner:1.7.0"
androidTestImplementation "androidx.test.ext:junit:1.3.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.7.0"
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
}
Loading
Loading