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