1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.shade.domain.interactor 18 19 import android.content.Intent 20 import android.content.IntentFilter 21 import android.os.UserHandle 22 import android.provider.AlarmClock 23 import com.android.systemui.broadcast.BroadcastDispatcher 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.plugins.ActivityStarter 26 import com.android.systemui.shade.data.repository.ShadeHeaderClockRepository 27 import com.android.systemui.util.kotlin.emitOnStart 28 import com.android.systemui.util.time.SystemClock 29 import java.util.Date 30 import javax.inject.Inject 31 import kotlinx.coroutines.flow.Flow 32 import kotlinx.coroutines.flow.map 33 34 @SysUISingleton 35 class ShadeHeaderClockInteractor 36 @Inject 37 constructor( 38 private val repository: ShadeHeaderClockRepository, 39 private val activityStarter: ActivityStarter, 40 private val broadcastDispatcher: BroadcastDispatcher, 41 private val systemClock: SystemClock, 42 ) { 43 /** [Flow] that emits `Unit` whenever the timezone or locale has changed. */ 44 val onTimezoneOrLocaleChanged: Flow<Unit> = 45 broadcastFlowForActions(Intent.ACTION_TIMEZONE_CHANGED, Intent.ACTION_LOCALE_CHANGED) 46 .emitOnStart() 47 48 /** [Flow] that emits the current `Date` every minute, or when the system time has changed. */ 49 val currentTime: Flow<Date> = 50 broadcastFlowForActions(Intent.ACTION_TIME_TICK, Intent.ACTION_TIME_CHANGED) 51 .emitOnStart() <lambda>null52 .map { Date(systemClock.currentTimeMillis()) } 53 54 /** Launch the clock activity. */ launchClockActivitynull55 fun launchClockActivity() { 56 val nextAlarmIntent = repository.nextAlarmIntent 57 if (nextAlarmIntent != null) { 58 activityStarter.postStartActivityDismissingKeyguard(nextAlarmIntent) 59 } else { 60 activityStarter.postStartActivityDismissingKeyguard( 61 Intent(AlarmClock.ACTION_SHOW_ALARMS), 62 0, 63 ) 64 } 65 } 66 67 /** 68 * Returns a `Flow` that, when collected, emits `Unit` whenever a broadcast matching one of the 69 * given [actionsToFilter] is received. 70 */ broadcastFlowForActionsnull71 private fun broadcastFlowForActions( 72 vararg actionsToFilter: String, 73 user: UserHandle = UserHandle.SYSTEM, 74 ): Flow<Unit> { 75 return broadcastDispatcher.broadcastFlow( 76 filter = IntentFilter().apply { actionsToFilter.forEach(::addAction) }, 77 user = user, 78 ) 79 } 80 } 81