1 /* 2 * Copyright 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 androidx.appfunctions.metadata 18 19 import androidx.annotation.RestrictTo 20 import androidx.appsearch.annotation.Document 21 import java.util.Objects 22 23 internal const val APP_FUNCTION_NAMESPACE = "appfunctions" 24 internal const val APP_FUNCTION_ID_EMPTY = "unused" 25 26 /** 27 * Represents an AppFunction's metadata. 28 * 29 * The class provides the essential information to call an AppFunction. The caller has two options 30 * to invoke a function: 31 * * Using function schema to identify input/output: The function schema defines the input and 32 * output of a function. If [schema] is not null, the caller can look up the input/output 33 * information based on the schema definition, and call the function accordingly. 34 * * Examine [parameters] and [response]: A function metadata also has parameters and response 35 * properties describe the input and output of a function. The caller can examine these fields to 36 * obtain the input/output information, and call the function accordingly. 37 */ 38 public class AppFunctionMetadata 39 @JvmOverloads 40 constructor( 41 /** 42 * The ID used in an [androidx.appfunctions.ExecuteAppFunctionRequest] to refer to this 43 * AppFunction. 44 */ 45 public val id: String, 46 /** The package name of the Android app called to execute the app function. */ 47 public val packageName: String, 48 /** Indicates whether the function is enabled currently or not. */ 49 public val isEnabled: Boolean, 50 /** 51 * The predefined schema of the AppFunction. If null, it indicates this function is not 52 * implement a particular predefined schema. 53 */ 54 public val schema: AppFunctionSchemaMetadata?, 55 /** The parameters of the AppFunction. */ 56 public val parameters: List<AppFunctionParameterMetadata>, 57 /** The response of the AppFunction. */ 58 public val response: AppFunctionResponseMetadata, 59 /** Reusable components that could be shared within the function specification. */ 60 public val components: AppFunctionComponentsMetadata = AppFunctionComponentsMetadata(), 61 ) { 62 equalsnull63 override fun equals(other: Any?): Boolean { 64 if (this === other) return true 65 if (javaClass != other?.javaClass) return false 66 67 other as AppFunctionMetadata 68 69 if (id != other.id) return false 70 if (isEnabled != other.isEnabled) return false 71 if (packageName != other.packageName) return false 72 if (schema != other.schema) return false 73 if (parameters != other.parameters) return false 74 if (response != other.response) return false 75 if (components != other.components) return false 76 77 return true 78 } 79 hashCodenull80 override fun hashCode(): Int { 81 return Objects.hash(isEnabled, id, packageName, schema, parameters, response, components) 82 } 83 <lambda>null84 override fun toString(): String = buildString { 85 append("AppFunctionMetadata(") 86 append("id='$id', ") 87 append("packageName='$packageName', ") 88 append("isEnabled=$isEnabled, ") 89 append("schema=$schema, ") 90 append("parameters=$parameters, ") 91 append("response=$response, ") 92 append("components=$components") 93 append(")") 94 } 95 } 96 97 /** 98 * Represents the computed compile-time metadata of an AppFunction. 99 * 100 * This class is used to generate AppFunctionInventory and an intermediate representation to persist 101 * the metadata in AppSearch. 102 */ 103 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 104 public data class CompileTimeAppFunctionMetadata( 105 /** 106 * The ID used in an [androidx.appfunctions.ExecuteAppFunctionRequest] to refer to this 107 * AppFunction. 108 */ 109 public val id: String, 110 /** 111 * Indicates whether the function is enabled by default. 112 * 113 * This represents the initial configuration and might not represent the current enabled state, 114 * as it could be modified at runtime. 115 */ 116 public val isEnabledByDefault: Boolean, 117 /** 118 * The predefined schema of the AppFunction. If null, it indicates this function is not 119 * implement a particular predefined schema. 120 */ 121 public val schema: AppFunctionSchemaMetadata?, 122 /** The parameters of the AppFunction. */ 123 public val parameters: List<AppFunctionParameterMetadata>, 124 /** The response of the AppFunction. */ 125 public val response: AppFunctionResponseMetadata, 126 /** Reusable components that could be shared within the function specification. */ 127 public val components: AppFunctionComponentsMetadata = AppFunctionComponentsMetadata(), 128 ) { 129 130 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) copynull131 public fun copy( 132 id: String? = null, 133 isEnabledByDefault: Boolean? = null, 134 schema: AppFunctionSchemaMetadata? = null, 135 parameters: List<AppFunctionParameterMetadata>? = null, 136 response: AppFunctionResponseMetadata? = null, 137 components: AppFunctionComponentsMetadata? = null 138 ): CompileTimeAppFunctionMetadata { 139 return CompileTimeAppFunctionMetadata( 140 id = id ?: this.id, 141 isEnabledByDefault = isEnabledByDefault ?: this.isEnabledByDefault, 142 schema = schema ?: this.schema, 143 parameters = parameters ?: this.parameters, 144 response = response ?: this.response, 145 components = components ?: this.components 146 ) 147 } 148 149 /** 150 * Converts the [CompileTimeAppFunctionMetadata] to an [AppFunctionMetadataDocument]. 151 * 152 * This method is used to persist the [CompileTimeAppFunctionMetadata] in a database. 153 */ 154 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) toAppFunctionMetadataDocumentnull155 public fun toAppFunctionMetadataDocument(): AppFunctionMetadataDocument { 156 return AppFunctionMetadataDocument( 157 id = id, 158 isEnabledByDefault = isEnabledByDefault, 159 schemaName = schema?.name, 160 schemaCategory = schema?.category, 161 schemaVersion = schema?.version, 162 parameters = parameters.map { it.toAppFunctionParameterMetadataDocument() }, 163 response = response.toAppFunctionResponseMetadataDocument(), 164 components = components.toAppFunctionComponentsMetadataDocument() 165 ) 166 } 167 } 168 169 /** Represents the persistent storage format of [AppFunctionMetadata]. */ 170 @Document(name = "AppFunctionStaticMetadata") 171 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 172 public data class AppFunctionMetadataDocument( 173 @Document.Namespace public val namespace: String = APP_FUNCTION_NAMESPACE, 174 /** The id of the AppFunction. */ 175 @Document.Id public val id: String = APP_FUNCTION_ID_EMPTY, 176 /** 177 * Indicates whether the function is enabled by default. 178 * 179 * This represents the initial configuration and might not represent the current enabled state, 180 * as it could be modified at runtime. 181 */ 182 @Document.BooleanProperty(name = "enabledByDefault") public val isEnabledByDefault: Boolean, 183 /** The category of the schema, used to group related schemas. */ 184 @Document.StringProperty public val schemaCategory: String?, 185 /** The unique name of the schema within its category. */ 186 @Document.StringProperty public val schemaName: String?, 187 /** The version of the schema. This is used to track the changes to the schema over time. */ 188 @Document.LongProperty public val schemaVersion: Long?, 189 // Below properties are nullable as they won't be populated in the underlying GD created by 190 // legacy AppSearch indexer. 191 /** The parameters of the AppFunction. */ 192 @Document.DocumentProperty public val parameters: List<AppFunctionParameterMetadataDocument>?, 193 /** The response of the AppFunction. */ 194 @Document.DocumentProperty public val response: AppFunctionResponseMetadataDocument?, 195 /** The reusable components for the AppFunction. */ 196 @Document.DocumentProperty public val components: AppFunctionComponentsMetadataDocument?, 197 ) 198