1 /* 2 * Copyright (C) 2025 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.animation 18 19 import android.content.ComponentName 20 import android.util.Log 21 import com.android.systemui.animation.ActivityTransitionAnimator.Controller 22 import com.android.systemui.animation.ActivityTransitionAnimator.ControllerFactory 23 import kotlinx.coroutines.flow.MutableStateFlow 24 25 private const val TAG = "ComposableControllerFactory" 26 27 /** 28 * [ControllerFactory] extension for Compose. Since composables are not guaranteed to be part of the 29 * composition when [ControllerFactory.createController] is called, this class provides a way for 30 * the composable to register itself at the time of composition, and deregister itself when 31 * disposed. 32 */ 33 abstract class ComposableControllerFactory( 34 cookie: ActivityTransitionAnimator.TransitionCookie, 35 component: ComponentName?, 36 launchCujType: Int? = null, 37 returnCujType: Int? = null, 38 ) : ControllerFactory(cookie, component, launchCujType, returnCujType) { 39 /** 40 * The object to be used to create [Controller]s, when its associate composable is in the 41 * composition. 42 */ 43 protected val expandable = MutableStateFlow<Expandable?>(null) 44 45 /** To be called when the composable to be animated enters composition. */ onComposenull46 fun onCompose(expandable: Expandable) { 47 if (TransitionAnimator.DEBUG) { 48 Log.d(TAG, "Composable entered composition (expandable=$expandable") 49 } 50 this.expandable.value = expandable 51 } 52 53 /** To be called when the composable to be animated exits composition. */ onDisposenull54 fun onDispose() { 55 if (TransitionAnimator.DEBUG) { 56 Log.d(TAG, "Composable left composition (expandable=${this.expandable.value}") 57 } 58 this.expandable.value = null 59 } 60 } 61