1 /* 2 * Copyright (C) 2022 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.launcher3.taskbar.navbutton 18 19 import android.content.res.Resources 20 import android.view.Surface.ROTATION_90 21 import android.view.Surface.Rotation 22 import android.view.ViewGroup 23 import android.widget.ImageView 24 import android.widget.LinearLayout 25 import android.widget.Space 26 import com.android.launcher3.DeviceProfile 27 import com.android.launcher3.taskbar.TaskbarActivityContext 28 import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.ID_END_CONTEXTUAL_BUTTONS 29 import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.ID_END_NAV_BUTTONS 30 import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.ID_START_CONTEXTUAL_BUTTONS 31 import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.Companion 32 import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter 33 34 /** 35 * Select the correct layout for nav buttons 36 * 37 * Since layouts are done dynamically for the nav buttons on Taskbar, this class returns a 38 * corresponding [NavButtonLayoutter] via [Companion.getUiLayoutter] that can help position the 39 * buttons based on the current [DeviceProfile] 40 */ 41 class NavButtonLayoutFactory { 42 companion object { 43 /** 44 * Get the correct instance of [NavButtonLayoutter] 45 * 46 * No layouts supported for configurations where: 47 * * taskbar isn't showing AND 48 * * the device is not in [phoneMode] OR 49 * * phone is showing 50 * * device is using gesture navigation 51 * 52 * @param navButtonsView ViewGroup that contains start, end, nav button ViewGroups 53 * @param isKidsMode no-op when taskbar is hidden/not showing 54 * @param isInSetup no-op when taskbar is hidden/not showing 55 * @param phoneMode refers to the device using the taskbar window on phones 56 * @param isThreeButtonNav are no-ops when taskbar is present/showing 57 */ getUiLayoutternull58 fun getUiLayoutter( 59 deviceProfile: DeviceProfile, 60 navButtonsView: NearestTouchFrame, 61 imeSwitcher: ImageView?, 62 a11yButton: ImageView?, 63 space: Space?, 64 resources: Resources, 65 isKidsMode: Boolean, 66 isInSetup: Boolean, 67 isThreeButtonNav: Boolean, 68 phoneMode: Boolean, 69 @Rotation surfaceRotation: Int, 70 ): NavButtonLayoutter { 71 val navButtonContainer = 72 navButtonsView.requireViewById<LinearLayout>(ID_END_NAV_BUTTONS) 73 val endContextualContainer = 74 navButtonsView.requireViewById<ViewGroup>(ID_END_CONTEXTUAL_BUTTONS) 75 val startContextualContainer = 76 navButtonsView.requireViewById<ViewGroup>(ID_START_CONTEXTUAL_BUTTONS) 77 val isPhoneNavMode = phoneMode && isThreeButtonNav 78 val isPhoneGestureMode = phoneMode && !isThreeButtonNav 79 return when { 80 isInSetup -> { 81 SetupNavLayoutter( 82 resources, 83 navButtonsView, 84 navButtonContainer, 85 endContextualContainer, 86 startContextualContainer, 87 imeSwitcher, 88 a11yButton, 89 space, 90 ) 91 } 92 isPhoneNavMode -> { 93 if (!deviceProfile.isLandscape) { 94 navButtonsView.setIsVertical(false) 95 PhonePortraitNavLayoutter( 96 resources, 97 navButtonContainer, 98 endContextualContainer, 99 startContextualContainer, 100 imeSwitcher, 101 a11yButton, 102 space, 103 ) 104 } else if (surfaceRotation == ROTATION_90) { 105 navButtonsView.setIsVertical(true) 106 PhoneLandscapeNavLayoutter( 107 resources, 108 navButtonContainer, 109 endContextualContainer, 110 startContextualContainer, 111 imeSwitcher, 112 a11yButton, 113 space, 114 ) 115 } else { 116 navButtonsView.setIsVertical(true) 117 PhoneSeascapeNavLayoutter( 118 resources, 119 navButtonContainer, 120 endContextualContainer, 121 startContextualContainer, 122 imeSwitcher, 123 a11yButton, 124 space, 125 ) 126 } 127 } 128 isPhoneGestureMode -> { 129 PhoneGestureLayoutter( 130 resources, 131 navButtonContainer, 132 endContextualContainer, 133 startContextualContainer, 134 imeSwitcher, 135 a11yButton, 136 space, 137 ) 138 } 139 deviceProfile.isTaskbarPresent -> { 140 return when { 141 isKidsMode -> { 142 KidsNavLayoutter( 143 resources, 144 navButtonContainer, 145 endContextualContainer, 146 startContextualContainer, 147 imeSwitcher, 148 a11yButton, 149 space, 150 ) 151 } 152 else -> 153 TaskbarNavLayoutter( 154 resources, 155 navButtonContainer, 156 endContextualContainer, 157 startContextualContainer, 158 imeSwitcher, 159 a11yButton, 160 space, 161 ) 162 } 163 } 164 else -> error("No layoutter found") 165 } 166 } 167 } 168 169 /** Lays out and provides access to the home, recents, and back buttons for various mischief */ 170 interface NavButtonLayoutter { layoutButtonsnull171 fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) 172 } 173 } 174