Merge "Enhance dagger usage in UnfoldSharedModule"
This commit is contained in:
committed by
Android (Google) Code Review
commit
15b6908100
@@ -49,9 +49,12 @@ android_library {
|
||||
"PluginCoreLib",
|
||||
"androidx.dynamicanimation_dynamicanimation",
|
||||
"androidx.concurrent_concurrent-futures",
|
||||
"dagger2",
|
||||
"jsr330",
|
||||
],
|
||||
java_version: "1.8",
|
||||
min_sdk_version: "current",
|
||||
plugins: ["dagger2-compiler"],
|
||||
}
|
||||
|
||||
java_library {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.unfold
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.hardware.SensorManager
|
||||
import android.hardware.devicestate.DeviceStateManager
|
||||
import android.os.Handler
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
||||
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
|
||||
import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Provides [UnfoldTransitionProgressProvider]. The [Optional] is empty when the transition
|
||||
* animation is disabled.
|
||||
*
|
||||
* This component is meant to be used for places that don't use dagger. By providing those
|
||||
* parameters to the factory, all dagger objects are correctly instantiated. See
|
||||
* [createUnfoldTransitionProgressProvider] for an example.
|
||||
*/
|
||||
@Singleton
|
||||
@Component(modules = [UnfoldSharedModule::class])
|
||||
internal interface UnfoldSharedComponent {
|
||||
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
fun create(
|
||||
@BindsInstance context: Context,
|
||||
@BindsInstance config: UnfoldTransitionConfig,
|
||||
@BindsInstance screenStatusProvider: ScreenStatusProvider,
|
||||
@BindsInstance deviceStateManager: DeviceStateManager,
|
||||
@BindsInstance sensorManager: SensorManager,
|
||||
@BindsInstance @Main handler: Handler,
|
||||
@BindsInstance @Main executor: Executor,
|
||||
@BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
|
||||
@BindsInstance contentResolver: ContentResolver = context.contentResolver
|
||||
): UnfoldSharedComponent
|
||||
}
|
||||
|
||||
val unfoldTransitionProvider: Optional<UnfoldTransitionProgressProvider>
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.unfold
|
||||
|
||||
import android.hardware.SensorManager
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
||||
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
|
||||
import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
|
||||
import com.android.systemui.unfold.updates.DeviceFoldStateProvider
|
||||
import com.android.systemui.unfold.updates.FoldStateProvider
|
||||
import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
|
||||
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
|
||||
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
|
||||
import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
|
||||
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import java.util.Optional
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
class UnfoldSharedModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun unfoldTransitionProgressProvider(
|
||||
config: UnfoldTransitionConfig,
|
||||
scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
|
||||
tracingListener: ATraceLoggerTransitionProgressListener,
|
||||
foldStateProvider: FoldStateProvider
|
||||
): Optional<UnfoldTransitionProgressProvider> =
|
||||
if (!config.isEnabled) {
|
||||
Optional.empty()
|
||||
} else {
|
||||
val baseProgressProvider =
|
||||
if (config.isHingeAngleEnabled) {
|
||||
PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
|
||||
} else {
|
||||
FixedTimingTransitionProgressProvider(foldStateProvider)
|
||||
}
|
||||
Optional.of(
|
||||
scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
|
||||
// Always present callback that logs animation beginning and end.
|
||||
addCallback(tracingListener)
|
||||
})
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFoldStateProvider(
|
||||
deviceFoldStateProvider: DeviceFoldStateProvider
|
||||
): FoldStateProvider = deviceFoldStateProvider
|
||||
|
||||
@Provides
|
||||
fun hingeAngleProvider(
|
||||
config: UnfoldTransitionConfig,
|
||||
sensorManager: SensorManager
|
||||
): HingeAngleProvider =
|
||||
if (config.isHingeAngleEnabled) {
|
||||
HingeSensorAngleProvider(sensorManager)
|
||||
} else {
|
||||
EmptyHingeAngleProvider
|
||||
}
|
||||
}
|
||||
@@ -23,22 +23,16 @@ import android.hardware.devicestate.DeviceStateManager
|
||||
import android.os.Handler
|
||||
import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
||||
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
|
||||
import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
|
||||
import com.android.systemui.unfold.updates.DeviceFoldStateProvider
|
||||
import com.android.systemui.unfold.updates.FoldStateProvider
|
||||
import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
|
||||
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
|
||||
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
|
||||
import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
|
||||
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
/**
|
||||
* Factory for [UnfoldTransitionProgressProvider].
|
||||
*
|
||||
* This is needed as Launcher has to create the object manually. Sysui create it using dagger (see
|
||||
* [UnfoldTransitionModule]).
|
||||
* This is needed as Launcher has to create the object manually. If dagger is available, this object
|
||||
* is provided in [UnfoldSharedModule].
|
||||
*
|
||||
* This should **never** be called from sysui, as the object is already provided in that process.
|
||||
*/
|
||||
fun createUnfoldTransitionProgressProvider(
|
||||
context: Context,
|
||||
@@ -49,62 +43,21 @@ fun createUnfoldTransitionProgressProvider(
|
||||
mainHandler: Handler,
|
||||
mainExecutor: Executor,
|
||||
tracingTagPrefix: String
|
||||
): UnfoldTransitionProgressProvider {
|
||||
|
||||
if (!config.isEnabled) {
|
||||
throw IllegalStateException(
|
||||
"Trying to create " +
|
||||
"UnfoldTransitionProgressProvider when the transition is disabled")
|
||||
}
|
||||
|
||||
val foldStateProvider =
|
||||
createFoldStateProvider(
|
||||
): UnfoldTransitionProgressProvider =
|
||||
DaggerUnfoldSharedComponent.factory()
|
||||
.create(
|
||||
context,
|
||||
config,
|
||||
screenStatusProvider,
|
||||
deviceStateManager,
|
||||
sensorManager,
|
||||
mainHandler,
|
||||
mainExecutor)
|
||||
|
||||
val unfoldTransitionProgressProvider =
|
||||
if (config.isHingeAngleEnabled) {
|
||||
PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
|
||||
} else {
|
||||
FixedTimingTransitionProgressProvider(foldStateProvider)
|
||||
}
|
||||
|
||||
return ScaleAwareTransitionProgressProvider(
|
||||
unfoldTransitionProgressProvider, context.contentResolver)
|
||||
.apply {
|
||||
// Always present callback that logs animation beginning and end.
|
||||
addCallback(ATraceLoggerTransitionProgressListener(tracingTagPrefix))
|
||||
}
|
||||
}
|
||||
|
||||
fun createFoldStateProvider(
|
||||
context: Context,
|
||||
config: UnfoldTransitionConfig,
|
||||
screenStatusProvider: ScreenStatusProvider,
|
||||
deviceStateManager: DeviceStateManager,
|
||||
sensorManager: SensorManager,
|
||||
mainHandler: Handler,
|
||||
mainExecutor: Executor
|
||||
): FoldStateProvider {
|
||||
val hingeAngleProvider =
|
||||
if (config.isHingeAngleEnabled) {
|
||||
HingeSensorAngleProvider(sensorManager)
|
||||
} else {
|
||||
EmptyHingeAngleProvider()
|
||||
}
|
||||
|
||||
return DeviceFoldStateProvider(
|
||||
context,
|
||||
hingeAngleProvider,
|
||||
screenStatusProvider,
|
||||
deviceStateManager,
|
||||
mainExecutor,
|
||||
mainHandler)
|
||||
}
|
||||
mainExecutor,
|
||||
tracingTagPrefix)
|
||||
.unfoldTransitionProvider
|
||||
.orElse(null)
|
||||
?: throw IllegalStateException(
|
||||
"Trying to create " +
|
||||
"UnfoldTransitionProgressProvider when the transition is disabled")
|
||||
|
||||
fun createConfig(context: Context): UnfoldTransitionConfig = ResourceUnfoldTransitionConfig(context)
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.os.Handler
|
||||
import android.util.Log
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.core.util.Consumer
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
|
||||
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
|
||||
import com.android.systemui.unfold.updates.hinge.FULLY_CLOSED_DEGREES
|
||||
@@ -29,14 +30,17 @@ import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES
|
||||
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
|
||||
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Inject
|
||||
|
||||
class DeviceFoldStateProvider(
|
||||
class DeviceFoldStateProvider
|
||||
@Inject
|
||||
constructor(
|
||||
context: Context,
|
||||
private val hingeAngleProvider: HingeAngleProvider,
|
||||
private val screenStatusProvider: ScreenStatusProvider,
|
||||
private val deviceStateManager: DeviceStateManager,
|
||||
private val mainExecutor: Executor,
|
||||
private val handler: Handler
|
||||
@Main private val mainExecutor: Executor,
|
||||
@Main private val handler: Handler
|
||||
) : FoldStateProvider {
|
||||
|
||||
private val outputListeners: MutableList<FoldUpdatesListener> = mutableListOf()
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.android.systemui.unfold.updates.hinge
|
||||
|
||||
import androidx.core.util.Consumer
|
||||
|
||||
internal class EmptyHingeAngleProvider : HingeAngleProvider {
|
||||
internal object EmptyHingeAngleProvider : HingeAngleProvider {
|
||||
override fun start() {
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.android.systemui.unfold.util
|
||||
|
||||
import android.os.Trace
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/**
|
||||
* Listener that logs start and end of the fold-unfold transition.
|
||||
@@ -9,7 +11,10 @@ import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionPr
|
||||
* [tracePrefix] arg helps in differentiating those. Currently, this is expected to be logged twice
|
||||
* for each fold/unfold: in (1) systemui and (2) launcher process.
|
||||
*/
|
||||
class ATraceLoggerTransitionProgressListener(tracePrefix: String) : TransitionProgressListener {
|
||||
class ATraceLoggerTransitionProgressListener
|
||||
@Inject
|
||||
internal constructor(@UnfoldTransitionATracePrefix tracePrefix: String) :
|
||||
TransitionProgressListener {
|
||||
|
||||
private val traceName = "$tracePrefix#$UNFOLD_TRANSITION_TRACE_NAME"
|
||||
|
||||
@@ -27,3 +32,5 @@ class ATraceLoggerTransitionProgressListener(tracePrefix: String) : TransitionPr
|
||||
}
|
||||
|
||||
private const val UNFOLD_TRANSITION_TRACE_NAME = "FoldUnfoldTransitionInProgress"
|
||||
|
||||
@Qualifier annotation class UnfoldTransitionATracePrefix
|
||||
@@ -6,15 +6,20 @@ import android.database.ContentObserver
|
||||
import android.provider.Settings
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
|
||||
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
/** Wraps [UnfoldTransitionProgressProvider] to disable transitions when animations are disabled. */
|
||||
class ScaleAwareTransitionProgressProvider(
|
||||
unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
|
||||
class ScaleAwareTransitionProgressProvider
|
||||
@AssistedInject
|
||||
constructor(
|
||||
@Assisted progressProviderToWrap: UnfoldTransitionProgressProvider,
|
||||
private val contentResolver: ContentResolver
|
||||
) : UnfoldTransitionProgressProvider {
|
||||
|
||||
private val scopedUnfoldTransitionProgressProvider =
|
||||
ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider)
|
||||
ScopedUnfoldTransitionProgressProvider(progressProviderToWrap)
|
||||
|
||||
private val animatorDurationScaleObserver = object : ContentObserver(null) {
|
||||
override fun onChange(selfChange: Boolean) {
|
||||
@@ -47,4 +52,11 @@ class ScaleAwareTransitionProgressProvider(
|
||||
contentResolver.unregisterContentObserver(animatorDurationScaleObserver)
|
||||
scopedUnfoldTransitionProgressProvider.destroy()
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun wrap(
|
||||
progressProvider: UnfoldTransitionProgressProvider
|
||||
): ScaleAwareTransitionProgressProvider
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,87 +17,38 @@
|
||||
package com.android.systemui.unfold
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.SensorManager
|
||||
import android.hardware.devicestate.DeviceStateManager
|
||||
import android.os.Handler
|
||||
import android.view.IWindowManager
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.keyguard.LifecycleScreenStatusProvider
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
||||
import com.android.systemui.unfold.updates.FoldStateProvider
|
||||
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
|
||||
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
|
||||
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
|
||||
import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
|
||||
import com.android.systemui.util.time.SystemClockImpl
|
||||
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
|
||||
import dagger.Lazy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@Module(includes = [UnfoldSharedModule::class])
|
||||
class UnfoldTransitionModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUnfoldTransitionProgressProvider(
|
||||
context: Context,
|
||||
config: UnfoldTransitionConfig,
|
||||
screenStatusProvider: Lazy<LifecycleScreenStatusProvider>,
|
||||
deviceStateManager: DeviceStateManager,
|
||||
sensorManager: SensorManager,
|
||||
@Main executor: Executor,
|
||||
@Main handler: Handler
|
||||
): Optional<UnfoldTransitionProgressProvider> =
|
||||
if (config.isEnabled) {
|
||||
Optional.of(
|
||||
createUnfoldTransitionProgressProvider(
|
||||
context,
|
||||
config,
|
||||
screenStatusProvider.get(),
|
||||
deviceStateManager,
|
||||
sensorManager,
|
||||
handler,
|
||||
executor,
|
||||
tracingTagPrefix = "systemui"))
|
||||
} else {
|
||||
Optional.empty()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFoldStateProvider(
|
||||
context: Context,
|
||||
config: UnfoldTransitionConfig,
|
||||
screenStatusProvider: Lazy<LifecycleScreenStatusProvider>,
|
||||
deviceStateManager: DeviceStateManager,
|
||||
sensorManager: SensorManager,
|
||||
@Main executor: Executor,
|
||||
@Main handler: Handler
|
||||
): Optional<FoldStateProvider> =
|
||||
if (!config.isHingeAngleEnabled) {
|
||||
Optional.empty()
|
||||
} else {
|
||||
Optional.of(
|
||||
createFoldStateProvider(
|
||||
context,
|
||||
config,
|
||||
screenStatusProvider.get(),
|
||||
deviceStateManager,
|
||||
sensorManager,
|
||||
handler,
|
||||
executor))
|
||||
}
|
||||
@Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesFoldStateLoggingProvider(
|
||||
optionalFoldStateProvider: Optional<FoldStateProvider>
|
||||
config: UnfoldTransitionConfig,
|
||||
foldStateProvider: Lazy<FoldStateProvider>
|
||||
): Optional<FoldStateLoggingProvider> =
|
||||
optionalFoldStateProvider.map { foldStateProvider ->
|
||||
FoldStateLoggingProviderImpl(foldStateProvider, SystemClockImpl())
|
||||
if (config.isHingeAngleEnabled) {
|
||||
Optional.of(FoldStateLoggingProviderImpl(foldStateProvider.get(), SystemClockImpl()))
|
||||
} else {
|
||||
Optional.empty()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@@ -144,6 +95,9 @@ class UnfoldTransitionModule {
|
||||
} else {
|
||||
ShellUnfoldProgressProvider.NO_PROVIDER
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun screenStatusProvider(impl: LifecycleScreenStatusProvider): ScreenStatusProvider = impl
|
||||
}
|
||||
|
||||
const val UNFOLD_STATUS_BAR = "unfold_status_bar"
|
||||
|
||||
Reference in New Issue
Block a user