1 /* 2 * Copyright 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 androidx.tracing.perfetto.internal.handshake.protocol 18 19 import androidx.annotation.IntDef 20 import androidx.annotation.RestrictTo 21 import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP 22 23 // Keep these two packages in sync: 24 // - `androidx.tracing.perfetto.handshake.protocol` in the tracing/tracing-perfetto-handshake folder 25 // - `androidx.tracing.perfetto.internal.handshake.protocol` in the tracing/tracing-perfetto folder 26 // 27 // This is a part of a WIP refactor to decouple tracing-perfetto and tracing-perfetto-handshake 28 // tracked under TODO(243405142) 29 30 @RestrictTo(LIBRARY_GROUP) 31 internal object RequestKeys { 32 public const val RECEIVER_CLASS_NAME: String = "androidx.tracing.perfetto.TracingReceiver" 33 34 /** 35 * Request to enable tracing in an app. 36 * 37 * The action is performed straight away allowing for warm / hot tracing. For cold start tracing 38 * see [ACTION_ENABLE_TRACING_COLD_START] 39 * 40 * Request can include [KEY_PATH] as an optional extra. 41 * 42 * Response to the request is a JSON string (to allow for CLI support) with the following: 43 * - [ResponseKeys.KEY_RESULT_CODE] (always) 44 * - [ResponseKeys.KEY_REQUIRED_VERSION] (always) 45 * - [ResponseKeys.KEY_MESSAGE] (optional) 46 */ 47 public const val ACTION_ENABLE_TRACING: String = 48 "androidx.tracing.perfetto.action.ENABLE_TRACING" 49 50 /** 51 * Request to enable cold start tracing in an app. 52 * 53 * For warm / hot tracing, see [ACTION_ENABLE_TRACING]. 54 * 55 * The action must be performed in the following order, otherwise its effects are unspecified: 56 * - the app process must be killed before performing the action 57 * - the action must then follow 58 * - the app process must be killed after performing the action 59 * 60 * Request can include [KEY_PATH] as an optional extra. Request can include [KEY_PERSISTENT] as 61 * an optional extra. 62 * 63 * Response to the request is a JSON string (to allow for CLI support) with the following: 64 * - [ResponseKeys.KEY_RESULT_CODE] (always) 65 * - [ResponseKeys.KEY_REQUIRED_VERSION] (always) 66 * - [ResponseKeys.KEY_MESSAGE] (optional) 67 */ 68 public const val ACTION_ENABLE_TRACING_COLD_START: String = 69 "androidx.tracing.perfetto.action.ENABLE_TRACING_COLD_START" 70 71 /** 72 * Request to disable cold start tracing (previously enabled with 73 * [ACTION_ENABLE_TRACING_COLD_START]). 74 * 75 * The action is particularly useful when cold start tracing was enabled in [KEY_PERSISTENT] 76 * mode. 77 * 78 * The action must be performed in the following order, otherwise its effects are unspecified: 79 * - the app process must be killed before performing the action 80 * - the action must then follow 81 * - the app process must be killed after performing the action 82 * 83 * Request can include [KEY_PATH] as an optional extra. Request can include [KEY_PERSISTENT] as 84 * an optional extra. 85 * 86 * Response to the request is a JSON string (to allow for CLI support) with the following: 87 * - [ResponseKeys.KEY_RESULT_CODE] (always) 88 */ 89 public const val ACTION_DISABLE_TRACING_COLD_START: String = 90 "androidx.tracing.perfetto.action.DISABLE_TRACING_COLD_START" 91 92 /** Path to tracing native binary file */ 93 public const val KEY_PATH: String = "path" 94 95 /** 96 * Boolean flag to signify whether the operation should be persistent between runs (or only 97 * performed once). 98 * 99 * Applies to [ACTION_ENABLE_TRACING_COLD_START] 100 */ 101 public const val KEY_PERSISTENT: String = "persistent" 102 } 103 104 @RestrictTo(LIBRARY_GROUP) 105 internal object ResponseKeys { 106 /** 107 * Result code as listed in [ResponseResultCodes]. 108 * 109 * Note: the value of the string ("exitCode") is kept unchanged to maintain backwards 110 * compatibility. 111 */ 112 public const val KEY_RESULT_CODE: String = "exitCode" 113 114 /** 115 * Required version of the binaries. Java and binary library versions have to match to ensure 116 * compatibility. In the Maven format, e.g. 1.2.3-beta01. 117 */ 118 public const val KEY_REQUIRED_VERSION: String = "requiredVersion" 119 120 /** 121 * Message string that gives more information about the response, e.g. recovery steps if 122 * applicable. 123 */ 124 public const val KEY_MESSAGE: String = "message" 125 } 126 127 internal object ResponseResultCodes { 128 /** 129 * Indicates that the broadcast resulted in `result=0`, which is an equivalent of 130 * [android.app.Activity.RESULT_CANCELED]. 131 * 132 * This most likely means that the app does not expose a [PerfettoSdkHandshake] compatible 133 * receiver. 134 */ 135 @Suppress("KDocUnresolvedReference") public const val RESULT_CODE_CANCELLED: Int = 0 136 137 public const val RESULT_CODE_SUCCESS: Int = 1 138 public const val RESULT_CODE_ALREADY_ENABLED: Int = 2 139 140 /** 141 * Required version described in [Response.requiredVersion]. A follow-up 142 * [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.enableTracingImmediate] request 143 * expected with binaries to sideload specified. 144 */ 145 public const val RESULT_CODE_ERROR_BINARY_MISSING: Int = 11 146 147 /** Required version described in [Response.requiredVersion]. */ 148 public const val RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH: Int = 12 149 150 /** 151 * Could be a result of a stale version of the binary cached locally. Retrying with a freshly 152 * downloaded library likely to fix the issue. More specific information in [Response.message] 153 */ 154 public const val RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR: Int = 13 155 156 /** More specific information in [Response.message] */ 157 public const val RESULT_CODE_ERROR_OTHER: Int = 99 158 } 159 160 @Retention(AnnotationRetention.SOURCE) 161 @IntDef( 162 ResponseResultCodes.RESULT_CODE_CANCELLED, 163 ResponseResultCodes.RESULT_CODE_SUCCESS, 164 ResponseResultCodes.RESULT_CODE_ALREADY_ENABLED, 165 ResponseResultCodes.RESULT_CODE_ERROR_BINARY_MISSING, 166 ResponseResultCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH, 167 ResponseResultCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR, 168 ResponseResultCodes.RESULT_CODE_ERROR_OTHER 169 ) 170 private annotation class ResultCode 171 172 internal class Response 173 @RestrictTo(LIBRARY_GROUP) 174 constructor( 175 @ResultCode public val resultCode: Int, 176 177 /** 178 * This can be `null` iff we cannot communicate with the broadcast receiver of the target 179 * process (e.g. app does not offer Perfetto tracing) or if we cannot parse the response from 180 * the receiver. In either case, tracing is unlikely to work under these circumstances, and more 181 * context on how to proceed can be found in [resultCode] or [message] properties. 182 */ 183 public val requiredVersion: String?, 184 public val message: String? 185 ) 186