fix: harden OriginOS recognition tracking
This commit is contained in:
@@ -183,6 +183,14 @@ void main() {
|
||||
'accessibilityConnected': false,
|
||||
'accessibilityConnectionState': 'reconnecting',
|
||||
'accessibilityLastConnectedAt': 1724472000000,
|
||||
'keepAliveExpected': true,
|
||||
'keepAliveRunning': false,
|
||||
'keepAliveError': '系统限制了后台保护启动',
|
||||
'recentsProtectionExpected': true,
|
||||
'recentsProtectionActive': true,
|
||||
'lastRecognitionExitAt': 1788077518000,
|
||||
'lastRecognitionExitReason': 'low_memory: single-cleaner',
|
||||
'taskCleanerRecoveryNeeded': true,
|
||||
'settings': jsonEncode({'accessibilityEvents': true}),
|
||||
});
|
||||
final connected = RecognitionStatus.fromMap({
|
||||
@@ -204,6 +212,15 @@ void main() {
|
||||
);
|
||||
expect(reconnecting.accessibilityConnectionLabel, '正在重连');
|
||||
expect(reconnecting.accessibilityLastConnectedAt, isNotNull);
|
||||
expect(reconnecting.keepAliveExpected, isTrue);
|
||||
expect(reconnecting.keepAliveRunning, isFalse);
|
||||
expect(reconnecting.keepAliveNeedsRecovery, isTrue);
|
||||
expect(reconnecting.keepAliveError, '系统限制了后台保护启动');
|
||||
expect(reconnecting.recentsProtectionExpected, isTrue);
|
||||
expect(reconnecting.recentsProtectionActive, isTrue);
|
||||
expect(reconnecting.lastRecognitionExitAt, isNotNull);
|
||||
expect(reconnecting.lastRecognitionExitReason, contains('single-cleaner'));
|
||||
expect(reconnecting.taskCleanerRecoveryNeeded, isTrue);
|
||||
expect(connected.accessibilityConnectionLabel, '已连接');
|
||||
expect(disconnected.accessibilityConnectionLabel, '服务未连接');
|
||||
expect(disconnected.accessibilityNeedsRecovery, isTrue);
|
||||
|
||||
@@ -153,9 +153,21 @@ void main() {
|
||||
);
|
||||
expect(
|
||||
RecognitionDiagnosticDisplay.from(
|
||||
diagnostic('rejected', 'payment_input_page'),
|
||||
diagnostic('waiting', 'payment_input_page'),
|
||||
).summaryLabel,
|
||||
'规则拒绝',
|
||||
'等待结果页',
|
||||
);
|
||||
expect(
|
||||
RecognitionDiagnosticDisplay.from(
|
||||
diagnostic('waiting', 'payment_input_page'),
|
||||
).reasonLabel,
|
||||
'当前仍是付款输入或确认页面,等待结果页,不会提前入账',
|
||||
);
|
||||
expect(
|
||||
RecognitionDiagnosticDisplay.from(
|
||||
diagnostic('rejected', 'result_page_timeout'),
|
||||
).reasonLabel,
|
||||
'90 秒内未等到明确结果页,本次流程已停止追踪',
|
||||
);
|
||||
expect(
|
||||
RecognitionDiagnosticDisplay.from(
|
||||
|
||||
@@ -280,7 +280,7 @@ void main() {
|
||||
expect(source, contains('_BackgroundKeepAliveCard'));
|
||||
});
|
||||
|
||||
test('长期识别组件与系统绑定使用默认进程并支持重连状态', () {
|
||||
test('长期识别组件使用独立保活进程并支持非阻塞重连', () {
|
||||
final manifest = File(
|
||||
'android/app/src/main/AndroidManifest.xml',
|
||||
).readAsStringSync();
|
||||
@@ -290,6 +290,12 @@ void main() {
|
||||
final activity = File(
|
||||
'android/app/src/main/kotlin/com/nx/miaoji/MainActivity.kt',
|
||||
).readAsStringSync();
|
||||
final settingsPage = File(
|
||||
'lib/features/settings/screenshot_settings_page.dart',
|
||||
).readAsStringSync();
|
||||
final keepAlive = File(
|
||||
'android/app/src/main/kotlin/com/nx/miaoji/RecognitionKeepAliveService.kt',
|
||||
).readAsStringSync();
|
||||
|
||||
for (final component in [
|
||||
'ScreenshotTileService',
|
||||
@@ -301,18 +307,40 @@ void main() {
|
||||
).firstMatch(manifest)?.group(0);
|
||||
expect(declaration, isNotNull);
|
||||
expect(declaration, contains('android:stopWithTask="false"'));
|
||||
expect(declaration, isNot(contains('android:process=')));
|
||||
expect(declaration, contains('android:process=":recognition"'));
|
||||
}
|
||||
final provider = RegExp(
|
||||
'<provider\\s+android:name="\\.RecognitionBridgeProvider"[\\s\\S]*?/>',
|
||||
).firstMatch(manifest)?.group(0);
|
||||
expect(provider, isNotNull);
|
||||
expect(provider, isNot(contains('android:process=')));
|
||||
expect(provider, contains('android:process=":recognition"'));
|
||||
expect(manifest, contains('android:name=".OneShotProjectionService"'));
|
||||
expect(manifest, contains('android:process=":recognition"'));
|
||||
final projection = RegExp(
|
||||
'<service\\s+android:name="\\.OneShotProjectionService"[\\s\\S]*?/>',
|
||||
).firstMatch(manifest)?.group(0);
|
||||
expect(projection, isNotNull);
|
||||
expect(projection, contains('android:process=":projection"'));
|
||||
expect(manifest, contains('android:name=".RecognitionKeepAliveService"'));
|
||||
expect(manifest, contains('android:foregroundServiceType="specialUse"'));
|
||||
expect(manifest, contains('FOREGROUND_SERVICE_SPECIAL_USE'));
|
||||
expect(manifest, contains('PROPERTY_SPECIAL_USE_FGS_SUBTYPE'));
|
||||
expect(keepAlive, contains('START_STICKY'));
|
||||
expect(keepAlive, contains('智能识别运行中'));
|
||||
expect(channel, contains('waitForAccessibilityConnection'));
|
||||
expect(channel, contains('_activeAccessibilityConnectionWait'));
|
||||
expect(channel, contains('ensureRecognitionKeepAlive'));
|
||||
expect(channel, contains('AccessibilityConnectionState.reconnecting'));
|
||||
expect(activity, contains('"reconnecting"'));
|
||||
expect(activity, contains('"disconnected"'));
|
||||
expect(activity, contains('setExcludeFromRecents'));
|
||||
expect(activity, contains('getHistoricalProcessExitReasons'));
|
||||
expect(activity, contains('single-cleaner'));
|
||||
expect(settingsPage, contains('_check();'));
|
||||
expect(settingsPage, isNot(contains('_check(waitForConnection: true)')));
|
||||
expect(settingsPage, contains('系统仍显示已授权,但 OriginOS 未重新绑定服务'));
|
||||
expect(settingsPage, contains('启动后台保护'));
|
||||
expect(settingsPage, contains('OriginOS 清理了识别进程'));
|
||||
expect(settingsPage, contains('记之已从最近任务隐藏'));
|
||||
expect(channel, contains('taskCleanerRecoveryNeeded'));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user