Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".App"
android:icon="@mipmap/ic_launcher"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/yangfentuozi/batteryrecorder/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class App: Application() {
val settings = SharedSettings.readServerSettings(this)
LoggerX.d(TAG,
"[应用] SharedPreferences 配置读取完成: intervalMs=${settings.recordIntervalMs} " +
"screenOffRecord=${settings.screenOffRecordEnabled} polling=${settings.alwaysPollingScreenStatusEnabled}"
"screenOffRecord=${settings.screenOffRecordEnabled} preciseScreenOffRecord=${settings.preciseScreenOffRecordEnabled} polling=${settings.alwaysPollingScreenStatusEnabled}"
)
LoggerX.maxHistoryDays = settings.maxHistoryDays
LoggerX.logLevel = settings.logLevel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ fun ServerSection(
)
}

item {
M3ESwitchWidget(
text = stringResource(R.string.settings_precise_screen_off_record),
summary = stringResource(R.string.settings_precise_screen_off_record_summary),
checked = state.preciseScreenOffRecordEnabled,
onCheckedChange = actions.setPreciseScreenOffRecordEnabled
)
}

item {
M3ESwitchWidget(
text = stringResource(R.string.settings_poll_screen_status),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class ServerActions(
val setWriteLatencyMs: (Long) -> Unit,
val setBatchSize: (Int) -> Unit,
val setScreenOffRecordEnabled: (Boolean) -> Unit,
val setPreciseScreenOffRecordEnabled: (Boolean) -> Unit,
val setAlwaysPollingScreenStatusEnabled: (Boolean) -> Unit,
val setSegmentDurationMin: (Long) -> Unit,
val setRootBootAutoStartEnabled: (Boolean) -> Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ data class SettingsUiState(
val batchSize: Int = ServerSettings().batchSize,
/** 息屏记录 */
val recordScreenOffEnabled: Boolean = ServerSettings().screenOffRecordEnabled,
/** 精确息屏记录 */
val preciseScreenOffRecordEnabled: Boolean = ServerSettings().preciseScreenOffRecordEnabled,
/** 轮询获取息屏状态 */
val alwaysPollingScreenStatusEnabled: Boolean = ServerSettings().alwaysPollingScreenStatusEnabled,
/** 自动分段时间 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ fun SettingsScreen(
setWriteLatencyMs = settingsViewModel::setWriteLatencyMs,
setBatchSize = settingsViewModel::setBatchSize,
setScreenOffRecordEnabled = settingsViewModel::setScreenOffRecordEnabled,
setPreciseScreenOffRecordEnabled = settingsViewModel::setPreciseScreenOffRecordEnabled,
setAlwaysPollingScreenStatusEnabled = settingsViewModel::setAlwaysPollingScreenStatusEnabled,
setSegmentDurationMin = settingsViewModel::setSegmentDurationMin,
setRootBootAutoStartEnabled = settingsViewModel::setRootBootAutoStartEnabled
Expand Down Expand Up @@ -101,6 +102,7 @@ fun SettingsScreen(
writeLatencyMs = serverSettings.writeLatencyMs,
batchSize = serverSettings.batchSize,
recordScreenOffEnabled = serverSettings.screenOffRecordEnabled,
preciseScreenOffRecordEnabled = serverSettings.preciseScreenOffRecordEnabled,
alwaysPollingScreenStatusEnabled = serverSettings.alwaysPollingScreenStatusEnabled,
segmentDurationMin = serverSettings.segmentDurationMin,
rootBootAutoStartEnabled = appSettings.rootBootAutoStartEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class SettingsViewModel : ViewModel() {

LoggerX.d(
TAG,
"[设置] loadSettings 完成: notification=${currentServerSettings.notificationEnabled} compatMode=${currentServerSettings.notificationCompatModeEnabled} dualCell=${currentServerSettings.dualCellEnabled} calibration=${currentServerSettings.calibrationValue} intervalMs=${currentServerSettings.recordIntervalMs} writeLatencyMs=${currentServerSettings.writeLatencyMs} batchSize=${currentServerSettings.batchSize} screenOffRecord=${currentServerSettings.screenOffRecordEnabled} polling=${currentServerSettings.alwaysPollingScreenStatusEnabled} logLevel=${currentServerSettings.logLevel}"
"[设置] loadSettings 完成: notification=${currentServerSettings.notificationEnabled} compatMode=${currentServerSettings.notificationCompatModeEnabled} dualCell=${currentServerSettings.dualCellEnabled} calibration=${currentServerSettings.calibrationValue} intervalMs=${currentServerSettings.recordIntervalMs} writeLatencyMs=${currentServerSettings.writeLatencyMs} batchSize=${currentServerSettings.batchSize} screenOffRecord=${currentServerSettings.screenOffRecordEnabled} preciseScreenOffRecord=${currentServerSettings.preciseScreenOffRecordEnabled} polling=${currentServerSettings.alwaysPollingScreenStatusEnabled} logLevel=${currentServerSettings.logLevel}"
)
}

Expand Down Expand Up @@ -236,6 +236,20 @@ class SettingsViewModel : ViewModel() {
}
}

/**
* 更新精确息屏记录开关并下发到运行中的服务端。
*
* @param enabled `true` 表示允许 Server 在息屏记录阶段持有唤醒锁;`false` 表示恢复默认自然息屏采样。
* @return 无。
*/
fun setPreciseScreenOffRecordEnabled(enabled: Boolean) {
updateServerSettings(
message = "[设置] 更新精确息屏记录并准备下发: enabled=$enabled"
) { current ->
current.copy(preciseScreenOffRecordEnabled = enabled)
}
}

fun setAlwaysPollingScreenStatusEnabled(enabled: Boolean) {
updateServerSettings(
message = "[设置] 更新轮询亮屏状态并准备下发: enabled=$enabled"
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
<string name="settings_notification_enabled">实时功率通知</string>
<string name="settings_notification_compat_mode">通知兼容模式</string>
<string name="settings_screen_off_record">息屏记录</string>
<string name="settings_precise_screen_off_record">精确息屏记录</string>
<string name="settings_precise_screen_off_record_summary">可能导致息屏耗电增高</string>
<string name="settings_poll_screen_status">轮询获取息屏状态</string>
<string name="settings_record_interval">采样间隔</string>
<string name="settings_write_latency">写入延迟</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
<string name="settings_notification_enabled">Realtime power notification</string>
<string name="settings_notification_compat_mode">Notification compatibility mode</string>
<string name="settings_screen_off_record">Record when screen is off</string>
<string name="settings_precise_screen_off_record">Precise screen-off recording</string>
<string name="settings_precise_screen_off_record_summary">May increase screen-off power draw.</string>
<string name="settings_poll_screen_status">Poll screen state</string>
<string name="settings_record_interval">Sampling interval</string>
<string name="settings_write_latency">Write latency</string>
Expand Down
61 changes: 37 additions & 24 deletions server/src/main/java/yangfentuozi/batteryrecorder/server/Server.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,31 +82,43 @@ class Server internal constructor() : IService.Stub() {
monitor.unregisterRecordListener(listener)
}

override fun updateConfig(settings: ServerSettings) {
Handlers.common.post {
LoggerX.d(
tag,
"updateConfig: 应用配置, notification=${settings.notificationEnabled} compatMode=${settings.notificationCompatModeEnabled} dualCell=${settings.dualCellEnabled} calibration=${settings.calibrationValue} intervalMs=${settings.recordIntervalMs} writeLatencyMs=${settings.writeLatencyMs} batchSize=${settings.batchSize} screenOffRecord=${settings.screenOffRecordEnabled} segmentDurationMin=${settings.segmentDurationMin} logLevel=${settings.logLevel} polling=${settings.alwaysPollingScreenStatusEnabled}"
)
LoggerX.maxHistoryDays = settings.maxHistoryDays
LoggerX.logLevel = settings.logLevel
/**
* 应用一份服务端配置到当前运行时实例。
*
* @param settings 要生效的服务端配置。
* @param source 本次配置应用来源,仅用于日志定位。
* @return 无。
*/
private fun applyConfigInternal(settings: ServerSettings, source: String) {
LoggerX.d(
tag,
"$source: 应用配置, notification=${settings.notificationEnabled} compatMode=${settings.notificationCompatModeEnabled} dualCell=${settings.dualCellEnabled} calibration=${settings.calibrationValue} intervalMs=${settings.recordIntervalMs} writeLatencyMs=${settings.writeLatencyMs} batchSize=${settings.batchSize} screenOffRecord=${settings.screenOffRecordEnabled} preciseScreenOffRecord=${settings.preciseScreenOffRecordEnabled} segmentDurationMin=${settings.segmentDurationMin} logLevel=${settings.logLevel} polling=${settings.alwaysPollingScreenStatusEnabled}"
)
LoggerX.maxHistoryDays = settings.maxHistoryDays
LoggerX.logLevel = settings.logLevel

unlockOPlusSampleTimeLimit(settings.recordIntervalMs.coerceAtLeast(200))
unlockOPlusSampleTimeLimit(settings.recordIntervalMs.coerceAtLeast(200))

monitor.notificationPowerMultiplier = computeNotificationPowerMultiplier(
dualCellEnabled = settings.dualCellEnabled,
calibrationValue = settings.calibrationValue,
)
monitor.setNotificationCompatModeEnabled(settings.notificationCompatModeEnabled)
monitor.setNotificationEnabled(settings.notificationEnabled)
monitor.alwaysPollingScreenStatusEnabled = settings.alwaysPollingScreenStatusEnabled
monitor.recordIntervalMs = settings.recordIntervalMs
monitor.screenOffRecord = settings.screenOffRecordEnabled
monitor.notifyLock()

writer.flushIntervalMs = settings.writeLatencyMs
writer.batchSize = settings.batchSize
writer.maxSegmentDurationMs = settings.segmentDurationMin * 60 * 1000L
monitor.notificationPowerMultiplier = computeNotificationPowerMultiplier(
dualCellEnabled = settings.dualCellEnabled,
calibrationValue = settings.calibrationValue,
)
monitor.setNotificationCompatModeEnabled(settings.notificationCompatModeEnabled)
monitor.setNotificationEnabled(settings.notificationEnabled)
monitor.alwaysPollingScreenStatusEnabled = settings.alwaysPollingScreenStatusEnabled
monitor.recordIntervalMs = settings.recordIntervalMs
monitor.screenOffRecord = settings.screenOffRecordEnabled
monitor.preciseScreenOffRecordEnabled = settings.preciseScreenOffRecordEnabled
monitor.notifyLock()

writer.flushIntervalMs = settings.writeLatencyMs
writer.batchSize = settings.batchSize
writer.maxSegmentDurationMs = settings.segmentDurationMin * 60 * 1000L
}

override fun updateConfig(settings: ServerSettings) {
Handlers.common.post {
applyConfigInternal(settings, "updateConfig")
}
}

Expand Down Expand Up @@ -473,7 +485,8 @@ class Server internal constructor() : IService.Stub() {
LoggerX.i(tag, "init: 通过 ConfigProvider 读取配置")
ConfigUtil.getServerSettingsByContentProvider()
}
serverSettings?.let(::updateConfig) ?: LoggerX.w(tag, "init: 未读取到配置, 使用当前默认值")
serverSettings?.let { applyConfigInternal(it, "init") }
?: LoggerX.w(tag, "init: 未读取到配置, 使用当前默认值")

monitor.start()
LoggerX.i(tag, "init: Monitor 已启动, 进入消息循环")
Expand Down
Loading
Loading