1 /* 2 * 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.quickstep 18 19 import android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS 20 import android.app.PendingIntent 21 import android.app.RemoteAction 22 import android.content.Context 23 import android.graphics.drawable.Icon 24 import android.view.accessibility.AccessibilityManager 25 import com.android.launcher3.R 26 import java.util.concurrent.Executor 27 28 /** 29 * Registers a [RemoteAction] for toggling All Apps if needed. 30 * 31 * We need this action when either [isHomeAndOverviewSame] or [isTaskbarPresent] is `true`. When 32 * home and overview are the same, we can control Launcher's or Taskbar's All Apps tray. If they are 33 * not the same, but Taskbar is present, we can only control Taskbar's tray. 34 */ 35 class AllAppsActionManager( 36 private val context: Context, 37 private val bgExecutor: Executor, 38 private val createAllAppsPendingIntent: () -> PendingIntent, 39 ) { 40 41 /** `true` if home and overview are the same Activity. */ 42 var isHomeAndOverviewSame = false 43 set(value) { 44 field = value 45 updateSystemAction() 46 } 47 48 /** `true` if Taskbar is enabled. */ 49 var isTaskbarPresent = false 50 set(value) { 51 field = value 52 updateSystemAction() 53 } 54 55 /** `true` if the action should be registered. */ 56 var isActionRegistered = false 57 private set 58 updateSystemActionnull59 private fun updateSystemAction() { 60 val shouldRegisterAction = isHomeAndOverviewSame || isTaskbarPresent 61 if (isActionRegistered == shouldRegisterAction) return 62 isActionRegistered = shouldRegisterAction 63 64 bgExecutor.execute { 65 val accessibilityManager = 66 context.getSystemService(AccessibilityManager::class.java) ?: return@execute 67 if (shouldRegisterAction) { 68 accessibilityManager.registerSystemAction( 69 RemoteAction( 70 Icon.createWithResource(context, R.drawable.ic_apps), 71 context.getString(R.string.all_apps_label), 72 context.getString(R.string.all_apps_label), 73 createAllAppsPendingIntent(), 74 ), 75 GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS, 76 ) 77 } else { 78 accessibilityManager.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS) 79 } 80 } 81 } 82 onDestroynull83 fun onDestroy() { 84 isActionRegistered = false 85 context 86 .getSystemService(AccessibilityManager::class.java) 87 ?.unregisterSystemAction( 88 GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS, 89 ) 90 } 91 } 92