1 /* <lambda>null2 * Copyright (C) 2024 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.statusbar.chips.mediaprojection.ui.view 18 19 import android.app.ActivityManager 20 import android.content.DialogInterface 21 import android.content.pm.PackageManager 22 import android.util.Log 23 import com.android.systemui.animation.DialogTransitionAnimator 24 import com.android.systemui.dagger.SysUISingleton 25 import com.android.systemui.mediaprojection.data.model.MediaProjectionState 26 import com.android.systemui.statusbar.phone.SystemUIDialog 27 import javax.inject.Inject 28 29 /** Helper class for showing dialogs that let users end different types of media projections. */ 30 @SysUISingleton 31 class EndMediaProjectionDialogHelper 32 @Inject 33 constructor( 34 private val dialogFactory: SystemUIDialog.Factory, 35 private val dialogTransitionAnimator: DialogTransitionAnimator, 36 private val packageManager: PackageManager, 37 ) { 38 /** Creates a new [SystemUIDialog] using the given delegate. */ 39 fun createDialog(delegate: SystemUIDialog.Delegate): SystemUIDialog { 40 return dialogFactory.create(delegate) 41 } 42 43 /** 44 * Returns the click listener that should be invoked if a user clicks "Stop" on the end media 45 * projection dialog. 46 * 47 * The click listener will invoke [stopAction] and also do some UI manipulation. 48 * 49 * @param stopAction an action that, when invoked, should notify system API(s) that the media 50 * projection should be stopped. 51 */ 52 fun wrapStopAction(stopAction: () -> Unit): DialogInterface.OnClickListener { 53 return DialogInterface.OnClickListener { _, _ -> 54 // If the projection is stopped, then the chip will disappear, so we don't want the 55 // dialog to animate back into the chip just for the chip to disappear in a few frames. 56 dialogTransitionAnimator.disableAllCurrentDialogsExitAnimations() 57 stopAction.invoke() 58 } 59 } 60 61 fun getAppName(state: MediaProjectionState.Projecting): CharSequence? { 62 val specificTaskInfo = 63 if (state is MediaProjectionState.Projecting.SingleTask) { 64 state.task 65 } else { 66 null 67 } 68 return getAppName(specificTaskInfo) 69 } 70 71 fun getAppName(specificTaskInfo: ActivityManager.RunningTaskInfo?): CharSequence? { 72 val packageName = specificTaskInfo?.baseIntent?.component?.packageName ?: return null 73 return getAppName(packageName) 74 } 75 76 /** 77 * Returns the human-readable application name for the given package, or null if it couldn't be 78 * found for any reason. 79 */ 80 fun getAppName(packageName: String): CharSequence? { 81 return try { 82 val appInfo = packageManager.getApplicationInfo(packageName, 0) 83 appInfo.loadLabel(packageManager) 84 } catch (e: PackageManager.NameNotFoundException) { 85 Log.w( 86 TAG, 87 "Failed to find application info for package: $packageName when creating " + 88 "end media projection dialog", 89 e, 90 ) 91 null 92 } 93 } 94 95 companion object { 96 private const val TAG = "EndMediaProjectionDialogHelper" 97 } 98 } 99