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