Protocol.kt
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.tracing.perfetto.internal.handshake.protocol
import androidx.annotation.IntDef
import androidx.annotation.RestrictTo
import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
// Keep these two packages in sync:
// - `androidx.tracing.perfetto.handshake.protocol` in the tracing/tracing-perfetto-common folder
// - `androidx.tracing.perfetto.internal.handshake.protocol` in the tracing/tracing-perfetto folder
//
// This is a part of a WIP refactor to decouple tracing-perfetto and tracing-perfetto-common and to
// rename tracing-perfetto-common to tracing-perfetto-handshake tracked under TODO(243405142)
@RestrictTo(LIBRARY_GROUP)
internal object RequestKeys {
public const val RECEIVER_CLASS_NAME: String = "androidx.tracing.perfetto.TracingReceiver"
/**
* Request to enable tracing in an app.
*
* The action is performed straight away allowing for warm / hot tracing. For cold start
* tracing see [ACTION_ENABLE_TRACING_COLD_START]
*
* Request can include [KEY_PATH] as an optional extra.
*
* Response to the request is a JSON string (to allow for CLI support) with the following:
* - [ResponseKeys.KEY_EXIT_CODE] (always)
* - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
* - [ResponseKeys.KEY_MESSAGE] (optional)
*/
public const val ACTION_ENABLE_TRACING: String =
"androidx.tracing.perfetto.action.ENABLE_TRACING"
/**
* Request to enable cold start tracing in an app.
*
* For warm / hot tracing, see [ACTION_ENABLE_TRACING].
*
* The action must be performed in the following order, otherwise its effects are
* unspecified:
* - the app process must be killed before performing the action
* - the action must then follow
* - the app process must be killed after performing the action
*
* Request can include [KEY_PATH] as an optional extra.
* Request can include [KEY_PERSISTENT] as an optional extra.
*
* Response to the request is a JSON string (to allow for CLI support) with the following:
* - [ResponseKeys.KEY_EXIT_CODE] (always)
* - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
* - [ResponseKeys.KEY_MESSAGE] (optional)
*/
public const val ACTION_ENABLE_TRACING_COLD_START: String =
"androidx.tracing.perfetto.action.ENABLE_TRACING_COLD_START"
/**
* Request to disable cold start tracing (previously enabled with
* [ACTION_ENABLE_TRACING_COLD_START]).
*
* The action is particularly useful when cold start tracing was enabled in
* [KEY_PERSISTENT] mode.
*
* The action must be performed in the following order, otherwise its effects are
* unspecified:
* - the app process must be killed before performing the action
* - the action must then follow
* - the app process must be killed after performing the action
*
* Request can include [KEY_PATH] as an optional extra.
* Request can include [KEY_PERSISTENT] as an optional extra.
*
* Response to the request is a JSON string (to allow for CLI support) with the following:
* - [ResponseKeys.KEY_EXIT_CODE] (always)
*/
public const val ACTION_DISABLE_TRACING_COLD_START: String =
"androidx.tracing.perfetto.action.DISABLE_TRACING_COLD_START"
/** Path to tracing native binary file */
public const val KEY_PATH: String = "path"
/**
* Boolean flag to signify whether the operation should be persistent between runs
* (or only performed once).
*
* Applies to [ACTION_ENABLE_TRACING_COLD_START]
*/
public const val KEY_PERSISTENT: String = "persistent"
}
@RestrictTo(LIBRARY_GROUP)
internal object ResponseKeys {
/** Exit code as listed in [ResponseExitCodes]. */
public const val KEY_EXIT_CODE: String = "exitCode"
/**
* Required version of the binaries. Java and binary library versions have to match to
* ensure compatibility. In the Maven format, e.g. 1.2.3-beta01.
*/
public const val KEY_REQUIRED_VERSION: String = "requiredVersion"
/**
* Message string that gives more information about the response, e.g. recovery steps
* if applicable.
*/
public const val KEY_MESSAGE: String = "message"
}
internal object ResponseExitCodes {
/**
* Indicates that the broadcast resulted in `result=0`, which is an equivalent
* of [android.app.Activity.RESULT_CANCELED].
*
* This most likely means that the app does not expose a [PerfettoSdkHandshake] compatible
* receiver.
*/
@Suppress("KDocUnresolvedReference")
public const val RESULT_CODE_CANCELLED: Int = 0
public const val RESULT_CODE_SUCCESS: Int = 1
public const val RESULT_CODE_ALREADY_ENABLED: Int = 2
/**
* Required version described in [EnableTracingResponse.requiredVersion].
* A follow-up [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.enableTracingImmediate]
* request expected with binaries to sideload specified.
*/
public const val RESULT_CODE_ERROR_BINARY_MISSING: Int = 11
/** Required version described in [EnableTracingResponse.requiredVersion]. */
public const val RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH: Int = 12
/**
* Could be a result of a stale version of the binary cached locally.
* Retrying with a freshly downloaded library likely to fix the issue.
* More specific information in [EnableTracingResponse.message]
*/
public const val RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR: Int = 13
/** More specific information in [EnableTracingResponse.message] */
public const val RESULT_CODE_ERROR_OTHER: Int = 99
}
@Retention(AnnotationRetention.SOURCE)
@IntDef(
ResponseExitCodes.RESULT_CODE_CANCELLED,
ResponseExitCodes.RESULT_CODE_SUCCESS,
ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED,
ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING,
ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH,
ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR,
ResponseExitCodes.RESULT_CODE_ERROR_OTHER
)
private annotation class EnableTracingResultCode
internal class EnableTracingResponse @RestrictTo(LIBRARY_GROUP) constructor(
@EnableTracingResultCode public val exitCode: Int,
/**
* This can be `null` iff we cannot communicate with the broadcast receiver of the target
* process (e.g. app does not offer Perfetto tracing) or if we cannot parse the response
* from the receiver. In either case, tracing is unlikely to work under these circumstances,
* and more context on how to proceed can be found in [exitCode] or [message] properties.
*/
public val requiredVersion: String?,
public val message: String?
)