1 /* 2 * Copyright (C) 2021 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 package com.android.systemui.qs.tiles.dialog 17 18 import android.util.Log 19 import com.android.internal.jank.InteractionJankMonitor 20 import com.android.systemui.animation.DialogCuj 21 import com.android.systemui.animation.DialogTransitionAnimator 22 import com.android.systemui.animation.Expandable 23 import com.android.systemui.coroutines.newTracingContext 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.dagger.qualifiers.Background 26 import com.android.systemui.statusbar.phone.SystemUIDialog 27 import javax.inject.Inject 28 import kotlinx.coroutines.CoroutineDispatcher 29 import kotlinx.coroutines.CoroutineScope 30 import kotlinx.coroutines.cancel 31 32 private const val TAG = "InternetDialogFactory" 33 private val DEBUG = Log.isLoggable(TAG, Log.DEBUG) 34 35 /** Factory to create [InternetDialogDelegate] objects. */ 36 @SysUISingleton 37 class InternetDialogManager 38 @Inject 39 constructor( 40 private val dialogTransitionAnimator: DialogTransitionAnimator, 41 private val dialogFactory: InternetDialogDelegate.Factory, 42 @Background private val bgDispatcher: CoroutineDispatcher, 43 ) { 44 private lateinit var coroutineScope: CoroutineScope 45 companion object { 46 private const val INTERACTION_JANK_TAG = "internet" 47 var dialog: SystemUIDialog? = null 48 } 49 50 /** 51 * Creates a [InternetDialogDelegate]. The dialog will be animated from [expandable] if it is 52 * not null. 53 */ createnull54 fun create( 55 aboveStatusBar: Boolean, 56 canConfigMobileData: Boolean, 57 canConfigWifi: Boolean, 58 expandable: Expandable? 59 ) { 60 if (dialog != null) { 61 if (DEBUG) { 62 Log.d(TAG, "InternetDialog is showing, do not create it twice.") 63 } 64 return 65 } else { 66 coroutineScope = CoroutineScope(bgDispatcher + newTracingContext("InternetDialogScope")) 67 dialog = 68 dialogFactory 69 .create(aboveStatusBar, canConfigMobileData, canConfigWifi, coroutineScope) 70 .createDialog() 71 val controller = 72 expandable?.dialogTransitionController( 73 DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG) 74 ) 75 controller?.let { 76 dialogTransitionAnimator.show( 77 dialog!!, 78 controller, 79 animateBackgroundBoundsChange = true 80 ) 81 } 82 ?: dialog?.show() 83 } 84 } 85 destroyDialognull86 fun destroyDialog() { 87 if (DEBUG) { 88 Log.d(TAG, "destroyDialog") 89 } 90 if (dialog != null) { 91 coroutineScope.cancel() 92 } 93 dialog = null 94 } 95 } 96