Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e90d7a79 authored by William Escande's avatar William Escande
Browse files

SystemServer: AutoOn: Handle time change

Bug: 323060869
Bug: 316946334
Test: atest ServiceBluetoothRoboTests
Change-Id: I37829ee5083d182fc0fd6ff8dd805e57ba48a0a4
parent 1deaa5e5
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -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
@@ -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() {
@@ -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,
@@ -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 {
@@ -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 =
@@ -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 */
@@ -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)
    }

@@ -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)
    }
+49 −0
Original line number Diff line number Diff line
@@ -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
@@ -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()
    }
}