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 android.os; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.profiling.Flags; 24 import android.text.TextUtils; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * Encapsulates results of a single profiling request operation. 32 */ 33 @FlaggedApi(Flags.FLAG_TELEMETRY_APIS) 34 public final class ProfilingResult implements Parcelable { 35 36 // LINT.IfChange(params) 37 /** @see #getErrorCode */ 38 final @ErrorCode int mErrorCode; 39 40 /** @see #getResultFilePath */ 41 @Nullable final String mResultFilePath; 42 43 /** @see #getTag */ 44 @Nullable final String mTag; 45 46 /** @see #getErrorMessage */ 47 @Nullable final String mErrorMessage; 48 49 /** @see #getTriggerType */ 50 final int mTriggerType; 51 // LINT.ThenChange(:from_parcel) 52 53 /** The request was executed and succeeded. */ 54 public static final int ERROR_NONE = 0; 55 56 /** The request was denied due to system level rate limiting. */ 57 public static final int ERROR_FAILED_RATE_LIMIT_SYSTEM = 1; 58 59 /** The request was denied due to process level rate limiting. */ 60 public static final int ERROR_FAILED_RATE_LIMIT_PROCESS = 2; 61 62 /** The request was denied due to profiling already in progress. */ 63 public static final int ERROR_FAILED_PROFILING_IN_PROGRESS = 3; 64 65 /** The request was executed and failed for a reason not specified below. */ 66 public static final int ERROR_FAILED_EXECUTING = 4; 67 68 /** The request was executed but post processing failed and the result was discarded. */ 69 public static final int ERROR_FAILED_POST_PROCESSING = 5; 70 71 /** The request was executed and failed due to a lack of disk space. */ 72 public static final int ERROR_FAILED_NO_DISK_SPACE = 6; 73 74 /** The request failed due to invalid ProfilingRequest. */ 75 public static final int ERROR_FAILED_INVALID_REQUEST = 7; 76 77 /** The request was denied or failed for an unspecified reason. */ 78 public static final int ERROR_UNKNOWN = 8; 79 80 /** @hide */ 81 @IntDef(value = { 82 ERROR_NONE, 83 ERROR_FAILED_RATE_LIMIT_SYSTEM, 84 ERROR_FAILED_RATE_LIMIT_PROCESS, 85 ERROR_FAILED_PROFILING_IN_PROGRESS, 86 ERROR_FAILED_EXECUTING, 87 ERROR_FAILED_POST_PROCESSING, 88 ERROR_FAILED_NO_DISK_SPACE, 89 ERROR_UNKNOWN, 90 }) 91 @Retention(RetentionPolicy.SOURCE) 92 @interface ErrorCode {} 93 94 /** @hide */ ProfilingResult(@rrorCode int errorCode, String resultFilePath, String tag, String errorMessage, int triggerType)95 public ProfilingResult(@ErrorCode int errorCode, String resultFilePath, String tag, 96 String errorMessage, int triggerType) { 97 mErrorCode = errorCode; 98 mResultFilePath = resultFilePath; 99 mTag = tag; 100 mErrorMessage = errorMessage; 101 mTriggerType = triggerType; 102 } 103 104 // LINT.IfChange(from_parcel) 105 /** @hide */ ProfilingResult(@onNull Parcel in)106 public ProfilingResult(@NonNull Parcel in) { 107 mErrorCode = in.readInt(); 108 mResultFilePath = in.readString(); 109 mTag = in.readString(); 110 mErrorMessage = in.readString(); 111 mTriggerType = in.readInt(); 112 } 113 // LINT.ThenChange(:to_parcel) 114 115 // LINT.IfChange(to_parcel) 116 @Override writeToParcel(@onNull Parcel dest, int flags)117 public void writeToParcel(@NonNull Parcel dest, int flags) { 118 dest.writeInt(mErrorCode); 119 dest.writeString(mResultFilePath); 120 dest.writeString(mTag); 121 dest.writeString(mErrorMessage); 122 dest.writeInt(mTriggerType); 123 } 124 // LINT.ThenChange(:equals) 125 126 @Override describeContents()127 public int describeContents() { 128 return 0; 129 } 130 131 public @NonNull static final Creator<ProfilingResult> CREATOR = 132 new Creator<ProfilingResult>() { 133 @Override 134 public ProfilingResult createFromParcel(Parcel in) { 135 return new ProfilingResult(in); 136 } 137 138 @Override 139 public ProfilingResult[] newArray(int size) { 140 return new ProfilingResult[size]; 141 } 142 }; 143 144 /** 145 * The result ErrorCode for the profiling request indicating the failure reason if applicable. 146 */ getErrorCode()147 public @ErrorCode int getErrorCode() { 148 return mErrorCode; 149 } 150 151 /** 152 * The file path of the profiling result data. 153 * 154 * Will be null if {@see #getErrorCode} returns code other than {@see #ERROR_NONE}. 155 */ getResultFilePath()156 public @Nullable String getResultFilePath() { 157 return mResultFilePath; 158 } 159 160 /** 161 * The tag defined by the caller at request time. 162 */ getTag()163 public @Nullable String getTag() { 164 return mTag; 165 } 166 167 /** 168 * Additional details about failures that occurred, if applicable. 169 */ getErrorMessage()170 public @Nullable String getErrorMessage() { 171 return mErrorMessage; 172 } 173 174 /** 175 * Trigger type that started this profiling, or {@link ProfilingTrigger#TRIGGER_TYPE_NONE} for 176 * profiling not started by a trigger. 177 */ 178 @FlaggedApi(Flags.FLAG_SYSTEM_TRIGGERED_PROFILING_NEW) getTriggerType()179 public int getTriggerType() { 180 return mTriggerType; 181 } 182 183 // LINT.IfChange(equals) 184 /** @hide */ 185 @Override equals(@ullable Object other)186 public boolean equals(@Nullable Object other) { 187 if (other == null || !(other instanceof ProfilingResult)) { 188 return false; 189 } 190 191 final ProfilingResult o = (ProfilingResult) other; 192 193 if (Flags.systemTriggeredProfilingNew()) { 194 if (mTriggerType != o.getTriggerType()) { 195 return false; 196 } 197 } 198 199 return mErrorCode == o.getErrorCode() 200 && TextUtils.equals(mResultFilePath, o.getResultFilePath()) 201 && TextUtils.equals(mTag, o.getTag()) 202 && TextUtils.equals(mErrorMessage, o.getErrorMessage()); 203 } 204 205 /** @hide */ 206 @Override hashCode()207 public int hashCode() { 208 return Objects.hash(mErrorCode, mResultFilePath, mTag, mErrorMessage, mTriggerType); 209 } 210 // LINT.ThenChange(:params) 211 } 212