1 /* 2 * Copyright (C) 2019 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.server.am; 18 19 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_ACTIVITY; 20 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_ADDED_APPLICATION; 21 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_BACKUP; 22 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_BROADCAST; 23 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_CONTENT_PROVIDER; 24 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_EMPTY; 25 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_LINK_FAIL; 26 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_NEXT_ACTIVITY; 27 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_NEXT_TOP_ACTIVITY; 28 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_ON_HOLD; 29 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_RESTART; 30 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SERVICE; 31 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SYSTEM; 32 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_TOP_ACTIVITY; 33 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_ALARM; 34 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_JOB; 35 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE; 36 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA; 37 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN; 38 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TYPE__UNKNOWN; 39 40 import android.annotation.NonNull; 41 import android.annotation.Nullable; 42 import android.content.ComponentName; 43 44 /** 45 * This class describes various information required to start a process. 46 * 47 * The {@code mHostingType} field describes the reason why we started a process, and 48 * is only used for logging and stats. 49 * 50 * The {@code mHostingName} field describes the Component for which we are starting the 51 * process, and is only used for logging and stats. 52 * 53 * The {@code mHostingZygote} field describes from which Zygote the new process should be spawned. 54 * 55 * The {@code mTriggerType} field describes the trigger that started this processs. This could be 56 * an alarm or a push-message for a broadcast, for example. This is purely for logging and stats. 57 * 58 * {@code mDefiningPackageName} contains the packageName of the package that defines the 59 * component we want to start; this can be different from the packageName and uid in the 60 * ApplicationInfo that we're creating the process with, in case the service is a 61 * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName 62 * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package. 63 * 64 * {@code mDefiningUid} contains the uid of the application that defines the component we want to 65 * start; this can be different from the packageName and uid in the ApplicationInfo that we're 66 * creating the process with, in case the service is a 67 * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName 68 * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package. 69 * 70 * {@code mIsTopApp} will be passed to {@link android.os.Process#start}. So Zygote will initialize 71 * the process with high priority. 72 * 73 * {@code mAction} the broadcast's intent action if the process is started for a broadcast 74 * receiver. 75 */ 76 77 public final class HostingRecord { 78 private static final int REGULAR_ZYGOTE = 0; 79 private static final int WEBVIEW_ZYGOTE = 1; 80 private static final int APP_ZYGOTE = 2; 81 82 public static final String HOSTING_TYPE_ACTIVITY = "activity"; 83 public static final String HOSTING_TYPE_ADDED_APPLICATION = "added application"; 84 public static final String HOSTING_TYPE_BACKUP = "backup"; 85 public static final String HOSTING_TYPE_BROADCAST = "broadcast"; 86 public static final String HOSTING_TYPE_CONTENT_PROVIDER = "content provider"; 87 public static final String HOSTING_TYPE_LINK_FAIL = "link fail"; 88 public static final String HOSTING_TYPE_ON_HOLD = "on-hold"; 89 public static final String HOSTING_TYPE_NEXT_ACTIVITY = "next-activity"; 90 public static final String HOSTING_TYPE_NEXT_TOP_ACTIVITY = "next-top-activity"; 91 public static final String HOSTING_TYPE_RESTART = "restart"; 92 public static final String HOSTING_TYPE_SERVICE = "service"; 93 public static final String HOSTING_TYPE_SYSTEM = "system"; 94 public static final String HOSTING_TYPE_TOP_ACTIVITY = "top-activity"; 95 public static final String HOSTING_TYPE_EMPTY = ""; 96 97 public static final String TRIGGER_TYPE_UNKNOWN = "unknown"; 98 public static final String TRIGGER_TYPE_ALARM = "alarm"; 99 public static final String TRIGGER_TYPE_PUSH_MESSAGE = "push_message"; 100 public static final String TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA = "push_message_over_quota"; 101 public static final String TRIGGER_TYPE_JOB = "job"; 102 103 @NonNull private final String mHostingType; 104 private final String mHostingName; 105 private final int mHostingZygote; 106 private final String mDefiningPackageName; 107 private final int mDefiningUid; 108 private final boolean mIsTopApp; 109 private final String mDefiningProcessName; 110 @Nullable private final String mAction; 111 @NonNull private final String mTriggerType; 112 HostingRecord(@onNull String hostingType)113 public HostingRecord(@NonNull String hostingType) { 114 this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */, 115 -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */, 116 null /* action */, TRIGGER_TYPE_UNKNOWN); 117 } 118 HostingRecord(@onNull String hostingType, ComponentName hostingName)119 public HostingRecord(@NonNull String hostingType, ComponentName hostingName) { 120 this(hostingType, hostingName, REGULAR_ZYGOTE); 121 } 122 HostingRecord(@onNull String hostingType, ComponentName hostingName, @Nullable String action, @Nullable String triggerType)123 public HostingRecord(@NonNull String hostingType, ComponentName hostingName, 124 @Nullable String action, @Nullable String triggerType) { 125 this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, 126 null /* definingPackageName */, -1 /* mDefiningUid */, false /* isTopApp */, 127 null /* definingProcessName */, action, triggerType); 128 } 129 HostingRecord(@onNull String hostingType, ComponentName hostingName, String definingPackageName, int definingUid, String definingProcessName, String triggerType)130 public HostingRecord(@NonNull String hostingType, ComponentName hostingName, 131 String definingPackageName, int definingUid, String definingProcessName, 132 String triggerType) { 133 this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName, 134 definingUid, false /* isTopApp */, definingProcessName, null /* action */, 135 triggerType); 136 } 137 HostingRecord(@onNull String hostingType, ComponentName hostingName, boolean isTopApp)138 public HostingRecord(@NonNull String hostingType, ComponentName hostingName, boolean isTopApp) { 139 this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, 140 null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */, 141 null /* definingProcessName */, null /* action */, TRIGGER_TYPE_UNKNOWN); 142 } 143 HostingRecord(@onNull String hostingType, String hostingName)144 public HostingRecord(@NonNull String hostingType, String hostingName) { 145 this(hostingType, hostingName, REGULAR_ZYGOTE); 146 } 147 HostingRecord(@onNull String hostingType, ComponentName hostingName, int hostingZygote)148 private HostingRecord(@NonNull String hostingType, ComponentName hostingName, 149 int hostingZygote) { 150 this(hostingType, hostingName.toShortString(), hostingZygote); 151 } 152 HostingRecord(@onNull String hostingType, String hostingName, int hostingZygote)153 private HostingRecord(@NonNull String hostingType, String hostingName, int hostingZygote) { 154 this(hostingType, hostingName, hostingZygote, null /* definingPackageName */, 155 -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */, 156 null /* action */, TRIGGER_TYPE_UNKNOWN); 157 } 158 HostingRecord(@onNull String hostingType, String hostingName, int hostingZygote, String definingPackageName, int definingUid, boolean isTopApp, String definingProcessName, @Nullable String action, String triggerType)159 private HostingRecord(@NonNull String hostingType, String hostingName, int hostingZygote, 160 String definingPackageName, int definingUid, boolean isTopApp, 161 String definingProcessName, @Nullable String action, String triggerType) { 162 mHostingType = hostingType; 163 mHostingName = hostingName; 164 mHostingZygote = hostingZygote; 165 mDefiningPackageName = definingPackageName; 166 mDefiningUid = definingUid; 167 mIsTopApp = isTopApp; 168 mDefiningProcessName = definingProcessName; 169 mAction = action; 170 mTriggerType = triggerType; 171 } 172 getType()173 public @NonNull String getType() { 174 return mHostingType; 175 } 176 getName()177 public String getName() { 178 return mHostingName; 179 } 180 isTopApp()181 public boolean isTopApp() { 182 return mIsTopApp; 183 } 184 185 /** 186 * Returns the UID of the package defining the component we want to start. Only valid 187 * when {@link #usesAppZygote()} returns true. 188 * 189 * @return the UID of the hosting application 190 */ getDefiningUid()191 public int getDefiningUid() { 192 return mDefiningUid; 193 } 194 195 /** 196 * Returns the packageName of the package defining the component we want to start. Only valid 197 * when {@link #usesAppZygote()} returns true. 198 * 199 * @return the packageName of the hosting application 200 */ getDefiningPackageName()201 public String getDefiningPackageName() { 202 return mDefiningPackageName; 203 } 204 205 /** 206 * Returns the processName of the component we want to start as specified in the defining app's 207 * manifest. 208 * 209 * @return the processName of the process in the hosting application 210 */ getDefiningProcessName()211 public String getDefiningProcessName() { 212 return mDefiningProcessName; 213 } 214 215 /** 216 * Returns the broadcast's intent action if the process is started for a broadcast receiver. 217 * 218 * @return the intent action of the broadcast. 219 */ getAction()220 public @Nullable String getAction() { 221 return mAction; 222 } 223 224 /** Returns the type of trigger that led to this process start. */ getTriggerType()225 public @NonNull String getTriggerType() { 226 return mTriggerType; 227 } 228 229 /** 230 * Creates a HostingRecord for a process that must spawn from the webview zygote 231 * @param hostingName name of the component to be hosted in this process 232 * @return The constructed HostingRecord 233 */ byWebviewZygote(ComponentName hostingName, String definingPackageName, int definingUid, String definingProcessName)234 public static HostingRecord byWebviewZygote(ComponentName hostingName, 235 String definingPackageName, int definingUid, String definingProcessName) { 236 return new HostingRecord(HostingRecord.HOSTING_TYPE_EMPTY, hostingName.toShortString(), 237 WEBVIEW_ZYGOTE, definingPackageName, definingUid, false /* isTopApp */, 238 definingProcessName, null /* action */, TRIGGER_TYPE_UNKNOWN); 239 } 240 241 /** 242 * Creates a HostingRecord for a process that must spawn from the application zygote 243 * @param hostingName name of the component to be hosted in this process 244 * @param definingPackageName name of the package defining the service 245 * @param definingUid uid of the package defining the service 246 * @return The constructed HostingRecord 247 */ byAppZygote(ComponentName hostingName, String definingPackageName, int definingUid, String definingProcessName)248 public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName, 249 int definingUid, String definingProcessName) { 250 return new HostingRecord(HostingRecord.HOSTING_TYPE_EMPTY, hostingName.toShortString(), 251 APP_ZYGOTE, definingPackageName, definingUid, false /* isTopApp */, 252 definingProcessName, null /* action */, TRIGGER_TYPE_UNKNOWN); 253 } 254 255 /** 256 * @return whether the process should spawn from the application zygote 257 */ usesAppZygote()258 public boolean usesAppZygote() { 259 return mHostingZygote == APP_ZYGOTE; 260 } 261 262 /** 263 * @return whether the process should spawn from the webview zygote 264 */ usesWebviewZygote()265 public boolean usesWebviewZygote() { 266 return mHostingZygote == WEBVIEW_ZYGOTE; 267 } 268 269 /** 270 * Map the string hostingType to enum HostingType defined in ProcessStartTime proto. 271 * @param hostingType 272 * @return enum HostingType defined in ProcessStartTime proto 273 */ getHostingTypeIdStatsd(@onNull String hostingType)274 public static int getHostingTypeIdStatsd(@NonNull String hostingType) { 275 switch(hostingType) { 276 case HOSTING_TYPE_ACTIVITY: 277 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_ACTIVITY; 278 case HOSTING_TYPE_ADDED_APPLICATION: 279 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_ADDED_APPLICATION; 280 case HOSTING_TYPE_BACKUP: 281 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_BACKUP; 282 case HOSTING_TYPE_BROADCAST: 283 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_BROADCAST; 284 case HOSTING_TYPE_CONTENT_PROVIDER: 285 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_CONTENT_PROVIDER; 286 case HOSTING_TYPE_LINK_FAIL: 287 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_LINK_FAIL; 288 case HOSTING_TYPE_ON_HOLD: 289 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_ON_HOLD; 290 case HOSTING_TYPE_NEXT_ACTIVITY: 291 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_NEXT_ACTIVITY; 292 case HOSTING_TYPE_NEXT_TOP_ACTIVITY: 293 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_NEXT_TOP_ACTIVITY; 294 case HOSTING_TYPE_RESTART: 295 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_RESTART; 296 case HOSTING_TYPE_SERVICE: 297 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SERVICE; 298 case HOSTING_TYPE_SYSTEM: 299 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SYSTEM; 300 case HOSTING_TYPE_TOP_ACTIVITY: 301 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_TOP_ACTIVITY; 302 case HOSTING_TYPE_EMPTY: 303 return PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_EMPTY; 304 default: 305 return PROCESS_START_TIME__TYPE__UNKNOWN; 306 } 307 } 308 309 /** 310 * Map the string triggerType to enum TriggerType defined in ProcessStartTime proto. 311 * @param triggerType 312 * @return enum TriggerType defined in ProcessStartTime proto 313 */ getTriggerTypeForStatsd(@onNull String triggerType)314 public static int getTriggerTypeForStatsd(@NonNull String triggerType) { 315 switch(triggerType) { 316 case TRIGGER_TYPE_ALARM: 317 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_ALARM; 318 case TRIGGER_TYPE_PUSH_MESSAGE: 319 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE; 320 case TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA: 321 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA; 322 case TRIGGER_TYPE_JOB: 323 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_JOB; 324 default: 325 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN; 326 } 327 } 328 isTypeActivity(String hostingType)329 private static boolean isTypeActivity(String hostingType) { 330 return HOSTING_TYPE_ACTIVITY.equals(hostingType) 331 || HOSTING_TYPE_NEXT_ACTIVITY.equals(hostingType) 332 || HOSTING_TYPE_NEXT_TOP_ACTIVITY.equals(hostingType) 333 || HOSTING_TYPE_TOP_ACTIVITY.equals(hostingType); 334 } 335 isTypeActivity()336 public boolean isTypeActivity() { 337 return isTypeActivity(mHostingType); 338 } 339 } 340