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 package com.android.launcher3.uioverrides 17 18 import android.app.ActivityOptions 19 import android.app.PendingIntent 20 import android.app.role.RoleManager 21 import android.content.Context 22 import android.content.IIntentReceiver 23 import android.content.IIntentSender 24 import android.content.Intent 25 import android.content.pm.ActivityInfo 26 import android.content.pm.LauncherActivityInfo 27 import android.content.pm.LauncherApps 28 import android.content.pm.ShortcutInfo 29 import android.os.Bundle 30 import android.os.Flags.allowPrivateProfile 31 import android.os.IBinder 32 import android.os.UserHandle 33 import android.os.UserManager 34 import android.util.ArrayMap 35 import android.widget.Toast 36 import android.window.RemoteTransition 37 import com.android.launcher3.Flags.enablePrivateSpace 38 import com.android.launcher3.Flags.enablePrivateSpaceInstallShortcut 39 import com.android.launcher3.Flags.privateSpaceAppInstallerButton 40 import com.android.launcher3.Flags.privateSpaceSysAppsSeparation 41 import com.android.launcher3.R 42 import com.android.launcher3.Utilities 43 import com.android.launcher3.proxy.ProxyActivityStarter 44 import com.android.launcher3.util.ApiWrapper 45 import com.android.launcher3.util.Executors 46 import com.android.launcher3.util.StartActivityParams 47 import com.android.launcher3.util.UserIconInfo 48 import com.android.quickstep.util.FadeOutRemoteTransition 49 50 /** A wrapper for the hidden API calls */ 51 open class SystemApiWrapper(context: Context?) : ApiWrapper(context) { 52 53 override fun getPersons(si: ShortcutInfo) = si.persons ?: Utilities.EMPTY_PERSON_ARRAY 54 55 override fun getActivityOverrides(): Map<String, LauncherActivityInfo> = 56 mContext.getSystemService(LauncherApps::class.java)!!.activityOverrides 57 58 override fun createFadeOutAnimOptions(): ActivityOptions = 59 ActivityOptions.makeBasic().apply { 60 remoteTransition = RemoteTransition(FadeOutRemoteTransition()) 61 } 62 63 override fun queryAllUsers(): Map<UserHandle, UserIconInfo> { 64 if (!allowPrivateProfile() || !enablePrivateSpace()) { 65 return super.queryAllUsers() 66 } 67 val users = ArrayMap<UserHandle, UserIconInfo>() 68 mContext.getSystemService(UserManager::class.java)!!.userProfiles?.forEach { user -> 69 mContext.getSystemService(LauncherApps::class.java)!!.getLauncherUserInfo(user)?.apply { 70 users[user] = 71 UserIconInfo( 72 user, 73 when (userType) { 74 UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK 75 UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED 76 UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE 77 else -> UserIconInfo.TYPE_MAIN 78 }, 79 userSerialNumber.toLong() 80 ) 81 } 82 } 83 return users 84 } 85 86 override fun getPreInstalledSystemPackages(user: UserHandle): List<String> = 87 if (allowPrivateProfile() && enablePrivateSpace() && privateSpaceSysAppsSeparation()) 88 mContext 89 .getSystemService(LauncherApps::class.java)!! 90 .getPreInstalledSystemPackages(user) 91 else ArrayList() 92 93 override fun getAppMarketActivityIntent(packageName: String, user: UserHandle): Intent = 94 if ( 95 allowPrivateProfile() && 96 enablePrivateSpace() && 97 (privateSpaceAppInstallerButton() || enablePrivateSpaceInstallShortcut()) 98 ) 99 ProxyActivityStarter.getLaunchIntent( 100 mContext, 101 StartActivityParams(null as PendingIntent?, 0).apply { 102 intentSender = 103 mContext 104 .getSystemService(LauncherApps::class.java)!! 105 .getAppMarketActivityIntent(packageName, user) 106 options = 107 ActivityOptions.makeBasic() 108 .setPendingIntentBackgroundActivityStartMode( 109 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED 110 ) 111 .toBundle() 112 requireActivityResult = false 113 } 114 ) 115 else super.getAppMarketActivityIntent(packageName, user) 116 117 /** Returns an intent which can be used to open Private Space Settings. */ 118 override fun getPrivateSpaceSettingsIntent(): Intent? = 119 if (allowPrivateProfile() && enablePrivateSpace()) 120 ProxyActivityStarter.getLaunchIntent( 121 mContext, 122 StartActivityParams(null as PendingIntent?, 0).apply { 123 intentSender = 124 mContext 125 .getSystemService(LauncherApps::class.java) 126 ?.privateSpaceSettingsIntent ?: return null 127 options = 128 ActivityOptions.makeBasic() 129 .setPendingIntentBackgroundActivityStartMode( 130 ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED 131 ) 132 .toBundle() 133 requireActivityResult = false 134 } 135 ) 136 else null 137 138 override fun isNonResizeableActivity(lai: LauncherActivityInfo) = 139 lai.activityInfo.resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE 140 141 /** 142 * Starts an Activity which can be used to set this Launcher as the HOME app, via a consent 143 * screen. In case the consent screen cannot be shown, or the user does not set current Launcher 144 * as HOME app, a toast asking the user to do the latter is shown. 145 */ 146 override fun assignDefaultHomeRole(context: Context) { 147 val roleManager = context.getSystemService(RoleManager::class.java) 148 if ( 149 (roleManager!!.isRoleAvailable(RoleManager.ROLE_HOME) && 150 !roleManager.isRoleHeld(RoleManager.ROLE_HOME)) 151 ) { 152 val roleRequestIntent = roleManager.createRequestRoleIntent(RoleManager.ROLE_HOME) 153 val pendingIntent = 154 PendingIntent( 155 object : IIntentSender.Stub() { 156 override fun send( 157 code: Int, 158 intent: Intent, 159 resolvedType: String?, 160 allowlistToken: IBinder?, 161 finishedReceiver: IIntentReceiver?, 162 requiredPermission: String?, 163 options: Bundle? 164 ) { 165 if (code != -1) { 166 Executors.MAIN_EXECUTOR.execute { 167 Toast.makeText( 168 context, 169 context.getString( 170 R.string.set_default_home_app, 171 context.getString(R.string.derived_app_name) 172 ), 173 Toast.LENGTH_LONG 174 ) 175 .show() 176 } 177 } 178 } 179 } 180 ) 181 val params = StartActivityParams(pendingIntent, 0) 182 params.intent = roleRequestIntent 183 context.startActivity(ProxyActivityStarter.getLaunchIntent(context, params)) 184 } 185 } 186 } 187