1 /* <lambda>null2 * 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.wallpaper.picker.customization.ui 18 19 import android.annotation.TargetApi 20 import android.content.pm.ActivityInfo 21 import android.content.res.Configuration 22 import android.os.Bundle 23 import android.widget.FrameLayout 24 import androidx.activity.viewModels 25 import androidx.appcompat.app.AppCompatActivity 26 import androidx.core.view.WindowCompat 27 import com.android.customization.picker.clock.ui.view.ClockViewFactory 28 import com.android.wallpaper.R 29 import com.android.wallpaper.module.MultiPanesChecker 30 import com.android.wallpaper.picker.AppbarFragment 31 import com.android.wallpaper.picker.category.ui.viewmodel.CategoriesViewModel 32 import com.android.wallpaper.picker.common.preview.data.repository.PersistentWallpaperModelRepository 33 import com.android.wallpaper.picker.common.preview.ui.binder.WorkspaceCallbackBinder 34 import com.android.wallpaper.picker.customization.ui.binder.ColorUpdateBinder 35 import com.android.wallpaper.picker.customization.ui.binder.CustomizationOptionsBinder 36 import com.android.wallpaper.picker.customization.ui.binder.ToolbarBinder 37 import com.android.wallpaper.picker.customization.ui.util.CustomizationOptionUtil 38 import com.android.wallpaper.picker.customization.ui.viewmodel.ColorUpdateViewModel 39 import com.android.wallpaper.picker.di.modules.BackgroundDispatcher 40 import com.android.wallpaper.picker.di.modules.MainDispatcher 41 import com.android.wallpaper.util.ActivityUtils 42 import com.android.wallpaper.util.DisplayUtils 43 import com.android.wallpaper.util.converter.WallpaperModelFactory 44 import com.android.wallpaper.util.wallpaperconnection.WallpaperConnectionUtils 45 import dagger.hilt.android.AndroidEntryPoint 46 import javax.inject.Inject 47 import kotlinx.coroutines.CoroutineScope 48 49 @AndroidEntryPoint(AppCompatActivity::class) 50 class CustomizationPickerActivity2 : 51 Hilt_CustomizationPickerActivity2(), AppbarFragment.AppbarFragmentHost { 52 53 interface ActivityEnterAnimationCallback { 54 /** 55 * The callback is called when Fragment's parent Activity is the first time created and the 56 * enter animation is completed. 57 */ 58 fun onEnterAnimationCompleteAfterActivityCreated() 59 } 60 61 @Inject lateinit var multiPanesChecker: MultiPanesChecker 62 @Inject lateinit var customizationOptionUtil: CustomizationOptionUtil 63 @Inject lateinit var customizationOptionsBinder: CustomizationOptionsBinder 64 @Inject lateinit var workspaceCallbackBinder: WorkspaceCallbackBinder 65 @Inject lateinit var toolbarBinder: ToolbarBinder 66 @Inject lateinit var wallpaperModelFactory: WallpaperModelFactory 67 @Inject lateinit var persistentWallpaperModelRepository: PersistentWallpaperModelRepository 68 @Inject lateinit var displayUtils: DisplayUtils 69 @Inject @BackgroundDispatcher lateinit var backgroundScope: CoroutineScope 70 @Inject @MainDispatcher lateinit var mainScope: CoroutineScope 71 @Inject lateinit var wallpaperConnectionUtils: WallpaperConnectionUtils 72 @Inject lateinit var colorUpdateViewModel: ColorUpdateViewModel 73 @Inject lateinit var clockViewFactory: ClockViewFactory 74 75 private var configuration: Configuration? = null 76 private val categoriesViewModel: CategoriesViewModel by viewModels() 77 private var isInitialCreation = true 78 79 override fun onCreate(savedInstanceState: Bundle?) { 80 super.onCreate(savedInstanceState) 81 82 if (savedInstanceState != null) { 83 // Activity is being restored, not initial creation 84 isInitialCreation = false 85 } 86 87 if ( 88 multiPanesChecker.isMultiPanesEnabled(this) && 89 !ActivityUtils.isLaunchedFromSettingsTrampoline(intent) && 90 !ActivityUtils.isLaunchedFromSettingsRelated(intent) 91 ) { 92 // If the device supports multi panes, we check if the activity is launched by settings. 93 // If not, we need to start an intent to have settings launch the customization 94 // activity. In case it is a two-pane situation and the activity should be embedded in 95 // the settings app, instead of in the full screen. 96 val multiPanesIntent = multiPanesChecker.getMultiPanesIntent(intent) 97 ActivityUtils.startActivityForResultSafely( 98 this, /* activity */ 99 multiPanesIntent, 100 0, /* requestCode */ 101 ) 102 finish() 103 return 104 } 105 categoriesViewModel.initialize() 106 configuration = Configuration(resources.configuration) 107 colorUpdateViewModel.updateDarkModeAndColors() 108 colorUpdateViewModel.setPreviewEnabled(!displayUtils.isLargeScreenOrUnfoldedDisplay(this)) 109 110 setContentView(R.layout.activity_cusomization_picker2) 111 WindowCompat.setDecorFitsSystemWindows(window, ActivityUtils.isSUWMode(this)) 112 113 ColorUpdateBinder.bind( 114 setColor = { color -> 115 requireViewById<FrameLayout>(R.id.fragment_container).setBackgroundColor(color) 116 }, 117 color = colorUpdateViewModel.colorSurfaceContainer, 118 shouldAnimate = { 119 supportFragmentManager.findFragmentById(R.id.fragment_container) is 120 CustomizationPickerFragment2 121 }, 122 lifecycleOwner = this, 123 ) 124 125 val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container) 126 if (fragment == null) { 127 supportFragmentManager 128 .beginTransaction() 129 .add(R.id.fragment_container, CustomizationPickerFragment2()) 130 .commit() 131 } 132 } 133 134 override fun onEnterAnimationComplete() { 135 super.onEnterAnimationComplete() 136 if (isInitialCreation) { 137 val fragment = 138 supportFragmentManager.findFragmentById(R.id.fragment_container) 139 as? CustomizationPickerFragment2 140 fragment?.onEnterAnimationCompleteAfterActivityCreated() 141 isInitialCreation = false 142 } 143 } 144 145 override fun onUpArrowPressed() { 146 onBackPressedDispatcher.onBackPressed() 147 } 148 149 override fun isUpArrowSupported(): Boolean { 150 return !ActivityUtils.isSUWMode(baseContext) 151 } 152 153 @TargetApi(36) 154 override fun onConfigurationChanged(newConfig: Configuration) { 155 super.onConfigurationChanged(newConfig) 156 configuration?.let { 157 val diff = newConfig.diff(it) 158 val isAssetsPathsChange = diff and ActivityInfo.CONFIG_ASSETS_PATHS != 0 159 val isUiModeChange = diff and ActivityInfo.CONFIG_UI_MODE != 0 160 if (isAssetsPathsChange) { 161 colorUpdateViewModel.updateColors() 162 } 163 if (isUiModeChange) { 164 colorUpdateViewModel.updateDarkModeAndColors() 165 } 166 } 167 configuration?.setTo(newConfig) 168 } 169 } 170