1 /* <lambda>null2 * Copyright (C) 2023 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 18 package com.android.systemui.keyguard.ui.view.layout.sections 19 20 import android.content.res.Resources 21 import android.view.WindowInsets 22 import androidx.constraintlayout.widget.ConstraintLayout 23 import androidx.constraintlayout.widget.ConstraintSet 24 import androidx.constraintlayout.widget.ConstraintSet.BOTTOM 25 import androidx.constraintlayout.widget.ConstraintSet.LEFT 26 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID 27 import androidx.constraintlayout.widget.ConstraintSet.RIGHT 28 import androidx.constraintlayout.widget.ConstraintSet.VISIBILITY_MODE_IGNORE 29 import com.android.systemui.animation.view.LaunchableImageView 30 import com.android.systemui.dagger.qualifiers.Main 31 import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor 32 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor 33 import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder 34 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition 35 import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel 36 import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModelModule.Companion.LOCKSCREEN_INSTANCE 37 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel 38 import com.android.systemui.res.R 39 import com.android.systemui.statusbar.KeyguardIndicationController 40 import dagger.Lazy 41 import javax.inject.Inject 42 import javax.inject.Named 43 44 class DefaultShortcutsSection 45 @Inject 46 constructor( 47 @Main private val resources: Resources, 48 @Named(LOCKSCREEN_INSTANCE) 49 private val keyguardQuickAffordancesCombinedViewModel: 50 KeyguardQuickAffordancesCombinedViewModel, 51 private val indicationController: KeyguardIndicationController, 52 private val keyguardBlueprintInteractor: Lazy<KeyguardBlueprintInteractor>, 53 private val keyguardQuickAffordanceViewBinder: KeyguardQuickAffordanceViewBinder, 54 private val keyguardInteractor: KeyguardInteractor, 55 ) : BaseShortcutSection() { 56 57 // Amount to increase the bottom margin by to avoid colliding with inset 58 private var safeInsetBottom = 0 59 60 override fun addViews(constraintLayout: ConstraintLayout) { 61 addLeftShortcut(constraintLayout) 62 addRightShortcut(constraintLayout) 63 64 constraintLayout 65 .requireViewById<LaunchableImageView>(R.id.start_button) 66 .setOnApplyWindowInsetsListener { _, windowInsets -> 67 val tempSafeInset = windowInsets?.displayCutout?.safeInsetBottom ?: 0 68 if (safeInsetBottom != tempSafeInset) { 69 safeInsetBottom = tempSafeInset 70 keyguardBlueprintInteractor 71 .get() 72 .refreshBlueprint(IntraBlueprintTransition.Type.DefaultTransition) 73 } 74 WindowInsets.CONSUMED 75 } 76 } 77 78 override fun bindData(constraintLayout: ConstraintLayout) { 79 leftShortcutHandle?.destroy() 80 leftShortcutHandle = 81 keyguardQuickAffordanceViewBinder.bind( 82 constraintLayout.requireViewById(R.id.start_button), 83 keyguardQuickAffordancesCombinedViewModel.startButton, 84 keyguardQuickAffordancesCombinedViewModel.transitionAlpha, 85 ) { 86 indicationController.showTransientIndication(it) 87 } 88 rightShortcutHandle?.destroy() 89 rightShortcutHandle = 90 keyguardQuickAffordanceViewBinder.bind( 91 constraintLayout.requireViewById(R.id.end_button), 92 keyguardQuickAffordancesCombinedViewModel.endButton, 93 keyguardQuickAffordancesCombinedViewModel.transitionAlpha, 94 ) { 95 indicationController.showTransientIndication(it) 96 } 97 } 98 99 override fun applyConstraints(constraintSet: ConstraintSet) { 100 val width = resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width) 101 val height = resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height) 102 val horizontalOffsetMargin = 103 resources.getDimensionPixelSize(R.dimen.keyguard_affordance_horizontal_offset) 104 val verticalOffsetMargin = 105 resources.getDimensionPixelSize(R.dimen.keyguard_affordance_vertical_offset) 106 107 constraintSet.apply { 108 constrainWidth(R.id.start_button, width) 109 constrainHeight(R.id.start_button, height) 110 connect(R.id.start_button, LEFT, PARENT_ID, LEFT, horizontalOffsetMargin) 111 connect( 112 R.id.start_button, 113 BOTTOM, 114 PARENT_ID, 115 BOTTOM, 116 verticalOffsetMargin + safeInsetBottom, 117 ) 118 119 constrainWidth(R.id.end_button, width) 120 constrainHeight(R.id.end_button, height) 121 connect(R.id.end_button, RIGHT, PARENT_ID, RIGHT, horizontalOffsetMargin) 122 connect( 123 R.id.end_button, 124 BOTTOM, 125 PARENT_ID, 126 BOTTOM, 127 verticalOffsetMargin + safeInsetBottom, 128 ) 129 130 // The constraint set visibility for start and end button are default visible, set to 131 // ignore so the view's own initial visibility (invisible) is used 132 setVisibilityMode(R.id.start_button, VISIBILITY_MODE_IGNORE) 133 setVisibilityMode(R.id.end_button, VISIBILITY_MODE_IGNORE) 134 } 135 136 val shortcutAbsoluteTopInScreen = 137 (resources.displayMetrics.heightPixels - 138 (verticalOffsetMargin + safeInsetBottom) - 139 height) 140 .toFloat() 141 142 keyguardInteractor.setShortcutAbsoluteTop(shortcutAbsoluteTopInScreen) 143 } 144 } 145