1 /* 2 * Copyright (C) 2021 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 android.app; 18 19 import static android.app.ActivityOptions.BackgroundActivityStartMode; 20 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED; 21 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_COMPAT; 22 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED; 23 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; 24 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.SuppressLint; 28 import android.annotation.TestApi; 29 import android.os.Bundle; 30 31 /** 32 * Base class for {@link ActivityOptions} and {@link BroadcastOptions}. 33 * @hide 34 */ 35 // Expose the methods and constants required to test the SystemApis in subclasses. 36 @TestApi 37 // Suppressed since lint is recommending class have a suffix of Params. 38 @SuppressLint("UserHandleName") 39 @android.ravenwood.annotation.RavenwoodKeepWholeClass 40 public class ComponentOptions { 41 42 /** 43 * PendingIntent caller allows activity start even if PendingIntent creator is in background. 44 * This only works if the PendingIntent caller is allowed to start background activities, 45 * for example if it's in the foreground, or has BAL permission. 46 * @hide 47 */ 48 public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED = 49 "android.pendingIntent.backgroundActivityAllowed"; 50 51 /** 52 * PendingIntent caller allows activity to be started if caller has BAL permission. 53 * @hide 54 */ 55 public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION = 56 "android.pendingIntent.backgroundActivityAllowedByPermission"; 57 58 private Integer mPendingIntentBalAllowed = MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; 59 private boolean mPendingIntentBalAllowedByPermission = false; 60 ComponentOptions()61 ComponentOptions() { 62 } 63 ComponentOptions(Bundle opts)64 ComponentOptions(Bundle opts) { 65 // If the remote side sent us bad parcelables, they won't get the 66 // results they want, which is their loss. 67 opts.setDefusable(true); 68 69 mPendingIntentBalAllowed = 70 opts.getInt(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, 71 MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); 72 setPendingIntentBackgroundActivityLaunchAllowedByPermission( 73 opts.getBoolean( 74 KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, false)); 75 } 76 77 /** 78 * Set PendingIntent activity is allowed to be started in the background if the caller 79 * can start background activities. 80 * 81 * @deprecated use #setPendingIntentBackgroundActivityStartMode(int) to set the full range 82 * of states 83 * @hide 84 */ setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed)85 @Deprecated public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) { 86 mPendingIntentBalAllowed = allowed ? MODE_BACKGROUND_ACTIVITY_START_ALLOWED 87 : MODE_BACKGROUND_ACTIVITY_START_DENIED; 88 } 89 90 /** 91 * Get PendingIntent activity is allowed to be started in the background if the caller can start 92 * background activities. 93 * 94 * @deprecated use {@link #getPendingIntentBackgroundActivityStartMode()} since for apps 95 * targeting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or higher this value might 96 * not match the actual behavior if the value was not explicitly set. 97 * @hide 98 */ isPendingIntentBackgroundActivityLaunchAllowed()99 @Deprecated public boolean isPendingIntentBackgroundActivityLaunchAllowed() { 100 // cannot return all detail, so return the value used up to API level 33 for compatibility 101 return mPendingIntentBalAllowed != MODE_BACKGROUND_ACTIVITY_START_DENIED; 102 } 103 104 /** 105 * Sets the mode for allowing or denying the senders privileges to start background activities 106 * to the PendingIntent. 107 * 108 * This is typically used in when executing {@link PendingIntent#send(Bundle)} or similar 109 * methods. A privileged sender of a PendingIntent should only grant 110 * {@link #MODE_BACKGROUND_ACTIVITY_START_ALLOWED} if the PendingIntent is from a trusted source 111 * and/or executed on behalf the user. 112 * @hide 113 */ setPendingIntentBackgroundActivityStartMode( @ackgroundActivityStartMode int state)114 public @NonNull ComponentOptions setPendingIntentBackgroundActivityStartMode( 115 @BackgroundActivityStartMode int state) { 116 switch (state) { 117 case MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED: 118 case MODE_BACKGROUND_ACTIVITY_START_DENIED: 119 case MODE_BACKGROUND_ACTIVITY_START_COMPAT: 120 case MODE_BACKGROUND_ACTIVITY_START_ALLOWED: 121 mPendingIntentBalAllowed = state; 122 break; 123 default: 124 // Assume that future values are some variant of allowing the start. 125 mPendingIntentBalAllowed = MODE_BACKGROUND_ACTIVITY_START_ALLOWED; 126 break; 127 } 128 return this; 129 } 130 131 /** 132 * Gets the mode for allowing or denying the senders privileges to start background activities 133 * to the PendingIntent. 134 * @hide 135 * 136 * @see #setPendingIntentBackgroundActivityStartMode(int) 137 */ getPendingIntentBackgroundActivityStartMode()138 public @BackgroundActivityStartMode int getPendingIntentBackgroundActivityStartMode() { 139 return mPendingIntentBalAllowed; 140 } 141 142 /** 143 * Set PendingIntent activity can be launched from background if caller has BAL permission. 144 * @hide 145 */ setPendingIntentBackgroundActivityLaunchAllowedByPermission(boolean allowed)146 public void setPendingIntentBackgroundActivityLaunchAllowedByPermission(boolean allowed) { 147 mPendingIntentBalAllowedByPermission = allowed; 148 } 149 150 /** 151 * Get PendingIntent activity is allowed to be started in the background if the caller 152 * has BAL permission. 153 * @hide 154 */ isPendingIntentBackgroundActivityLaunchAllowedByPermission()155 public boolean isPendingIntentBackgroundActivityLaunchAllowedByPermission() { 156 return mPendingIntentBalAllowedByPermission; 157 } 158 159 /** @hide */ toBundle()160 public Bundle toBundle() { 161 Bundle b = new Bundle(); 162 if (mPendingIntentBalAllowed != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) { 163 b.putInt(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, mPendingIntentBalAllowed); 164 } 165 if (mPendingIntentBalAllowedByPermission) { 166 b.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, 167 mPendingIntentBalAllowedByPermission); 168 } 169 return b; 170 } 171 172 /** @hide */ fromBundle(@ullable Bundle options)173 public static @Nullable ComponentOptions fromBundle(@Nullable Bundle options) { 174 return (options != null) ? new ComponentOptions(options) : null; 175 } 176 } 177