1 /*
2  * Copyright (C) 2023 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.unfold.progress
18 
19 import android.util.Log
20 import androidx.annotation.BinderThread
21 import androidx.annotation.FloatRange
22 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
23 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
24 import com.android.systemui.unfold.dagger.UnfoldMain
25 import com.android.systemui.unfold.dagger.UseReceivingFilter
26 import java.util.concurrent.Executor
27 import javax.inject.Inject
28 
29 /**
30  * Receives unfold events from remote senders (System UI).
31  *
32  * A binder to an instance to this class (created with [RemoteUnfoldTransitionReceiver.asBinder])
33  * should be sent to the remote process providing events.
34  */
35 class RemoteUnfoldTransitionReceiver
36 @Inject
37 constructor(
38     @UseReceivingFilter useReceivingFilter: Boolean,
39     @UnfoldMain private val executor: Executor
40 ) : UnfoldTransitionProgressProvider, IUnfoldTransitionListener.Stub() {
41 
42     private val listeners: MutableSet<TransitionProgressListener> = mutableSetOf()
43     private val outputProgressListener = ProcessedProgressListener()
44     private val filter: TransitionProgressListener? =
45         if (useReceivingFilter) {
46             UnfoldRemoteFilter(outputProgressListener)
47         } else {
48             null
49         }
50 
51     @BinderThread
52     override fun onTransitionStarted() {
53         executor.execute {
54             filter?.onTransitionStarted() ?: outputProgressListener.onTransitionStarted()
55         }
56     }
57 
58     @BinderThread
59     override fun onTransitionProgress(progress: Float) {
60         executor.execute {
61             filter?.onTransitionProgress(progress)
62                 ?: outputProgressListener.onTransitionProgress(progress)
63         }
64     }
65 
66     @BinderThread
67     override fun onTransitionFinished() {
68         executor.execute {
69             filter?.onTransitionFinished() ?: outputProgressListener.onTransitionFinished()
70         }
71     }
72 
73     override fun addCallback(listener: TransitionProgressListener) {
74         listeners += listener
75     }
76 
77     override fun removeCallback(listener: TransitionProgressListener) {
78         listeners -= listener
79     }
80 
81     override fun destroy() {
82         listeners.clear()
83     }
84 
85     private inner class ProcessedProgressListener : TransitionProgressListener {
86         override fun onTransitionStarted() {
87             log { "onTransitionStarted" }
88             listeners.forEach { it.onTransitionStarted() }
89         }
90 
91         override fun onTransitionProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) {
92             log { "onTransitionProgress" }
93             listeners.forEach { it.onTransitionProgress(progress) }
94         }
95 
96         override fun onTransitionFinished() {
97             log { "onTransitionFinished" }
98             listeners.forEach { it.onTransitionFinished() }
99         }
100     }
101 
102     private fun log(s: () -> String) {
103         if (DEBUG) {
104             Log.d(TAG, s())
105         }
106     }
107 }
108 
109 private const val TAG = "RemoteUnfoldReceiver"
110 private val DEBUG = false
111