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 distributed under the 11 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 12 * KIND, either express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 package com.android.systemui.unfold.util 16 17 import android.content.ContentResolver 18 import android.database.ContentObserver 19 import android.provider.Settings 20 import com.android.systemui.unfold.UnfoldTransitionProgressProvider 21 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener 22 import dagger.assisted.Assisted 23 import dagger.assisted.AssistedFactory 24 import dagger.assisted.AssistedInject 25 26 /** Wraps [UnfoldTransitionProgressProvider] to disable transitions when animations are disabled. */ 27 class ScaleAwareTransitionProgressProvider 28 @AssistedInject 29 constructor( 30 @Assisted progressProviderToWrap: UnfoldTransitionProgressProvider, 31 private val contentResolver: ContentResolver 32 ) : UnfoldTransitionProgressProvider { 33 34 private val scopedUnfoldTransitionProgressProvider = 35 ScopedUnfoldTransitionProgressProvider(progressProviderToWrap) 36 37 private val animatorDurationScaleObserver = 38 object : ContentObserver(null) { onChangenull39 override fun onChange(selfChange: Boolean) { 40 onAnimatorScaleChanged() 41 } 42 } 43 44 init { 45 contentResolver.registerContentObserver( 46 Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE), 47 /* notifyForDescendants= */ false, 48 animatorDurationScaleObserver 49 ) 50 onAnimatorScaleChanged() 51 } 52 onAnimatorScaleChangednull53 private fun onAnimatorScaleChanged() { 54 scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition( 55 contentResolver.areAnimationsEnabled() 56 ) 57 } 58 addCallbacknull59 override fun addCallback(listener: TransitionProgressListener) { 60 scopedUnfoldTransitionProgressProvider.addCallback(listener) 61 } 62 removeCallbacknull63 override fun removeCallback(listener: TransitionProgressListener) { 64 scopedUnfoldTransitionProgressProvider.removeCallback(listener) 65 } 66 destroynull67 override fun destroy() { 68 contentResolver.unregisterContentObserver(animatorDurationScaleObserver) 69 scopedUnfoldTransitionProgressProvider.destroy() 70 } 71 72 @AssistedFactory 73 interface Factory { wrapnull74 fun wrap( 75 progressProvider: UnfoldTransitionProgressProvider 76 ): ScaleAwareTransitionProgressProvider 77 } 78 79 companion object { 80 fun ContentResolver.areAnimationsEnabled(): Boolean { 81 val animationScale = 82 Settings.Global.getString( 83 this, 84 Settings.Global.ANIMATOR_DURATION_SCALE, 85 ) 86 ?.toFloatOrNull() 87 ?: 1f 88 return animationScale != 0f 89 } 90 } 91 } 92