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
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 package com.android.systemui.screenshot
17 
18 import android.content.Intent
19 import android.os.IBinder
20 import android.util.Log
21 import androidx.lifecycle.LifecycleService
22 import androidx.lifecycle.lifecycleScope
23 import com.android.systemui.dagger.qualifiers.Main
24 import com.android.systemui.plugins.ActivityStarter
25 import com.android.systemui.shade.ShadeExpansionStateManager
26 import javax.inject.Inject
27 import kotlinx.coroutines.CoroutineDispatcher
28 import kotlinx.coroutines.launch
29 import kotlinx.coroutines.withContext
30 
31 /** Provides state from the main SystemUI process on behalf of the Screenshot process. */
32 internal class ScreenshotProxyService
33 @Inject
34 constructor(
35     private val mExpansionMgr: ShadeExpansionStateManager,
36     @Main private val mMainDispatcher: CoroutineDispatcher,
37     private val activityStarter: ActivityStarter,
38 ) : LifecycleService() {
39 
40     private val mBinder: IBinder =
41         object : IScreenshotProxy.Stub() {
42             /** @return true when the notification shade is partially or fully expanded. */
43             override fun isNotificationShadeExpanded(): Boolean {
44                 val expanded = !mExpansionMgr.isClosed()
45                 Log.d(TAG, "isNotificationShadeExpanded(): $expanded")
46                 return expanded
47             }
48 
49             override fun dismissKeyguard(callback: IOnDoneCallback) {
50                 lifecycleScope.launch { executeAfterDismissing(callback) }
51             }
52         }
53 
54     private suspend fun executeAfterDismissing(callback: IOnDoneCallback) =
55         withContext(mMainDispatcher) {
56             activityStarter.executeRunnableDismissingKeyguard(
57                 Runnable { callback.onDone(true) },
58                 null,
59                 true /* dismissShade */,
60                 true /* afterKeyguardGone */,
61                 true /* deferred */
62             )
63         }
64 
65     override fun onBind(intent: Intent): IBinder? {
66         Log.d(TAG, "onBind: $intent")
67         return mBinder
68     }
69 
70     companion object {
71         const val TAG = "ScreenshotProxyService"
72     }
73 }
74