Loading service/src/AutoOnFeature.kt +34 −3 Original line number Diff line number Diff line Loading @@ -19,8 +19,11 @@ package com.android.server.bluetooth import android.bluetooth.BluetoothAdapter.STATE_ON import android.content.BroadcastReceiver import android.content.ContentResolver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Handler import android.os.Looper import android.provider.Settings Loading Loading @@ -59,7 +62,16 @@ public fun resetAutoOnTimerForUser( return } timer = Timer.start(looper, context, callback_on) val receiver = object : BroadcastReceiver() { override fun onReceive(ctx: Context, intent: Intent) { Log.i(TAG, "Received ${intent.action} that trigger a new alarm scheduling") pause() resetAutoOnTimerForUser(looper, context, state, callback_on) } } timer = Timer.start(looper, context, receiver, callback_on) } public fun pause() { Loading Loading @@ -115,6 +127,7 @@ internal class Timer private constructor( looper: Looper, private val context: Context, private val receiver: BroadcastReceiver, callback_on: () -> Unit, private val now: LocalDateTime, private val target: LocalDateTime, Loading @@ -135,6 +148,17 @@ private constructor( timeToSleep.inWholeMilliseconds ) Log.i(TAG, "[${this}]: Scheduling next Bluetooth restart") context.registerReceiver( receiver, IntentFilter().apply { addAction(Intent.ACTION_DATE_CHANGED) addAction(Intent.ACTION_TIMEZONE_CHANGED) addAction(Intent.ACTION_TIME_CHANGED) }, null, handler ) } companion object { Loading @@ -153,7 +177,12 @@ private constructor( Settings.Secure.putString(resolver, STORAGE_KEY, null) } fun start(looper: Looper, context: Context, callback_on: () -> Unit): Timer? { fun start( looper: Looper, context: Context, receiver: BroadcastReceiver, callback_on: () -> Unit ): Timer? { val now = LocalDateTime.now() val target = getDateFromStorage(context.contentResolver) ?: nextTimeout(now) val timeToSleep = Loading @@ -166,7 +195,7 @@ private constructor( return null } return Timer(looper, context, callback_on, now, target, timeToSleep) return Timer(looper, context, receiver, callback_on, now, target, timeToSleep) } /** Return a LocalDateTime for tomorrow 5 am */ Loading @@ -177,6 +206,7 @@ private constructor( /** Save timer to storage and stop it */ internal fun pause() { Log.i(TAG, "[${this}]: Pausing timer") context.unregisterReceiver(receiver) handler.removeCallbacksAndMessages(null) } Loading @@ -184,6 +214,7 @@ private constructor( @VisibleForTesting internal fun cancel() { Log.i(TAG, "[${this}]: Cancelling timer") context.unregisterReceiver(receiver) handler.removeCallbacksAndMessages(null) resetStorage(context.contentResolver) } Loading service/src/AutoOnFeatureTest.kt +49 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.bluetooth.test import android.bluetooth.BluetoothAdapter import android.content.Context import android.content.Intent import android.os.Looper import android.provider.Settings import androidx.test.core.app.ApplicationProvider Loading Loading @@ -320,4 +321,52 @@ class AutoOnFeatureTest { expect.that(callback_count).isEqualTo(0) expectNoStorageTime() } @Test fun updateTimezone_whenTimerSchedule_isReScheduled() { setupTimer() // Fake storaged time so when receiving the intent, the test think we jump in the futur val pastTime = timerTarget.minusDays(3) Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) context.sendBroadcast(Intent(Intent.ACTION_TIMEZONE_CHANGED)) shadowOf(looper).idle() expect.that(timer).isNull() expect.that(callback_count).isEqualTo(1) expectNoStorageTime() } @Test fun updateTime_whenTimerSchedule_isReScheduled() { setupTimer() // Fake stored time so when receiving the intent, the test think we jumped in the future val pastTime = timerTarget.minusDays(3) Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) context.sendBroadcast(Intent(Intent.ACTION_TIME_CHANGED)) shadowOf(looper).idle() expect.that(timer).isNull() expect.that(callback_count).isEqualTo(1) expectNoStorageTime() } @Test fun updateDate_whenTimerSchedule_isReScheduled() { setupTimer() // Fake stored time so when receiving the intent, the test think we jumped in the future val pastTime = timerTarget.minusDays(3) Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) context.sendBroadcast(Intent(Intent.ACTION_DATE_CHANGED)) shadowOf(looper).idle() expect.that(timer).isNull() expect.that(callback_count).isEqualTo(1) expectNoStorageTime() } } Loading
service/src/AutoOnFeature.kt +34 −3 Original line number Diff line number Diff line Loading @@ -19,8 +19,11 @@ package com.android.server.bluetooth import android.bluetooth.BluetoothAdapter.STATE_ON import android.content.BroadcastReceiver import android.content.ContentResolver import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Handler import android.os.Looper import android.provider.Settings Loading Loading @@ -59,7 +62,16 @@ public fun resetAutoOnTimerForUser( return } timer = Timer.start(looper, context, callback_on) val receiver = object : BroadcastReceiver() { override fun onReceive(ctx: Context, intent: Intent) { Log.i(TAG, "Received ${intent.action} that trigger a new alarm scheduling") pause() resetAutoOnTimerForUser(looper, context, state, callback_on) } } timer = Timer.start(looper, context, receiver, callback_on) } public fun pause() { Loading Loading @@ -115,6 +127,7 @@ internal class Timer private constructor( looper: Looper, private val context: Context, private val receiver: BroadcastReceiver, callback_on: () -> Unit, private val now: LocalDateTime, private val target: LocalDateTime, Loading @@ -135,6 +148,17 @@ private constructor( timeToSleep.inWholeMilliseconds ) Log.i(TAG, "[${this}]: Scheduling next Bluetooth restart") context.registerReceiver( receiver, IntentFilter().apply { addAction(Intent.ACTION_DATE_CHANGED) addAction(Intent.ACTION_TIMEZONE_CHANGED) addAction(Intent.ACTION_TIME_CHANGED) }, null, handler ) } companion object { Loading @@ -153,7 +177,12 @@ private constructor( Settings.Secure.putString(resolver, STORAGE_KEY, null) } fun start(looper: Looper, context: Context, callback_on: () -> Unit): Timer? { fun start( looper: Looper, context: Context, receiver: BroadcastReceiver, callback_on: () -> Unit ): Timer? { val now = LocalDateTime.now() val target = getDateFromStorage(context.contentResolver) ?: nextTimeout(now) val timeToSleep = Loading @@ -166,7 +195,7 @@ private constructor( return null } return Timer(looper, context, callback_on, now, target, timeToSleep) return Timer(looper, context, receiver, callback_on, now, target, timeToSleep) } /** Return a LocalDateTime for tomorrow 5 am */ Loading @@ -177,6 +206,7 @@ private constructor( /** Save timer to storage and stop it */ internal fun pause() { Log.i(TAG, "[${this}]: Pausing timer") context.unregisterReceiver(receiver) handler.removeCallbacksAndMessages(null) } Loading @@ -184,6 +214,7 @@ private constructor( @VisibleForTesting internal fun cancel() { Log.i(TAG, "[${this}]: Cancelling timer") context.unregisterReceiver(receiver) handler.removeCallbacksAndMessages(null) resetStorage(context.contentResolver) } Loading
service/src/AutoOnFeatureTest.kt +49 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.bluetooth.test import android.bluetooth.BluetoothAdapter import android.content.Context import android.content.Intent import android.os.Looper import android.provider.Settings import androidx.test.core.app.ApplicationProvider Loading Loading @@ -320,4 +321,52 @@ class AutoOnFeatureTest { expect.that(callback_count).isEqualTo(0) expectNoStorageTime() } @Test fun updateTimezone_whenTimerSchedule_isReScheduled() { setupTimer() // Fake storaged time so when receiving the intent, the test think we jump in the futur val pastTime = timerTarget.minusDays(3) Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) context.sendBroadcast(Intent(Intent.ACTION_TIMEZONE_CHANGED)) shadowOf(looper).idle() expect.that(timer).isNull() expect.that(callback_count).isEqualTo(1) expectNoStorageTime() } @Test fun updateTime_whenTimerSchedule_isReScheduled() { setupTimer() // Fake stored time so when receiving the intent, the test think we jumped in the future val pastTime = timerTarget.minusDays(3) Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) context.sendBroadcast(Intent(Intent.ACTION_TIME_CHANGED)) shadowOf(looper).idle() expect.that(timer).isNull() expect.that(callback_count).isEqualTo(1) expectNoStorageTime() } @Test fun updateDate_whenTimerSchedule_isReScheduled() { setupTimer() // Fake stored time so when receiving the intent, the test think we jumped in the future val pastTime = timerTarget.minusDays(3) Settings.Secure.putString(resolver, Timer.STORAGE_KEY, pastTime.toString()) context.sendBroadcast(Intent(Intent.ACTION_DATE_CHANGED)) shadowOf(looper).idle() expect.that(timer).isNull() expect.that(callback_count).isEqualTo(1) expectNoStorageTime() } }