1 /* 2 * Copyright (C) 2023 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 android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.content.ComponentName; 23 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 27 /** 28 * A service module such as MediaSessionService, VOIP, Camera, Microphone, Location can ask 29 * ActivityManagerService to start a foreground service delegate on behalf of the actual app, 30 * by which the client app's process state can be promoted to FOREGROUND_SERVICE process state which 31 * is higher than the app's actual process state if the app is in the background. This can help to 32 * keep the app in the memory and extra run-time. 33 * The app does not need to define an actual service component nor add it into manifest file. 34 * 35 * @hide 36 */ 37 public class ForegroundServiceDelegationOptions { 38 39 public static final int DELEGATION_SERVICE_DEFAULT = 0; 40 public static final int DELEGATION_SERVICE_DATA_SYNC = 1; 41 public static final int DELEGATION_SERVICE_MEDIA_PLAYBACK = 2; 42 public static final int DELEGATION_SERVICE_PHONE_CALL = 3; 43 public static final int DELEGATION_SERVICE_LOCATION = 4; 44 public static final int DELEGATION_SERVICE_CONNECTED_DEVICE = 5; 45 public static final int DELEGATION_SERVICE_MEDIA_PROJECTION = 6; 46 public static final int DELEGATION_SERVICE_CAMERA = 7; 47 public static final int DELEGATION_SERVICE_MICROPHONE = 8; 48 public static final int DELEGATION_SERVICE_HEALTH = 9; 49 public static final int DELEGATION_SERVICE_REMOTE_MESSAGING = 10; 50 public static final int DELEGATION_SERVICE_SYSTEM_EXEMPTED = 11; 51 public static final int DELEGATION_SERVICE_SPECIAL_USE = 12; 52 53 @IntDef(flag = false, prefix = { "DELEGATION_SERVICE_" }, value = { 54 DELEGATION_SERVICE_DEFAULT, 55 DELEGATION_SERVICE_DATA_SYNC, 56 DELEGATION_SERVICE_MEDIA_PLAYBACK, 57 DELEGATION_SERVICE_PHONE_CALL, 58 DELEGATION_SERVICE_LOCATION, 59 DELEGATION_SERVICE_CONNECTED_DEVICE, 60 DELEGATION_SERVICE_MEDIA_PROJECTION, 61 DELEGATION_SERVICE_CAMERA, 62 DELEGATION_SERVICE_MICROPHONE, 63 DELEGATION_SERVICE_HEALTH, 64 DELEGATION_SERVICE_REMOTE_MESSAGING, 65 DELEGATION_SERVICE_SYSTEM_EXEMPTED, 66 DELEGATION_SERVICE_SPECIAL_USE, 67 }) 68 @Retention(RetentionPolicy.SOURCE) 69 public @interface DelegationService {} 70 71 // The actual app's PID 72 public final int mClientPid; 73 // The actual app's UID 74 public final int mClientUid; 75 // The actual app's package name 76 @NonNull 77 public final String mClientPackageName; 78 // The actual app's app thread 79 @Nullable 80 public final IApplicationThread mClientAppThread; 81 public final boolean mSticky; // Is it a sticky service 82 83 // The delegation service's instance name which is to identify the delegate. 84 @NonNull 85 public String mClientInstanceName; 86 // The foreground service types it consists of. 87 public final int mForegroundServiceTypes; 88 /** 89 * The service's name such as MediaSessionService, VOIP, Camera, Microphone, Location. This is 90 * the internal module's name which actually starts the FGS delegate on behalf of the client 91 * app. 92 */ 93 public final @DelegationService int mDelegationService; 94 ForegroundServiceDelegationOptions(int clientPid, int clientUid, @NonNull String clientPackageName, @NonNull IApplicationThread clientAppThread, boolean isSticky, @NonNull String clientInstanceName, int foregroundServiceTypes, @DelegationService int delegationService)95 public ForegroundServiceDelegationOptions(int clientPid, 96 int clientUid, 97 @NonNull String clientPackageName, 98 @NonNull IApplicationThread clientAppThread, 99 boolean isSticky, 100 @NonNull String clientInstanceName, 101 int foregroundServiceTypes, 102 @DelegationService int delegationService) { 103 mClientPid = clientPid; 104 mClientUid = clientUid; 105 mClientPackageName = clientPackageName; 106 mClientAppThread = clientAppThread; 107 mSticky = isSticky; 108 mClientInstanceName = clientInstanceName; 109 mForegroundServiceTypes = foregroundServiceTypes; 110 mDelegationService = delegationService; 111 } 112 113 /** 114 * A service delegates a foreground service state to a clientUID using a instanceName. 115 * This delegation is uniquely identified by 116 * mDelegationService/mClientUid/mClientPid/mClientInstanceName 117 */ isSameDelegate(ForegroundServiceDelegationOptions that)118 public boolean isSameDelegate(ForegroundServiceDelegationOptions that) { 119 return this.mDelegationService == that.mDelegationService 120 && this.mClientUid == that.mClientUid 121 && this.mClientPid == that.mClientPid 122 && this.mClientInstanceName.equals(that.mClientInstanceName); 123 } 124 125 /** 126 * Construct a component name for this delegate. 127 */ getComponentName()128 public ComponentName getComponentName() { 129 return new ComponentName(mClientPackageName, serviceCodeToString(mDelegationService) 130 + ":" + mClientInstanceName); 131 } 132 133 /** 134 * Get string description of this delegate options. 135 */ getDescription()136 public String getDescription() { 137 StringBuilder sb = new StringBuilder(128); 138 sb.append("ForegroundServiceDelegate{") 139 .append("package:") 140 .append(mClientPackageName) 141 .append(",") 142 .append("service:") 143 .append(serviceCodeToString(mDelegationService)) 144 .append(",") 145 .append("uid:") 146 .append(mClientUid) 147 .append(",") 148 .append("pid:") 149 .append(mClientPid) 150 .append(",") 151 .append("instance:") 152 .append(mClientInstanceName) 153 .append("}"); 154 return sb.toString(); 155 } 156 157 /** 158 * Map the integer service code to string name. 159 * @param serviceCode 160 * @return 161 */ serviceCodeToString(@elegationService int serviceCode)162 public static String serviceCodeToString(@DelegationService int serviceCode) { 163 switch (serviceCode) { 164 case DELEGATION_SERVICE_DEFAULT: 165 return "DEFAULT"; 166 case DELEGATION_SERVICE_DATA_SYNC: 167 return "DATA_SYNC"; 168 case DELEGATION_SERVICE_MEDIA_PLAYBACK: 169 return "MEDIA_PLAYBACK"; 170 case DELEGATION_SERVICE_PHONE_CALL: 171 return "PHONE_CALL"; 172 case DELEGATION_SERVICE_LOCATION: 173 return "LOCATION"; 174 case DELEGATION_SERVICE_CONNECTED_DEVICE: 175 return "CONNECTED_DEVICE"; 176 case DELEGATION_SERVICE_MEDIA_PROJECTION: 177 return "MEDIA_PROJECTION"; 178 case DELEGATION_SERVICE_CAMERA: 179 return "CAMERA"; 180 case DELEGATION_SERVICE_MICROPHONE: 181 return "MICROPHONE"; 182 case DELEGATION_SERVICE_HEALTH: 183 return "HEALTH"; 184 case DELEGATION_SERVICE_REMOTE_MESSAGING: 185 return "REMOTE_MESSAGING"; 186 case DELEGATION_SERVICE_SYSTEM_EXEMPTED: 187 return "SYSTEM_EXEMPTED"; 188 case DELEGATION_SERVICE_SPECIAL_USE: 189 return "SPECIAL_USE"; 190 default: 191 return "(unknown:" + serviceCode + ")"; 192 } 193 } 194 195 /** 196 * The helper class to build the instance of {@link ForegroundServiceDelegate}. 197 * 198 * @hide 199 */ 200 public static class Builder { 201 int mClientPid; // The actual app PID 202 int mClientUid; // The actual app UID 203 String mClientPackageName; // The actual app's package name 204 int mClientNotificationId; // The actual app's notification 205 IApplicationThread mClientAppThread; // The actual app's app thread 206 boolean mSticky; // Is it a sticky service 207 String mClientInstanceName; // The delegation service instance name 208 int mForegroundServiceTypes; // The foreground service types it consists of 209 @DelegationService int mDelegationService; // The internal service's name, i.e. VOIP 210 211 /** 212 * Set the client app's PID. 213 */ setClientPid(int clientPid)214 public Builder setClientPid(int clientPid) { 215 mClientPid = clientPid; 216 return this; 217 } 218 219 /** 220 * Set the client app's UID. 221 */ setClientUid(int clientUid)222 public Builder setClientUid(int clientUid) { 223 mClientUid = clientUid; 224 return this; 225 } 226 227 /** 228 * Set the client app's package name. 229 */ setClientPackageName(@onNull String clientPackageName)230 public Builder setClientPackageName(@NonNull String clientPackageName) { 231 mClientPackageName = clientPackageName; 232 return this; 233 } 234 235 /** 236 * Set the notification ID from the client app. 237 */ setClientNotificationId(int clientNotificationId)238 public Builder setClientNotificationId(int clientNotificationId) { 239 mClientNotificationId = clientNotificationId; 240 return this; 241 } 242 243 /** 244 * Set the client app's application thread. 245 */ setClientAppThread(@onNull IApplicationThread clientAppThread)246 public Builder setClientAppThread(@NonNull IApplicationThread clientAppThread) { 247 mClientAppThread = clientAppThread; 248 return this; 249 } 250 251 /** 252 * Set the client instance of this service. 253 */ setClientInstanceName(@onNull String clientInstanceName)254 public Builder setClientInstanceName(@NonNull String clientInstanceName) { 255 mClientInstanceName = clientInstanceName; 256 return this; 257 } 258 259 /** 260 * Set stickiness of this service. 261 */ setSticky(boolean isSticky)262 public Builder setSticky(boolean isSticky) { 263 mSticky = isSticky; 264 return this; 265 } 266 267 /** 268 * Set the foreground service type. 269 */ setForegroundServiceTypes(int foregroundServiceTypes)270 public Builder setForegroundServiceTypes(int foregroundServiceTypes) { 271 mForegroundServiceTypes = foregroundServiceTypes; 272 return this; 273 } 274 275 /** 276 * Set the delegation service type. 277 */ setDelegationService(@elegationService int delegationService)278 public Builder setDelegationService(@DelegationService int delegationService) { 279 mDelegationService = delegationService; 280 return this; 281 } 282 283 /** 284 * @return An instance of {@link ForegroundServiceDelegationOptions}. 285 */ build()286 public ForegroundServiceDelegationOptions build() { 287 return new ForegroundServiceDelegationOptions(mClientPid, 288 mClientUid, 289 mClientPackageName, 290 mClientAppThread, 291 mSticky, 292 mClientInstanceName, 293 mForegroundServiceTypes, 294 mDelegationService 295 ); 296 } 297 } 298 } 299