diff --git a/ai/neural_network_runtime/BUILD.gn b/ai/neural_network_runtime/BUILD.gn new file mode 100644 index 000000000..db9a140e4 --- /dev/null +++ b/ai/neural_network_runtime/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libneural_network_runtime_ndk") { + output_name = "neural_network_runtime.z" + output_extension = "so" + ndk_description_file = "libneural_network_runtime.ndk.json" + min_compact_version = "9" + system_capability = "SystemCapability.AI.NeuralNetworkRuntime" + system_capability_headers = [ + "neural_network_runtime.h", + "neural_network_runtime_type.h", + ] +} + +ohos_ndk_headers("libneural_network_runtime_header") { + dest_dir = "$ndk_headers_out_dir/neural_network_runtime" + sources = [ + "neural_network_runtime.h", + "neural_network_runtime_type.h", + ] +} \ No newline at end of file diff --git a/ai/neural_network_runtime/libneural_network_runtime.ndk.json b/ai/neural_network_runtime/libneural_network_runtime.ndk.json new file mode 100644 index 000000000..0d58444cb --- /dev/null +++ b/ai/neural_network_runtime/libneural_network_runtime.ndk.json @@ -0,0 +1,95 @@ +[ + { + "name": "OH_NNModel_Construct" + }, + { + "name": "OH_NNModel_AddTensor" + }, + { + "name": "OH_NNModel_SetTensorData" + }, + { + "name": "OH_NNModel_AddOperation" + }, + { + "name": "OH_NNModel_SpecifyInputsAndOutputs" + }, + { + "name": "OH_NNModel_Finish" + }, + { + "name": "OH_NNModel_Destroy" + }, + { + "name": "OH_NNModel_GetAvailableOperations" + }, + { + "name": "OH_NNCompilation_Construct" + }, + { + "name": "OH_NNCompilation_SetDevice" + }, + { + "name": "OH_NNCompilation_SetCache" + }, + { + "name": "OH_NNCompilation_SetPerformanceMode" + }, + { + "name": "OH_NNCompilation_SetPriority" + }, + { + "name": "OH_NNCompilation_EnableFloat16" + }, + { + "name": "OH_NNCompilation_Build" + }, + { + "name": "OH_NNCompilation_Destroy" + }, + { + "name": "OH_NNExecutor_Construct" + }, + { + "name": "OH_NNExecutor_SetInput" + }, + { + "name": "OH_NNExecutor_SetOutput" + }, + { + "name": "OH_NNExecutor_GetOutputShape" + }, + { + "name": "OH_NNExecutor_Run" + }, + { + "name": "OH_NNExecutor_AllocateInputMemory" + }, + { + "name": "OH_NNExecutor_AllocateOutputMemory" + }, + { + "name": "OH_NNExecutor_DestroyInputMemory" + }, + { + "name": "OH_NNExecutor_DestroyOutputMemory" + }, + { + "name": "OH_NNExecutor_SetInputWithMemory" + }, + { + "name": "OH_NNExecutor_SetOutputWithMemory" + }, + { + "name": "OH_NNExecutor_Destroy" + }, + { + "name": "OH_NNDevice_GetAllDevicesID" + }, + { + "name": "OH_NNDevice_GetName" + }, + { + "name": "OH_NNDevice_GetType" + } +] \ No newline at end of file diff --git a/ai/neural_network_runtime/neural_network_runtime.h b/ai/neural_network_runtime/neural_network_runtime.h new file mode 100644 index 000000000..b5cc5e2fb --- /dev/null +++ b/ai/neural_network_runtime/neural_network_runtime.h @@ -0,0 +1,690 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup NeuralNeworkRuntime + * @{ + * + * @brief Provides APIs of Neural Network Runtime for accelerating the model inference. + * + * @Syscap SystemCapability.Ai.NeuralNetworkRuntime + * @since 9 + * @version 1.0 + */ + +/** + * @file neural_network_runtime.h + * + * @brief Defines the Neural Network Runtime APIs. The AI inference framework uses the Native APIs provided by Neural Network Runtime + * to construct and compile models and perform inference and computing on acceleration hardware. + * Note: Currently, the APIs of Neural Network Runtime do not support multi-thread calling. \n + * + * @since 9 + * @version 1.0 + */ + +#ifndef NEURAL_NETWORK_RUNTIME_H +#define NEURAL_NETWORK_RUNTIME_H + +#include "neural_network_runtime_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates a model instance of the {@link OH_NNModel} type and uses other APIs provided by OH_NNModel to construct the model instance. + * + * Before composition, call {@link OH_NNModel_Construct} to create a model instance. Based on the model topology, + * call the {@link OH_NNModel_AddTensor}, {@link OH_NNModel_AddOperation}, and {@link OH_NNModel_SetTensorData} methods + * to fill in the data and operator nodes of the model, and then call {@link OH_NNModel_SpecifyInputsAndOutputs} to specify the inputs and outputs of the model. + * After the model topology is constructed, call {@link OH_NNModel_Finish} to build the model. \n + * + * After a model instance is used, you need to destroy it by calling {@link OH_NNModel_Destroy} to avoid memory leak. \n + * + * @return Returns the pointer to a {@link OH_NNModel} instance. + * @since 9 + * @version 1.0 + */ +OH_NNModel *OH_NNModel_Construct(void); + +/** + * @brief Adds a tensor to a model instance. + * + * The data node and operator parameters in the Neural Network Runtime model are composed of tensors of the model. + * This method is used to add tensors to a model instance based on the tensor parameter. + * The sequence of adding tensors is specified by the index value recorded in the model. The {@link OH_NNModel_SetTensorData}, {@link OH_NNModel_AddOperation}, + * and {@link OH_NNModel_SpecifyInputsAndOutputs} methods specifies tensors based on the index value. \n + * + * Neural Network Runtime supports inputs and outputs of the dynamic shape. When adding a data node with a dynamic shape, + * you need to set the dimensions that support dynamic changes in tensor.dimensions to -1. + * For example, if tensor.dimensions of a four-dimensional tensor is set to [1, -1, 2, 2], the second dimension supports dynamic changes. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @param tensor Pointer to the {@link OH_NN_Tensor} tensor. The tensor specifies the attributes of the tensor added to the model instance. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNModel_AddTensor(OH_NNModel *model, const OH_NN_Tensor *tensor); + +/** + * @brief Sets the tensor value. + * + * For tensors with constant values (such as model weights), you need to use this method in the composition phase. + * The index value of a tensor is determined by the sequence in which the tensor is added to the model. + * For details about how to add a tensor, see {@link OH_NNModel_AddTensor}. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @param index Index value of a tensor. + * @param dataBuffer Pointer to real data. + * @param length Length of the data buffer. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNModel_SetTensorData(OH_NNModel *model, uint32_t index, const void *dataBuffer, size_t length); + +/** + * @brief Adds an operator to a model instance. + * + * This method is used to add an operator to a model instance. The operator type is specified by op, and + * the operator parameters, inputs, and outputs are specified by paramIndices, inputIndices, and outputIndices respectively. + * This method verifies the attributes of operator parameters and the number of input and output parameters. + * These attributes must be correctly set when {@link OH_NNModel_AddTensor} is called to add tensors. + * For details about the expected parameters, input attributes, and output attributes of each operator, see {@link OH_NN_OperationType}. \n + * + * paramIndices, inputIndices, and outputIndices store index values of tensors. + * Index values are determined by the sequence in which tensors are added to the model. + * For details about how to add a tensor, see {@link OH_NNModel_AddTensor}. \n + * + * If unnecessary parameters are added for adding an operator, this method returns {@link OH_NN_INVALID_PARAMETER}. + * If no operator parameter is set, the operator uses the default parameter value. + * For details about the default values, see {@link OH_NN_OperationType}. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @param op Specifies the type of an operator to be added. For details, see the enumerated values of {@link OH_NN_OperationType}. + * @param paramIndices Pointer to the OH_NN_UInt32Array instance, which is used to set operator parameters. + * @param inputIndices Pointer to the OH_NN_UInt32Array instance, which is used to set the operator input. + * @param outputIndices Pointer to the OH_NN_UInt32Array instance, which is used to set the operator output. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNModel_AddOperation(OH_NNModel *model, + OH_NN_OperationType op, + const OH_NN_UInt32Array *paramIndices, + const OH_NN_UInt32Array *inputIndices, + const OH_NN_UInt32Array *outputIndices); + +/** + * @brief Specifies the inputs and outputs of a model. + * + * A tensor must be specified as the end-to-end inputs and outputs of a model instance. This type of tensor cannot be set + * using {@link OH_NNModel_SetTensorData}. The OH_NNExecutor method needs to be called in the execution phase to set the input and output data. \n + * + * The index value of a tensor is determined by the sequence in which the tensor is added to the model. + * For details about how to add a tensor, see {@link OH_NNModel_AddTensor}. \n + * + * Currently, the model inputs and outputs cannot be set asynchronously. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @param inputIndices Pointer to the OH_NN_UInt32Array instance, which is used to set the operator input. + * @param outputIndices Pointer to the OH_NN_UInt32Array instance, which is used to set the operator output. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNModel_SpecifyInputsAndOutputs(OH_NNModel *model, + const OH_NN_UInt32Array *inputIndices, + const OH_NN_UInt32Array *outputIndices); + +/** + * @brief Completes model composition. + * + * After the model topology is set up, call this method to indicate that the composition is complete. After this method is called, + * additional composition operations cannot be performed. If {@link OH_NNModel_AddTensor}, {@link OH_NNModel_AddOperation}, + * {@link OH_NNModel_SetTensorData}, and {@link OH_NNModel_SpecifyInputsAndOutputs} are called, + * {@link OH_NN_OPERATION_FORBIDDEN} is returned. \n + * + * Before calling {@link OH_NNModel_GetAvailableOperations} and {@link OH_NNCompilation_Construct}, + * you must call this method to complete composition. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNModel_Finish(OH_NNModel *model); + +/** + * @brief Releases a model instance. + * + * This method needs to be called to release the model instance created by calling {@link OH_NNModel_Construct}. Otherwise, memory leak will occur. \n + * + * If model or *model is a null pointer, this method only prints warning logs and does not execute the release logic. \n + * + * @param model Level-2 pointer to the {@link OH_NNModel} instance. After a model instance is destroyed, this method sets *model to a null pointer. + * @since 9 + * @version 1.0 + */ +void OH_NNModel_Destroy(OH_NNModel **model); + +/** + * @brief Queries whether the device supports operators in the model. The support status is indicated by the Boolean value. + * + * Queries whether underlying device supports operators in a model instance. The device is specified by deviceID, + * and the result is represented by the array pointed by isSupported. If the ith operator is supported, + * the value of (*isSupported)[i] is true. Otherwise, the value is false. \n + * + * After this method is successfully executed, (*isSupported) points to the bool array that records the operator support status. + * The operator quantity for the array length is the same as that for the model instance. The memory corresponding to this array is + * managed by Neural Network Runtime and is automatically destroyed after the model instance is destroyed or this method is called again. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @param deviceID Device ID to be queried, which can be obtained by using {@link OH_NNDevice_GetAllDevicesID}. + * @param isSupported Pointer to the bool array. When this method is called, (*isSupported) must be a null pointer. + * Otherwise, {@link OH_NN_INVALID_PARAMETER} is returned. + * + * @param opCount Number of operators in a model instance, corresponding to the length of the (*isSupported) array. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNModel_GetAvailableOperations(OH_NNModel *model, + size_t deviceID, + const bool **isSupported, + uint32_t *opCount); + + +/** + * @brief Creates a compilation instance of the {@link OH_NNCompilation} type. + * + * After the OH_NNModel module completes model construction, APIs provided by the OH_NNCompilation module pass the model + * to underlying device for compilation. This method creates a {@link OH_NNCompilation} instance + * based on the passed {@link OH_NNModel} instance. The {@link OH_NNCompilation_SetDevice} method is called + * to set the device to compile on, and {@link OH_NNCompilation_Build} is then called to complete compilation.\n + * + * In addition to computing device selection, the OH_NNCompilation module supports features such as model caching, performance preference, + * priority setting, and float16 computing, which can be implemented by the following methods: + * - {@link OH_NNCompilation_SetCache} + * - {@link OH_NNCompilation_SetPerformanceMode} + * - {@link OH_NNCompilation_SetPriority} + * - {@link OH_NNCompilation_EnableFloat16} \n + * + * After {@link OH_NNCompilation} is created by calling this method, the {@link OH_NNModel} instance can be released. \n + * + * @param model Pointer to the {@link OH_NNModel} instance. + * @return Returns the pointer to a {@link OH_NNCompilation} instance. + * @since 9 + * @version 1.0 + */ +OH_NNCompilation *OH_NNCompilation_Construct(const OH_NNModel *model); + +/** + * @brief Specifies the device for model compilation and computing. + * + * In the compilation phase, you need to specify the device for model compilation and computing. Call {@link OH_NNDevice_GetAllDevicesID} + * to obtain available device IDs. Call {@link OH_NNDevice_GetType} and {@link OH_NNDevice_GetName} to obtain device information + * and pass target device IDs to this method for setting. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @param deviceID Device ID. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNCompilation_SetDevice(OH_NNCompilation *compilation, size_t deviceID); + +/** + * @brief Set the cache directory and version of the compiled model. + * + * On the device that supports caching, a model can be saved as a cache file after being compiled at the device driver layer. + * The model can be directly read from the cache file in the next compilation, saving recompilation time. + * This method performs different operations based on the passed cache directory and version:\n + * + * - No file exists in the cache directory: + * Caches the compiled model to the directory and sets the cache version to version. \n + * + * - A complete cache file exists in the cache directory, and its version is version: + * Reads the cache file in the path and passes the data to the underlying device for conversion into executable model instances. \n + * + * - A complete cache file exists in the cache directory, and its version is earlier than version: + * When model compilation is complete on the underlying device, overwrites the cache file and changes the version number to version. \n + * + * - A complete cache file exists in the cache directory, and its version is later than version: + * Returns the {@link OH_NN_INVALID_PARAMETER} error code without reading the cache file. \n + * + * - The cache file in the cache directory is incomplete or you do not have the permission to access the cache file. + * Returns the {@link OH_NN_INVALID_FILE} error code. \n + * + * - The cache directory does not exist or you do not have the access permission. + * Returns the {@link OH_NN_INVALID_PATH} error code. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @param cachePath Directory for storing model cache files. This method creates directories for different devices in the cachePath directory. + * You are advised to use a separate cache directory for each model. + * @param version Cache version. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNCompilation_SetCache(OH_NNCompilation *compilation, const char *cachePath, uint32_t version); + +/** + * @brief Sets the performance mode for model computing. + * + * Neural Network Runtime allows you to set the performance mode for model computing to meet the requirements of low power consumption + * and ultimate performance. If this method is not called to set the performance mode in the compilation phase, the compilation instance assigns + * the {@link OH_NN_PERFORMANCE_NONE} mode for the model by default. In this case, the device performs computing in the default performance mode. \n + * + * If this method is called on the device that does not support the setting of the performance mode, the {@link OH_NN_UNAVALIDABLE_DEVICE} error code is returned. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @param performanceMode Performance mode. For details about the available performance modes, see {@link OH_NN_PerformanceMode}. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNCompilation_SetPerformanceMode(OH_NNCompilation *compilation, + OH_NN_PerformanceMode performanceMode); + +/** + * @brief Sets the model computing priority. + * + * Neural Network Runtime allows you to set computing priorities for models. + * The priorities apply only to models created by the process with the same UID. + * The settings will not affect models created by processes with different UIDs on different devices. \n + * + * If this method is called on the device that does not support the priority setting, the {@link OH_NN_UNAVALIDABLE_DEVICE} error code is returned. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @param priority Priority. For details about the optional priorities, see {@link OH_NN_Priority}. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNCompilation_SetPriority(OH_NNCompilation *compilation, OH_NN_Priority priority); + +/** + * @brief Enables float16 for computing. + * + * Currently, Neural Network Runtime supports only float32 and int8. If this method is called on a device that supports float16, + * float16 will be used for computing the float32 model to reduce memory usage and execution time. \n + * + * If this method is called on the device that does not support float16, the {@link OH_NN_UNAVALIDABLE_DEVICE} error code is returned. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @param enableFloat16 Indicates whether to enable float16. If this parameter is set to true, float16 inference is performed. + * If this parameter is set to false, float32 inference is performed. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, an error code is returned. + * For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNCompilation_EnableFloat16(OH_NNCompilation *compilation, bool enableFloat16); + +/** + * @brief Compiles a model. + * + * After the compilation configuration is complete, call this method to return the compilation result. The compilation instance pushes the model and + * compilation options to the device for compilation. After this method is called, additional compilation operations cannot be performed. + * If the {@link OH_NNCompilation_SetDevice}, {@link OH_NNCompilation_SetCache}, {@link OH_NNCompilation_SetPerformanceMode}, + * {@link OH_NNCompilation_SetPriority}, and {@link OH_NNCompilation_EnableFloat16} methods are called, {@link OH_NN_OPERATION_FORBIDDEN} is returned. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNCompilation_Build(OH_NNCompilation *compilation); + +/** + * @brief Releases the Compilation object. + * + * This method needs to be called to release the compilation instance created by calling {@link OH_NNCompilation_Construct}. Otherwise, memory leak will occur. \n + * + * If compilation or *compilation is a null pointer, this method only prints warning logs and does not execute the release logic. \n + * + * @param compilation Level-2 pointer to the {@link OH_NNCompilation} instance. After a compilation instance is destroyed, + * this method sets *compilation to a null pointer. + * @since 9 + * @version 1.0 + */ +void OH_NNCompilation_Destroy(OH_NNCompilation **compilation); + + +/** + * @brief Creates an executor instance of the {@link OH_NNExecutor} type. + * + * This method constructs a model inference executor associated with the device based on the passed compiler. Use {@link OH_NNExecutor_SetInput} + * to set the model input data. After the input data is set, call {@link OH_NNExecutor_Run} to perform inference and then call + * {@link OH_NNExecutor_SetOutput} to obtain the computing result. \n + * + * After calling this method to create the {@link OH_NNExecutor} instance, you can release the {@link OH_NNCompilation} + * instance if you do not need to create any other executors. \n + * + * @param compilation Pointer to the {@link OH_NNCompilation} instance. + * @return Pointer to a {@link OH_NNExecutor} instance. + * @since 9 + * @version 1.0 + */ +OH_NNExecutor *OH_NNExecutor_Construct(OH_NNCompilation *compilation); + +/** + * @brief Sets the single input data for a model. + * + * This method copies the data whose length is specified by length (in bytes) in dataBuffer to the shared memory + * of the underlying device. inputIndex specifies the input to be set and tensor sets information such as the input shape, + * type, and quantization parameters. \n + * + * Neural Network Runtime supports models with dynamical shape input. For fixed shape input and dynamic shape input scenarios, + * this method uses different processing policies. + * + * - Fixed shape input: The attributes of tensor must be the same as those of the tensor added by calling + * {@link OH_NNModel_AddTensor} in the composition phase. + * - Dynamic shape input: In the composition phase, because the shape is not fixed, each value in tensor.dimensions must be greater than + * 0 in the method calls to determine the shape input in the calculation phase. When setting the shape, you can modify + * only the dimension whose value is -1. Assume that [-1, 224, 224, 3] is input as the the dimension of A in the composition phase. + * When this method is called, only the size of the first dimension can be modified, for example, to [3, 224, 224, 3]. + * If other dimensions are adjusted, {@link OH_NN_INVALID_PARAMETER} is returned. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param inputIndex Input index value, which is in the same sequence of the data input when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of inputIndices is {1, 5, 9} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * In input settings, the index value for the three inputs is {0, 1, 2}. \n + * + * @param tensor Sets the tensor corresponding to the input data. + * @param dataBuffer Pointer to the input data. + * @param length Length of the data buffer, in bytes. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNExecutor_SetInput(OH_NNExecutor *executor, + uint32_t inputIndex, + const OH_NN_Tensor *tensor, + const void *dataBuffer, + size_t length); + +/** + * @brief Sets the buffer for a single output of a model. + * + * This method binds the buffer to which dataBuffer points to the output specified by outputIndex. + * The length of the buffer is specified by length. \n + * + * After {@link OH_NNExecutor_Run} is called to complete a single model inference, Neural Network Runtime compares + * the length of the buffer to which dataBuffer points with the length of the output data and returns different results + * based on the actual situation. \n + * + * - If the buffer length is greater than or equal to the data length, the inference result is copied to the buffer and + * {@link OH_NN_SUCCESS} is returned. You can read the inference result from dataBuffer. + * - If the buffer length is smaller than the data length, {@link OH_NNExecutor_Run} returns {@link OH_NN_INVALID_PARAMETER} + * and generates a log indicating that the buffer is too small. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param outputIndex Output Index value, which is in the same sequence of the data output when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of outputIndices is {4, 6, 8} when {@link OH_NNModel_SpecifyInputsAndOutputs} + * is called. In output buffer settings, the index value for the three outputs is {0, 1, 2}. + * @param dataBuffer Pointer to the output data. + * @param length Length of the data buffer, in bytes. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNExecutor_SetOutput(OH_NNExecutor *executor, + uint32_t outputIndex, + void *dataBuffer, + size_t length); + +/** + * @brief Obtains the dimension information about the output tensor. + * + * After {@link OH_NNExecutor_Run} is called to complete a single inference, call this method to obtain the specified output dimension + * information and number of dimensions. It is commonly used in dynamic shape input and output scenarios. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param outputIndex Output Index value, which is in the same sequence of the data output when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that outputIndices is {4, 6, 8} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * When {@link OH_NNExecutor_GetOutputShape} is called to obtain dimension information about the output tensor, + * outputIndices is {0, 1, 2}. + * + * @param shape Pointer to the int32_t array. The value of each element in the array is the length of the output tensor in each dimension. + * @param shapeLength Pointer to the uint32_t type. The number of output dimensions is returned. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNExecutor_GetOutputShape(OH_NNExecutor *executor, + uint32_t outputIndex, + int32_t **shape, + uint32_t *shapeLength); + +/** + * @brief Performs inference. + * + * Performs end-to-end inference and computing of the model on the device associated with the executor. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNExecutor_Run(OH_NNExecutor *executor); + +/** + * @brief Allocates shared memory to a single input on a device. + * + * Neural Network Runtime provides a method for proactively allocating shared memory on a device. By specifying the executor and input index value, + * this method allocates shared memory whose size is specified by length on the device associated with a single input and returns the + * operation result through the {@link OH_NN_Memory} instance. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param inputIndex Input index value, which is in the same sequence of the data input when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of inputIndices is {1, 5, 9} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * In the memory input application, the index value for the three inputs is {0, 1, 2}. + * @param length Memory size to be applied for, in bytes. + * @return Pointer to a {@link OH_NN_Memory} instance. + * @since 9 + * @version 1.0 + */ +OH_NN_Memory *OH_NNExecutor_AllocateInputMemory(OH_NNExecutor *executor, uint32_t inputIndex, size_t length); + +/** + * @brief Allocates shared memory to a single output on a device. + * + * Neural Network Runtime provides a method for proactively allocating shared memory on a device. By specifying the executor and + * output index value, this method allocates shared memory whose size is specified by length on the device associated with + * a single output and returns the operation result through the {@link OH_NN_Memory} instance. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param outputIndex Output Index value, which is in the same sequence of the data output when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of outputIndices is {4, 6, 8} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * In output memory application, the index value for the three outputs is {0, 1, 2}. + * @param length Memory size to be applied for, in bytes. + * @return Pointer to a {@link OH_NN_Memory} instance. + * @since 9 + * @version 1.0 + */ +OH_NN_Memory *OH_NNExecutor_AllocateOutputMemory(OH_NNExecutor *executor, uint32_t outputIndex, size_t length); + +/** + * @brief Releases the input memory to which the {@link OH_NN_Memory} instance points. + * + * This method needs to be called to release the memory instance created by calling {@link OH_NNExecutor_AllocateInputMemory}. + * Otherwise, memory leak will occur. + * The mapping between inputIndex and memory must be the same as that in memory instance creation. \n + * + * If memory or *memory is a null pointer, this method only prints warning logs and does not execute the release logic. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param inputIndex Input index value, which is in the same sequence of the data input when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of inputIndices is {1, 5, 9} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * In memory input release, the index value for the three inputs is {0, 1, 2}. + * @param memory Level-2 pointer to the {@link OH_NN_Memory} instance. After shared memory is destroyed, this method sets *memory to a null pointer. + * @since 9 + * @version 1.0 + */ +void OH_NNExecutor_DestroyInputMemory(OH_NNExecutor *executor, uint32_t inputIndex, OH_NN_Memory **memory); + +/** + * @brief Releases the output memory to which the {@link OH_NN_Memory} instance points. + * + * This method needs to be called to release the memory instance created by calling {@link OH_NNExecutor_AllocateOutputMemory}. Otherwise, memory leak will occur. + * The mapping between outputIndex and memory must be the same as that in memory instance creation. \n + * + * If memory or *memory is a null pointer, this method only prints warning logs and does not execute the release logic. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param outputIndex Output Index value, which is in the same sequence of the data output when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of outputIndices is {4, 6, 8} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * In output memory release, the index value for the three outputs is {0, 1, 2}. + * @param memory Level-2 pointer to the {@link OH_NN_Memory} instance. After shared memory is destroyed, this method sets *memory to a null pointer. + * @since 9 + * @version 1.0 + */ +void OH_NNExecutor_DestroyOutputMemory(OH_NNExecutor *executor, uint32_t outputIndex, OH_NN_Memory **memory); + +/** + * @brief Specifies the hardware shared memory pointed to by the {@link OH_NN_Memory} instance as the shared memory used by a single input. + * + * In scenarios where memory needs to be managed by yourself, this method binds the execution input to the {@link OH_NN_Memory} memory instance. + * During computing, the underlying device reads the input data from the shared memory pointed to by the memory instance. + * By using this method, concurrent execution of input setting, computing, and read can be implemented to improve inference efficiency of a data flow. \n + * + * @param executor Pointer to the {@link OH_NNExecutor} instance. + * @param inputIndex Input index value, which is in the same sequence of the data input when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of inputIndices is {1, 5, 9} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * When the input shared memory is specified, the index value for the three inputs is {0, 1, 2}. + * @param tensor Pointer to {@link OH_NN_Tensor}, used to set the tensor corresponding to a single input. + * @param memory Pointer to {@link OH_NN_Memory}. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNExecutor_SetInputWithMemory(OH_NNExecutor *executor, + uint32_t inputIndex, + const OH_NN_Tensor *tensor, + const OH_NN_Memory *memory); + +/** + * @brief Specifies the hardware shared memory pointed to by the {@link OH_NN_Memory} instance as the shared memory used by a single output. + * + * In scenarios where memory needs to be managed by yourself, this method binds the execution output to the {@link OH_NN_Memory} memory instance. + * When computing is performed, the underlying hardware directly writes the computing result to the shared memory to which the memory instance points. + * By using this method, concurrent execution of input setting, computing, and read can be implemented to improve inference efficiency of a data flow. \n + * + * @param executor Executor. + * @param outputIndex Output Index value, which is in the same sequence of the data output when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * Assume that the value of outputIndices is {4, 6, 8} when {@link OH_NNModel_SpecifyInputsAndOutputs} is called. + * When output shared memory is specified, the index value for the three outputs is {0, 1, 2}. + * @param memory Pointer to {@link OH_NN_Memory}. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNExecutor_SetOutputWithMemory(OH_NNExecutor *executor, + uint32_t outputIndex, + const OH_NN_Memory *memory); + +/** + * @brief Destroys an executor instance to release the memory occupied by the executor. + * + * This method needs to be called to release the executor instance created by calling {@link OH_NNExecutor_Construct}. Otherwise, + * memory leak will occur. \n + * + * If executor or *executor is a null pointer, this method only prints warning logs and does not execute the release logic. \n + * + * @param executor Level-2 pointer to the {@link OH_NNExecutor} instance. + * @since 9 + * @version 1.0 + */ +void OH_NNExecutor_Destroy(OH_NNExecutor **executor); + + +/** + * @brief Obtains the ID of the device connected to Neural Network Runtime. + * + * Each device has a unique and fixed ID in Neural Network Runtime. This method returns device IDs on the current device through the uint32_t array. \n + * + * Device IDs are returned through the size_t array. Each element of the array is the ID of a single device. + * The array memory is managed by Neural Network Runtime. + * The data pointer is valid before this method is called next time. \n + * + * @param allDevicesID Pointer to the size_t array. The input *allDevicesID must be a null pointer. Otherwise, {@link OH_NN_INVALID_PARAMETER} is returned. + * @param deviceCount Pointer of the uint32_t type, which is used to return the length of (*allDevicesID). + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. + * If the operation fails, an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNDevice_GetAllDevicesID(const size_t **allDevicesID, uint32_t *deviceCount); + +/** + * @brief Obtains the name of the specified device. + * + * deviceID specifies the device whose name will be obtained. The device ID needs to be obtained by calling {@link OH_NNDevice_GetAllDevicesID}. \n + * + * @param deviceID Device ID. + * @param name Pointer to the char array. The passed (*char) must be a null pointer. Otherwise, {@link OH_NN_INVALID_PARAMETER} is returned. + * The value of (*name) is a C-style string ended with '\0'. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNDevice_GetName(size_t deviceID, const char **name); + +/** + * @brief Obtains the type information of the specified device. + * + * deviceID specifies the device whose type will be obtained. Currently, Neural Network Runtime supports the following device types: + * - OH_NN_CPU: CPU device. + * - OH_NN_GPU: GPU device. + * - OH_NN_ACCELERATOR: machine learning dedicated accelerator. + * - OH_NN_OTHERS: other hardware types. \n + * + * @param deviceID Device ID. + * @param deviceType Pointer to the {@link OH_NN_DeviceType} instance. The device type information is returned. + * @return Execution result of the function. If the operation is successful, OH_NN_SUCCESS is returned. If the operation fails, + * an error code is returned. For details about the error codes, see {@link OH_NN_ReturnCode}. + * @since 9 + * @version 1.0 + */ +OH_NN_ReturnCode OH_NNDevice_GetType(size_t deviceID, OH_NN_DeviceType *deviceType); + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** @} */ +#endif // NEURAL_NETWORK_RUNTIME_H diff --git a/ai/neural_network_runtime/neural_network_runtime_type.h b/ai/neural_network_runtime/neural_network_runtime_type.h new file mode 100644 index 000000000..3bbbb4c52 --- /dev/null +++ b/ai/neural_network_runtime/neural_network_runtime_type.h @@ -0,0 +1,1783 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup NeuralNeworkRuntime + * @{ + * + * @brief Provides APIs for accelerating the Neural Network Runtime model inference. + * + * @Syscap SystemCapability.Ai.NeuralNetworkRuntime + * @since 9 + * @version 1.0 + */ + +/** + * @file neural_network_runtime_type.h + * + * @brief Defines the structure and enumeration for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ + +#ifndef NEURAL_NETWORK_RUNTIME_TYPE_H +#define NEURAL_NETWORK_RUNTIME_TYPE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines the handles of models for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NNModel OH_NNModel; + +/** + * @brief Defines the compiler handle for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NNCompilation OH_NNCompilation; + +/** + * @brief Defines the executor handle for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NNExecutor OH_NNExecutor; + +/** + * @brief Defines the hardware performance mode. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** No performance mode preference */ + OH_NN_PERFORMANCE_NONE = 0, + /** Low power consumption mode*/ + OH_NN_PERFORMANCE_LOW = 1, + /** Medium performance mode */ + OH_NN_PERFORMANCE_MEDIUM = 2, + /** High performance mode */ + OH_NN_PERFORMANCE_HIGH = 3, + /** Ultimate performance mode */ + OH_NN_PERFORMANCE_EXTREME = 4 +} OH_NN_PerformanceMode; + +/** + * @brief Defines the model inference task priority. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** No priority preference */ + OH_NN_PRIORITY_NONE = 0, + /** Low priority */ + OH_NN_PRIORITY_LOW = 1, + /** Medium priority */ + OH_NN_PRIORITY_MEDIUM = 2, + /** High priority */ + OH_NN_PRIORITY_HIGH = 3 +} OH_NN_Priority; + +/** + * @brief Defines error codes for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** The operation is successful. */ + OH_NN_SUCCESS = 0, + /** The operation failed. */ + OH_NN_FAILED = 1, + /** Invalid parameter. */ + OH_NN_INVALID_PARAMETER = 2, + /** Memory-related error, for example, insufficient memory, memory data copy failure, or memory application failure. */ + OH_NN_MEMORY_ERROR = 3, + /** Invalid operation. */ + OH_NN_OPERATION_FORBIDDEN = 4, + /** Null pointer exception */ + OH_NN_NULL_PTR = 5, + /** Invalid file. */ + OH_NN_INVALID_FILE = 6, + /** A hardware error occurs, for example, HDL service crash. */ + OH_NN_UNAVALIDABLE_DEVICE = 7, + /** Invalid path. */ + OH_NN_INVALID_PATH = 8 +} OH_NN_ReturnCode; + +/** + * @brief Defines activation function types in the fusion operator for Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum : int8_t { + /** The fusion activation function is not specified. */ + OH_NN_FUSED_NONE = 0, + /** Fusion relu activation function */ + OH_NN_FUSED_RELU = 1, + /** Fusion relu6 activation function */ + OH_NN_FUSED_RELU6 = 2 +} OH_NN_FuseType; + +/** + * @brief Defines the layout type of tensor data. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** The tensor does not have a specific layout type (such as scalar or vector). */ + OH_NN_FORMAT_NONE = 0, + /** The tensor arranges data in NCHW format.*/ + OH_NN_FORMAT_NCHW = 1, + /** The tensor arranges data in NHWC format.*/ + OH_NN_FORMAT_NHWC = 2 +} OH_NN_Format; + +/** + * @brief Defines device types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Devices that are not CPU, GPU, or dedicated accelerator*/ + OH_NN_OTHERS = 0, + /** CPU device */ + OH_NN_CPU = 1, + /** GPU device */ + OH_NN_GPU = 2, + /** Dedicated hardware accelerator */ + OH_NN_ACCELERATOR = 3, +} OH_NN_DeviceType; + +/** + * @brief Defines tensor data types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Unknown type */ + OH_NN_UNKNOWN = 0, + /** bool */ + OH_NN_BOOL = 1, + /** int8 */ + OH_NN_INT8 = 2, + /** int16 */ + OH_NN_INT16 = 3, + /** int32 */ + OH_NN_INT32 = 4, + /** int64 */ + OH_NN_INT64 = 5, + /** uint8 */ + OH_NN_UINT8 = 6, + /** uint16 */ + OH_NN_UINT16 = 7, + /** uint32 */ + OH_NN_UINT32 = 8, + /** uint64 */ + OH_NN_UINT64 = 9, + /** float16 */ + OH_NN_FLOAT16 = 10, + /** float32 */ + OH_NN_FLOAT32 = 11, + /** float64 */ + OH_NN_FLOAT64 = 12 +} OH_NN_DataType; + + +/** + * @brief Defines operator types supported by Neural Network Runtime. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** + * Returns the tensor of the sum of the elements corresponding to two input tensors. + * + * Inputs: + * + * * input1: first input tensor, of the Boolean or number type. + * * input2: second input tensor, whose data type must be the same as that of the first tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: sum of input1 and input2. + * The data shape is the same as that of the input after broadcasting, + * and the data type is the same as that of the input with a higher precision. + */ + OH_NN_OPS_ADD = 1, + + /** + * Apply 2D average pooling to the input tensor, which now must be in NHWC format. The int8 quantization input is supported. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize indicates the kernel size used to obtain the average value. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padMode: padding mode, which is optional. The value is of the int type and can be 0 (same) or 1 (valid). + * The nearest neighbor value is used for padding. + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. Excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize indicates the kernel size used to obtain the average value. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padList: padding around input. It is an int array [top, bottom, left, right], and the nearest neighbor values are used for padding. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: average pooling result of the input. + */ + OH_NN_OPS_AVG_POOL = 2, + + /** + * Batch normalization is performed on a tensor to scale and shift tensor elements, relieving potential covariate shift in a batch of data. + * + * Inputs: + * + * * input: n-dimensional tensor of shape [N, ..., C]. The nth dimension is the number of channels. + * * scale: 1D tensor of the scaling factor used to scale the first normalized tensor. + * * offset: 1D tensor used to move to the first normalized tensor. + * * mean: 1D tensor of the overall mean value. It is used only for inference. In case of training, this parameter must be left empty. + * * variance: 1D tensor used for the overall variance. It is used only for inference. In case of training, this parameter must be left empty. + * + * Parameters: + * + * * epsilon: fixed small additional value. + * + * Outputs: + * + * * output: n-dimensional output tensor whose shape and data type are the same as those of the input. + */ + OH_NN_OPS_BATCH_NORM = 3, + + /** + * Divides the batch dimension of a 4D tensor into small blocks by block_shape, and interleaves these blocks back into the spatial dimension. + * + * Parameters: + * + * * input: input tensor. The dimension will be divided into small blocks, and these blocks will be interleaved into the spatial dimension. + * + * Outputs: + * + * * blockSize: size of each block to be interleaved into the spatial dimension. The value is an array [height_block, width_block]. + * * crops: elements truncated from the spatial dimension of the output. The value is a 2D array [[crop0_start, crop0_end], + * [crop1_start, crop1_end]] with the shape of (2, 2). + * + * + * Outputs: + * + * * output. Assume that the shape of input is (n,h,w,c) and the shape of output is (n',h',w',c'): + * n' = n / (block_shape[0] * block_shape[1]) + * h' = h * block_shape[0] - crops[0][0] - crops[0][1] + * w' = w * block_shape[1] - crops[1][0] - crops[1][1] + * c'= c + */ + OH_NN_OPS_BATCH_TO_SPACE_ND = 4, + + /** + * Offsets the data in each dimension of the input tensor. + * + * Inputs: + * + * * input: input tensor, which can have two to five dimensions. + * * bias: offset of the number of input dimensions. + * + * Outputs: + * + * * output: sum of the input tensor and the bias in each dimension. + */ + OH_NN_OPS_BIAS_ADD = 5, + + /** + * Converts the data type in the input tensor. + * + * Inputs: + * + * * input: input tensor. + * * type: converted data type. + * + * Outputs: + * + * * output: converted tensor. + */ + OH_NN_OPS_CAST = 6, + + /** + * Connects tensors in a specified dimension. + * + * Inputs: + * + * * input: N input tensors. + * + * Parameters: + * + * * axis: dimension for connecting tensors. + * + * Outputs: + * + * * output: result of connecting N tensors along the axis. + */ + OH_NN_OPS_CONCAT = 7, + + /** + * 2D convolutional layer. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 and + * less than or equal to in_channel, it is a group convolution. + * * activationType is an integer constant which is contained in FuseType. The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. + * If group is in_channel, it is depthwiseConv2d. In this case, group==in_channel==out_channel. + * If group is greater than 1 and less than in_channel, it is a group convolution. In this case, out_channel==group. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: convolution computing result. + */ + OH_NN_OPS_CONV2D = 8, + + /** + * 2D convolution transposition. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * + * Parameters: + * + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 and + * less than or equal to in_channel, it is a group convolution. + * * outputPads: padding along the height and width of the output tensor. The value is an int or a tuple. + * It can be a single integer to specify the same value for all spatial dimensions. The amount of output + * padding along a dimension must be less than the stride along this dimension. + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, inChannel/group] format. + * The value of inChannel must be exactly divided by the value of group. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * group: number of groups in which the input is divided by in_channel. The value is of the int type. + * If group is 1, it is a conventional convolution. If group is greater than 1 + * and less than or equal to in_channel, it is a group convolution. + * * outputPads: padding along the height and width of the output tensor. The value is an int or a tuple. + * It can be a single integer to specify the same value for all spatial dimensions. The amount of output padding + * along a dimension must be less than the stride along this dimension. + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computing result after convolution and transposition. + */ + OH_NN_OPS_CONV2D_TRANSPOSE = 9, + + /** + * 2D depthwise separable convolution. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, 1] format. + * outChannel is equal to channelMultiplier multiplied by inChannel. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padMode: padding mode of input. The value is of the int type and can be 0 (same) or 1 (valid). + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: input tensor. + * * weight: convolution weight in [outChannel, kernelHeight, kernelWidth, 1] format. + * outChannel is equal to channelMultiplier multiplied by inChannel. + * * bias: bias of the convolution. It is an array with a length of [outChannel]. + * In quantization scenarios, the bias parameter does not require quantization parameters. + * The quantization version requires data input of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * stride: movement stride of the convolution kernel in height and width. It is an int array [strideHeight, strideWidth]. + * * dilation: dilation size of the convolution kernel in height and width. It is an int array [dilationHeight, dilationWidth]. + * The value must be greater than or equal to 1 and cannot exceed the height and width of input. + * * padList: padding around input. It is an int array [top, bottom, left, right]. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: convolution computing result. + */ + OH_NN_OPS_DEPTHWISE_CONV2D_NATIVE = 10, + + /** + * Divides two input scalars or tensors. + * + * Inputs: + * + * * input1: first input, which is a number, a bool, or a tensor whose data type is number or Boolean. + * * input2: second input, which must meet the following requirements: + * If the first input is a tensor, the second input can be a real number, a Boolean value, or a tensor whose data type is real number or Boolean value. + * If the first input is a real number or Boolean value, the second input must be a tensor whose data type is real number or Boolean value. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: result of dividing input1 by input2. + */ + OH_NN_OPS_DIV = 11, + + /** + * Sets parameters to perform product (dot product), sum (addition and subtraction), or max (larger value) on the input. + * + * Inputs: + * + * * input1: first input tensor. + * * input2: second input tensor. + * + * Parameters: + * + * * mode: operation mode. The value is an enumerated value. + * + * Outputs: + * + * * output: computing result, which has the same data type and shape of output and input1. + */ + OH_NN_OPS_ELTWISE = 12, + + /** + * Adds an additional dimension to a tensor in the given dimension. + * + * Inputs: + * + * * input: input tensor. + * * axis: index of the dimension to be added. The value is of the int32_t type and must be a constant in the range [-dim-1, dim]. + * + * Outputs: + * + * * output: tensor after dimension expansion. + */ + OH_NN_OPS_EXPAND_DIMS = 13, + + /** + * Creates a tensor of the specified dimensions and fills it with a scalar. + * + * Inputs: + * + * * value: scalar used to fill the tensor. + * * shape: dimensions of the tensor to be created. + * + * Outputs: + * + * * output: generated tensor, which has the same data type as value. The tensor shape is specified by the shape parameter. + */ + OH_NN_OPS_FILL = 14, + + /** + * Full connection. The entire input is used as the feature map for feature extraction. + * + * Inputs: + * + * * input: full-connection input tensor. + * * weight: weight tensor for a full connection. + * * bias: full-connection bias. In quantization scenarios, no quantized parameter is required for this parameter. + * If quantization is required, the data must be of the OH_NN_INT32 type. + * The actual quantization parameters are determined by input and weight. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computed tensor. + * + * If the input contains the axis parameter: + * + * Inputs: + * + * * input: full-connection input tensor. + * * weight: weight tensor for a full connection. + * * bias: full-connection bias. In quantization scenarios, no quantized parameter is required for this parameter. + * If quantization is required, the data must be of the OH_NN_INT32 type. The actual quantization parameters + * are determined by input and weight. + * + * Parameters: + * + * * axis: axis in which the full connection is applied. The specified axis and its following axes are + * converted into a 1D tensor for applying the full connection. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: computed tensor. + */ + OH_NN_OPS_FULL_CONNECTION = 15, + + /** + * Returns the slice of the input tensor based on the specified index and axis. + * + * Inputs: + * + * * input: tensor to be sliced. + * * inputIndices: indices of the specified input on the axis. The value is an array of the int type + * and must be in the range [0,input.shape[axis]). + * * axis: axis on which input is sliced. The value is an array with one element of the int32_t type. + * + * Outputs: + * + * * output: sliced tensor. + */ + OH_NN_OPS_GATHER = 16, + + /** + * Calculate the Hswish activation value of the input. + * + * Inputs: + * + * * An n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional Hswish activation value. The data type is the same as that of shape and input. + */ + OH_NN_OPS_HSWISH = 17, + + /** + * For input1 and input2, calculate the result of input1[i]<=input2[i] for each pair of elements, + * where i is the index of each element in the input tensor. + * + * Inputs: + * + * * input1, which can be a real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * * input2, which can be a real number or a Boolean value if input1 is a tensor and must be a tensor + * with the data type of real number or NN_BOOL if input1 is not a tensor. + * + * Outputs: + * + * * A tensor of the data type NN_BOOL. When a quantization model is used, the quantization parameters of the output + * cannot be omitted. However, values of the quantization parameters do not affect the result. + */ + OH_NN_OPS_LESS_EQUAL = 18, + + /** + * Calculate the inner product of input1 and input2. + * + * Inputs: + * + * * input1: n-dimensional input tensor. + * * input2: n-dimensional input tensor. + * + * Parameters: + * + * * TransposeX: Boolean value indicating whether to transpose input1. + * * TransposeY: Boolean value indicating whether to transpose input2. + * + * Outputs: + * + * * output: inner product obtained after calculation. In case of type!=NN_UNKNOWN, the output data type is + * determined by type. In case of type==NN_UNKNOWN, the output data type depends on the data type + * converted during computing of inputX and inputY. + * + */ + OH_NN_OPS_MATMUL = 19, + + /** + * Calculates the maximum of input1 and input2 element-wise. The inputs of input1 and input2 + * comply with the implicit type conversion rules to make the data types consistent. * The inputs must be two tensors or one tensor and one scalar. + * When the inputs are two tensors, their data types cannot be both NN_BOOL. Their shapes can be broadcast to the same size. + * When the inputs are one tensor and one scalar, the scalar must be a constant. + * + * Inputs: + * + * * input1: n-dimensional input tensor of the real number or NN_BOOL type. + * * input2: n-dimensional input tensor of the real number or NN_BOOL type. + * + * Outputs: + * + * * output: n-dimensional output tensor. The shape and data type of + * output are the same as those of the two inputs with a higher precision. + */ + OH_NN_OPS_MAXIMUM = 20, + + /** + * Applies 2D maximum pooling to the input tensor. + * + * If the input contains the padMode parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize: kernel size used to obtain the maximum. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padMode: padding mode, which is optional. The value is of the int type and can be 0 (same) + * or 1 (valid). The nearest neighbor value is used for padding. + * 0 (same): The height and width of the output are the same as those of the input. + * The total padding quantity is calculated horizontally and vertically and evenly distributed to the top, bottom, left, and right if possible. + * Otherwise, the last additional padding will be completed from the bottom and right. + * 1 (valid): The possible maximum height and width of the output will be returned in case of no padding. The excessive pixels will be discarded. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * If the input contains the padList parameter: + * + * Inputs: + * + * * input: tensor. + * + * Parameters: + * + * * kernelSize: kernel size used to obtain the maximum. It is an int array [kernel_height, kernel_width]. + * The first number indicates the kernel height, and the second number indicates the kernel width. + * * strides indicates the distance of kernel moving. The value is an int array [stride_height, stride_width]. + * The first number indicates the moving step in height, and the second number indicates the moving step in width. + * * padList: padding around input. It is an int array [top, bottom, left, right], + * and the nearest neighbor values are used for padding. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: tensor obtained after maximum pooling is applied to the input. + */ + OH_NN_OPS_MAX_POOL = 21, + + /** + * Multiplies elements in the same positions of inputX and inputY to obtain the output. + * If inputX and inputY have different shapes, expand them to the same shape + * through broadcast and then perform multiplication. + * + * Inputs: + * + * * input1: n-dimensional tensor. + * * input2: n-dimensional tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * Product of each element of input1 and input2. + */ + OH_NN_OPS_MUL = 22, + + /** + * Generates a one-hot tensor based on the positions specified by indices. The positions specified by indices + * are determined by on_value, and other positions are determined by off_value. + * + * Inputs: + * + * * indices: n-dimensional tensor. Each element in indices determines the position of + * on_value in each one-hot vector. + * * depth: integer scalar that determines the depth of the one-hot vector. The value of depth + * must be greater than 0. + * * on_value: scalar that specifies a valid value in the one-hot vector. + * * off_value: scalar that specifies the values of other posistions in the one-hot vector except the valid value. + * + * Parameters: + * + * * axis: integer scalar that specifies the dimension for inserting the one-hot. Assume that the shape + * of indices is [N, C], and the value of depth is D. + * When axis is 0, the shape of the output is [D, N, C]. + * When axis is -1, the shape of the output is [N, C, D]. + * When axis is 1, the shape of the output is [N, D, C]. + * + * Outputs: + * + * * output: (n+1)-dimensional tensor if indices is an n-dimensional tensor. + * The output shape is determined by indices and axis. + */ + OH_NN_OPS_ONE_HOT = 23, + + /** + * Pads inputX in the specified dimensions. + * + * Inputs: + * + * * inputX: n-dimensional tensor in [BatchSize, ...] format. + * * paddings: 2D tensor that specifies the length to pad in each dimension. The shape is [n, 2]. + * For example, paddings[i][0] indicates the number of paddings to be added preceding inputX in the ith dimension. + * paddings[i][1] indicates the number of paddings to be added following inputX in the ith dimension. + * + * Parameters: + * + * * padValues: value to be added to the pad operation. The value is a constant with the same data type as inputX. + * + * Outputs: + * + * * output: n-dimensional tensor after padding, with the same dimensions and data type as inputX. + * The shape is determined by inputX and paddings. + * output.shape[i] = input.shape[i] + paddings[i][0]+paddings[i][1] + */ + OH_NN_OPS_PAD = 24, + + /** + * Calculates the y power of each element in input. The inputs must be two tensors or one tensor and one scalar. + * When the inputs are two tensors, their data types cannot be both NN_BOOL, and their shapes must be the same. + * When the inputs are one tensor and one scalar, the scalar must be a constant. + * + * Inputs: + * + * * input: real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * * y: real number, Boolean value, or tensor whose data type is real number or NN_BOOL. + * + * Outputs: + * + * * output: tensor, whose shape is determined by the shape of input and y after broadcasting. + */ + OH_NN_OPS_POW = 25, + + /** + * Scales a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * * scale: scaling tensor. + * * bias: bias tensor. + * + * Parameters: + * + * * axis: dimensions to be scaled. + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: scaled n-dimensional tensor, whose data type is the same as that of input and + * shape is determined by axis. + */ + OH_NN_OPS_SCALE = 26, + + /** + * Calculates the shape of the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: integer array representing the dimensions of the input tensor. + */ + OH_NN_OPS_SHAPE = 27, + + /** + * Applies the sigmoid operation to the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: result of the sigmoid operation. It is an n-dimensional tensor + * with the same data type and shape as input. + */ + OH_NN_OPS_SIGMOID = 28, + + /** + * Slices a tensor of the specified size from the input in each dimension. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * begin: start of the slice, which is an array of integers greater than or equal to 0. + * * size: slice length, which is an array of integers greater than or equal to 0. + * Assume that a dimension is i and 1<=size[i]<=input.shape[i]-begin[i]. + * + * Outputs: + * + * * output: n-dimensional tensor obtained by slicing. + * The TensorType, shape, and size of the output are the same as those of the input. + */ + OH_NN_OPS_SLICE = 29, + + /** + * Applies the softmax operation to the input tensor. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Parameters: + * + * * axis: dimension in which the softmax operation is performed. + * The value is of the int64 type. It is an integer in the range [-n, n). + * + * Outputs: + * + * * output: result of the softmax operation. It is an n-dimensional tensor with + * the same data type and shape as input. + */ + OH_NN_OPS_SOFTMAX = 30, + + /** + * Divides a 4D tensor into small blocks and combines these blocks in the original batch. + * The number of blocks is blockShape[0] multiplied by blockShape[1]. + * + * Inputs: + * + * * input: 4D tensor. + * + * Parameters: + * + * * blockShape: a pair of integers. Each of them is greater than or equal to 1. + * * paddings: a pair of arrays. Each of them consists of two integers. The four integers that form paddings + * must be greater than or equal to 0. paddings[0][0] and paddings[0][1] + * specify the number of paddings in the third dimension, and paddings[1][0] and paddings[1][1] + * specify the number of paddings in the fourth dimension. + * + * Outputs: + * + * * output: 4D tensor with the same data type as input. The shape is determined by input, + * blockShape, and paddings. Assume that the input shape is [n,c,h,w], then: + * output.shape[0] = n * blockShape[0] * blockShape[1] + * output.shape[1] = c + * output.shape[2] = (h + paddings[0][0] + paddings[0][1]) / blockShape[0] + * output.shape[3] = (w + paddings[1][0] + paddings[1][1]) / blockShape[1] + * (h + paddings[0][0] + paddings[0][1]) and (w + paddings[1][0] + paddings[1][1]) is exactly divisible by + * (h + paddings[0][0] + paddings[0][1]) and (w + paddings[1][0] + paddings[1][1]). + * + */ + OH_NN_OPS_SPACE_TO_BATCH_ND = 31, + + /** + * Splits the input into multiple tensors along the axis dimension. The number of tensors is specified by outputNum. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Parameters: + * + * * outputNum: number of output tensors. The data type is long. + * * size_splits: size of each tensor split from the input. The value is a 1D tensor of the int type. + * If size_splits is empty, the input will be evenly split into tensors of the same size. In this case, + * input.shape[axis] can be exactly divisible by outputNum. + * If size_splits is not empty, the sum of all its elements must be equal to input.shape[axis]. + * * axis: splitting dimension of the int type. + * + * Outputs: + * + * * outputs: array of n-dimensional tensors, with the same data type and dimensions. + * The data type of each tensor is the same as that of input. + */ + OH_NN_OPS_SPLIT = 32, + + /** + * Calculates the square root of a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: square root of the input. It is an n-dimensional tensor with the same data type and shape as input. + */ + OH_NN_OPS_SQRT = 33, + + /** + * Calculates the square of the difference between two tensors. The SquaredDifference operator supports tensor and tensor subtraction. + * If two tensors have different TensorTypes, the Sub operator converts the low-precision tensor to a high-precision one. + * If two tensors have different shapes, the two tensors can be extended to tensors with the same shape through broadcast. + * + * Inputs: + * + * * input1: minuend, which is a tensor of the NN_FLOAT16, NN_FLOAT32, NN_INT32, or NN_BOOL type. + * * input2: subtrahend, which is a tensor of the NN_FLOAT16, NN_FLOAT32, NN_INT32, or NN_BOOL type. + * + * Outputs: + * + * * output: square of the difference between two inputs. The output shape is determined + * byinput1 and input2. If they have the same shape, the output tensor has the same shape as them. + * If they have different shapes, perform the broadcast operation on input1 and input2 and perform subtraction. + * TensorType of the output is the same as that of the input tensor with higher precision. + */ + OH_NN_OPS_SQUARED_DIFFERENCE = 34, + + /** + * Removes the dimension with a length of 1 from the specified axis. The int8 quantization input is supported. + * Assume that the input shape is [2, 1, 1, 2, 2] and axis is [0,1], the output shape is [2, 1, 2, 2], + * which means the dimension whose length is 0 between dimensions 0 and dimension 1 is removed. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Parameters: + * + * * axis: dimension to be removed. The value is of int64_t type and can be an integer in the range [-n, n) or an array. + * + * Outputs: + * + * * output: output tensor. + */ + OH_NN_OPS_SQUEEZE = 35, + + /** + * Stacks multiple tensors along the specified axis. If each tensor has n dimensions before stacking, + * the output tensor will have n+1 dimensions. + * + * Inputs: + * + * * input: input for stacking, which can contain multiple n-dimensional tensors. + * Each of them must have the same shape and type. + * + * Parameters: + * + * * axis: dimension for tensor stacking, which is an integer. The value range is [-(n+1),(n+1)), + * which means a negative number is allowed. + * + * Outputs: + * + * * output: stacking result of the input along the axis dimension. The value is an n+1-dimensional tensor + * and has the same TensorType as the input. + */ + OH_NN_OPS_STACK = 36, + + /** + * Slices a tensor with the specified stride. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * begin: start of slicing, which is a 1D tensor. The length of begin is n. + * begin[i] specifies the start of slicing in the ith dimension. + * * end: end of slicing, which is a 1D tensor. The length of end is n. + * end[i] specifies the end of slicing in the ith dimension. + * * strides: slicing stride, which is a 1D tensor. The length of strides is n. + * strides[i] specifies the stride at which the tensor is sliced in the ith dimension. + * + * Parameters: + * + * * beginMask: an integer used to mask begin. beginMask is represented in binary code. + * In case of binary(beginMask)[i]==1, for the ith dimension, elements are sliced from the first element + * at strides[i] until the end[i]-1 element. + * + * * endMask: an integer used to mask end. endMask is represented in binary code. + * In case of binary(endMask)[i]==1, elements are sliced from the element at the begin[i] position + * in the ith dimension until the tensor boundary at strides[i]. + * + * * ellipsisMask: integer used to mask begin and end. ellipsisMask is represented in binary code. + * In case of binary(ellipsisMask)[i]==1, elements are sliced from the first element at strides[i] in the ith dimension + * until the tensor boundary. Only one bit of binary(ellipsisMask) can be a non-zero value. + * + * * newAxisMask: new dimension, which is an integer. newAxisMask is represented in binary code. + * In case of binary(newAxisMask)[i]==1, a new dimension whose length is 1 is inserted into the ith dimension. + * * shrinkAxisMask: shrinking dimension, which is an integer. * shrinkAxisMask is represented in binary code. + * In the case of binary(shrinkAxisMask)[i]==1, all elements in the ith dimension will be discarded, + * and the length of the ith dimension is shrunk to 1. + * + * Outputs: + * + * * A tensor, with the same data type as input. The number of dimensions of the output tensor is rank(input[0])+1. + */ + OH_NN_OPS_STRIDED_SLICE = 37, + + /** + * Calculates the difference between two tensors. + * + * Inputs: + * + * * input1: minuend, which is a tensor. + * * input2: subtrahend, which is a tensor. + * + * Parameters: + * + * * activationType is an integer constant which is contained in FuseType. + * The specified activation function is called before output. + * + * Outputs: + * + * * output: difference between the two tensors. The output shape is determined byinput1 and input2. + * If they have the same shape, the output tensor has the same shape as them. + * If they have different shapes, perform the broadcast operation on input1 and input2 and perform subtraction. + * TensorType of the output is the same as that of the input tensor with higher precision. + */ + OH_NN_OPS_SUB = 38, + + /** + * Computes hyperbolic tangent of the input tensor. + * + * Inputs: + * + * * input: n-dimensional tensor. + * + * Outputs: + * + * * output: hyperbolic tangent of the input. The TensorType and tensor shape are the same as those of the input. + */ + OH_NN_OPS_TANH = 39, + + /** + * Copies a tensor the specified times. + * + * Inputs: + * * input: n-dimensional tensor. + * * multiples: number of times that the input tensor is copied in each dimension. The value is a 1D tensor. + * The length m is not less than the number of dimensions, that is, n. + * + * Outputs: + * * An m-dimensional tensor whose TensorType is the same as that of the input. If input and + * multiples have the same length, input and output have the same number of dimensions. + * If the length of multiples is greater than n, 1 is used to fill the input dimension, + * and then the input is copied in each dimension the specified times to obtain the m-dimensional tensor. + */ + OH_NN_OPS_TILE = 40, + + /** + * Transposes data of input 0 based on permutation. + * + * Inputs: + * + * * input: n-dimensional tensor to be transposed. + * * permutation: The value is a 1D tensor whose length is the same as the number of dimensions of input 0. + * + * Outputs: + * + * * output: n-dimensional tensor. TensorType of output 0 is the same as that of input 0, + * and the output shape is determined by the shape and permutation of input 0. + */ + OH_NN_OPS_TRANSPOSE = 41, + + /** + * Calculates the average value in the specified dimension. If keepDims is set to false, the number of dimensions + * is reduced for the input; if keepDims is set to true, the number of dimensions is retained. + * + * Inputs: + * + * * input: n-dimensional input tensor, where n is less than 8. + * * axis: dimension used to calculate the average value. The value is a 1D tensor. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * + * Outputs: + * + * * output: m-dimensional output tensor whose data type is the same as that of the input. If keepDims is + * false, m==n. If keepDims is true, minput: 4D input tensor. Each element in the input cannot be less than 0. The input layout must be [batchSize, height, width, channels]. + * + * Parameters: + * + * * newHeight: resized height of the 4D tensor. + * * newWidth: resized width of the 4D tensor. + * * preserveAspectRatio: indicates whether to maintain the height/width ratio of input after resizing. + * * coordinateTransformMode: coordinate transformation method used by the resize operation. The value is an int32 integer. + * Currently, the following methods are supported: + * * excludeOutside: an int64 floating point number. When its value is 1, the sampling weight of the part that + * exceeds the boundary of input is set to 0, and other weights are normalized. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same shape and data type as input. + */ + OH_NN_OPS_RESIZE_BILINEAR = 43, + + /** + * Calculates the reciprocal of the square root of a tensor. + * + * Inputs: + * + * * input: n-dimensional tensor, where n is less than 8. Each element of the tensor cannot be less than 0. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same shape and data type as input. + */ + OH_NN_OPS_RSQRT = 44, + + /** + * Reshapes a tensor. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * InputShape: shape of the output tensor. The value is a 1D constant tensor. + * + * Outputs: + * + * * output: tensor whose data type is the same as that of input and shape is determined by InputShape. + */ + OH_NN_OPS_RESHAPE = 45, + + /** + * Calculates the PReLU activation value of input and weight. + * + * Inputs: + * + * * input: n-dimensional tensor. If n is greater than or equal to 2, inputX must be [BatchSize, ..., Channels]. + * The second dimension is the number of channels. + * * weight: 1D tensor. The length of weight must be 1 or equal to the number of channels. If the length of weight is 1, + * all channels share the same weight. + * If the length of weight is equal to the number of channels, each channel exclusively has a weight. + * If n is less than 2 for inputX, the weight length must be 1. + * + * Outputs: + * + * * output: PReLU activation value of x, with the same shape and data type as inputX. + */ + OH_NN_OPS_PRELU = 46, + + /** + * Calculates the Relu activation value of input. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NN_OPS_RELU = 47, + + /** + * Calculates the Relu6 activation value of the input, that is, calculate min(max(x, 0), 6) for each element x in the input. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * + * Outputs: + * + * * output: n-dimensional Relu6 tensor, with the same data type and shape as the input tensor. + */ + OH_NN_OPS_RELU6 = 48, + + /** + * Applies layer normalization for a tensor from the specified axis. + * + * Inputs: + * + * * input: n-dimensional input tensor. + * * gamma: m-dimensional tensor. The dimensions of gamma must be the same as + * the shape of the part of the input tensor to normalize. + * * beta: m-dimensional tensor with the same shape as gamma. + * + * Parameters: + * + * * beginAxis is an NN_INT32 scalar that specifies the axis from which normalization starts. The value range is [1, rank(input)). + * * epsilon is a scalar of NN_FLOAT32. It is a tiny amount in the normalization formula. The common value is 1e-7. + * + * Outputs: + * + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NN_OPS_LAYER_NORM = 49, + + /** + * Calculates the accumulated value for a tensor along the specified dimension. + * + * Inputs: + * + * * input: n-dimensional input tensor, where n is less than 8. + * * axis: dimension used to calculate the product. The value is a 1D tensor. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * When its value is true, the number of output dimensions is the same as that of the input. + * When its value is false, the number of output dimensions is reduced. + * + * Outputs: + * + * * output: m-dimensional output tensor whose data type is the same as that of the input. + * If keepDims is false, m==n. If keepDims is true, mkeepDims is set to false, + * the number of dimensions is reduced for the input; if keepDims is set to true, the number of dimensions is retained. + * + * Inputs: + * + * * A n-dimensional input tensor, where n is less than 8. + * * A 1D tensor specifying the dimension used to operate the logical OR. The value range of each element in axis is [–n, n). + * + * Parameters: + * + * * keepDims: indicates whether to retain the dimension. The value is a Boolean value. + * + * Outputs: + * * output: m-dimensional output tensor whose data type is the same as that of the input. + * If keepDims is false, m==n. If keepDims is true, minput: n-dimensional tensor. + * + * Parameters: + * + * * src_t: data type of the input. + * * dst_t: data type of the output. + * + * Outputs: + * + * * output: n-dimensional tensor. The data type is determined by input2. + * The output shape is the same as the input shape. + */ + OH_NN_OPS_QUANT_DTYPE_CAST = 52, + + /** + * Obtains the values and indices of the largest k entries in the last dimension. + * + * Inputs: + * + * * input: n-dimensional tensor. + * * input k: first k records of data and their indices. + * + * Parameters: + * + * * sorted: order of sorting. The value true means descending and false means ascending. + * + * Outputs: + * + * * output0: largest k elements in each slice of the last dimension. + * * output1: index of the value in the last dimension of the input. + */ + OH_NN_OPS_TOP_K = 53, + + /** + * Returns the index of the maximum tensor value across axes. + * + * Inputs: + * + * * input: n-dimensional tensor (N, ∗), where ∗ means any number of additional dimensions. + * + * Parameters: + * + * * axis: dimension for calculating the index of the maximum. + * * keep_dims: indicates whether to maintain the input tensor dimension. The value is a Boolean value. + * + * Outputs: + * * output: index of the maximum input tensor on the axis. The value is a tensor. + */ + OH_NN_OPS_ARG_MAX = 54, + + /** + * Adds a dimension based on the value of axis. + * + * Inputs: + * * input: n-dimensional tensor. + * + * Parameters: + * + * * axis: dimension to be added. The value of axis can be an integer or an array of integers. + * The value range of the integer is [-n, n). + * + * Outputs: + * * output: output tensor. + */ + OH_NN_OPS_UNSQUEEZE = 55, + + /** + * Gaussian error linear unit activation function. The int quantization input is not supported. output=0.5∗input∗(1+tanh(input/2)) + * + * Inputs: + * * An n-dimensional input tensor. + * + * Outputs: + * * output: n-dimensional tensor, with the same data type and shape as the input tensor. + */ + OH_NN_OPS_GELU = 56, +} OH_NN_OperationType; + +/** + * @brief Enumerates the tensor data types. + * + * Tensors are usually used to set the input, output, and operator parameters of a model. When a tensor is used + * as the input or output of a model (or operator), set the tensor type to {@link OH_NN_TENSOR}. + * When the tensor is used as an operator parameter, select an enumerated value other than {@link OH_NN_TENSOR} as the tensor type. + * Assume that the pad parameter of the {@link OH_NN_OPS_CONV2D} operator is being set. + * You need to set the type attribute of the {@link OH_NN_Tensor} instance to {@link OH_NN_CONV2D_PAD}. + * The settings of other operator parameters are similar. The enumerated values are named + * in the format OH_NN_{Operator name}_{Attribute name}. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** This enumerated value is used when the tensor is used as the input or output of a model (or operator). */ + OH_NN_TENSOR = 0, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Add operator. */ + OH_NN_ADD_ACTIVATIONTYPE = 1, + + /** This enumerated value is used when the tensor is used as the kernel_size parameter of the AvgPool operator. */ + OH_NN_AVG_POOL_KERNEL_SIZE = 2, + /** This enumerated value is used when the tensor is used as the stride parameter of the AvgPool operator. */ + OH_NN_AVG_POOL_STRIDE = 3, + /** This enumerated value is used when the tensor is used as the pad_mode parameter of the AvgPool operator. */ + OH_NN_AVG_POOL_PAD_MODE = 4, + /** This enumerated value is used when the tensor is used as the pad parameter of the AvgPool operator. */ + OH_NN_AVG_POOL_PAD = 5, + /** This enumerated value is used when the tensor is used as the activation_type parameter of the AvgPool operator. */ + OH_NN_AVG_POOL_ACTIVATION_TYPE = 6, + + /** This enumerated value is used when the tensor is used as the eosilon parameter of the BatchNorm operator. */ + OH_NN_BATCH_NORM_EPSILON = 7, + + /** This enumerated value is used when the tensor is used as the blockSize parameter of the BatchToSpaceND operator. */ + OH_NN_BATCH_TO_SPACE_ND_BLOCKSIZE = 8, + /** This enumerated value is used when the tensor is used as the crops parameter of the BatchToSpaceND operator. */ + OH_NN_BATCH_TO_SPACE_ND_CROPS = 9, + + /** This enumerated value is used when the tensor is used as the axis parameter of the Concat operator. */ + OH_NN_CONCAT_AXIS = 10, + + /** This enumerated value is used when the tensor is used as the strides parameter of the Conv2D operator. */ + OH_NN_CONV2D_STRIDES = 11, + /** This enumerated value is used when the tensor is used as the pad parameter of the Conv2D operator. */ + OH_NN_CONV2D_PAD = 12, + /** This enumerated value is used when the tensor is used as the dilation parameter of the Conv2D operator. */ + OH_NN_CONV2D_DILATION = 13, + /** This enumerated value is used when the tensor is used as the padMode parameter of the Conv2D operator. */ + OH_NN_CONV2D_PAD_MODE = 14, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Conv2D operator. */ + OH_NN_CONV2D_ACTIVATION_TYPE = 15, + /** This enumerated value is used when the tensor is used as the group parameter of the Conv2D operator. */ + OH_NN_CONV2D_GROUP = 16, + + /** This enumerated value is used when the tensor is used as the strides parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_STRIDES = 17, + /** This enumerated value is used when the tensor is used as the pad parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_PAD = 18, + /** This enumerated value is used when the tensor is used as the dilation parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_DILATION = 19, + /** This enumerated value is used when the tensor is used as the outputPaddings parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_OUTPUT_PADDINGS = 20, + /** This enumerated value is used when the tensor is used as the padMode parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_PAD_MODE = 21, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_ACTIVATION_TYPE = 22, + /** This enumerated value is used when the tensor is used as the group parameter of the Conv2DTranspose operator. */ + OH_NN_CONV2D_TRANSPOSE_GROUP = 23, + + /** This enumerated value is used when the tensor is used as the strides parameter of the DepthwiseConv2dNative operator. */ + OH_NN_DEPTHWISE_CONV2D_NATIVE_STRIDES = 24, + /** This enumerated value is used when the tensor is used as the pad parameter of the DepthwiseConv2dNative operator. */ + OH_NN_DEPTHWISE_CONV2D_NATIVE_PAD = 25, + /** This enumerated value is used when the tensor is used as the dilation parameter of the DepthwiseConv2dNative operator. */ + OH_NN_DEPTHWISE_CONV2D_NATIVE_DILATION = 26, + /** This enumerated value is used when the tensor is used as the padMode parameter of the DepthwiseConv2dNative operator. */ + OH_NN_DEPTHWISE_CONV2D_NATIVE_PAD_MODE = 27, + /** This enumerated value is used when the tensor is used as the activationType parameter of the DepthwiseConv2dNative operator. */ + OH_NN_DEPTHWISE_CONV2D_NATIVE_ACTIVATION_TYPE = 28, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Div operator. */ + OH_NN_DIV_ACTIVATIONTYPE = 29, + + /** This enumerated value is used when the tensor is used as the mode parameter of the Eltwise operator. */ + OH_NN_ELTWISE_MODE = 30, + + /** This enumerated value is used when the tensor is used as the axis parameter of the FullConnection operator. */ + OH_NN_FULL_CONNECTION_AXIS = 31, + /** This enumerated value is used when the tensor is used as the activationType parameter of the FullConnection operator. */ + OH_NN_FULL_CONNECTION_ACTIVATIONTYPE = 32, + + /** This enumerated value is used when the tensor is used as the transposeA parameter of the Matmul operator. */ + OH_NN_MATMUL_TRANSPOSE_A = 33, + /** This enumerated value is used when the tensor is used as the transposeB parameter of the Matmul operator. */ + OH_NN_MATMUL_TRANSPOSE_B = 34, + /** This enumerated value is used when the tensor is used as the activationType parameter of the Matmul operator. */ + OH_NN_MATMUL_ACTIVATION_TYPE = 35, + + /** This enumerated value is used when the tensor is used as the kernel_size parameter of the MaxPool operator. */ + OH_NN_MAX_POOL_KERNEL_SIZE = 36, + /** This enumerated value is used when the tensor is used as the stride parameter of the MaxPool operator. */ + OH_NN_MAX_POOL_STRIDE = 37, + /** This enumerated value is used when the tensor is used as the pad_mode parameter of the MaxPool operator. */ + OH_NN_MAX_POOL_PAD_MODE = 38, + /** This enumerated value is used when the tensor is used as the pad parameter of the MaxPool operator. */ + OH_NN_MAX_POOL_PAD = 39, + /** This enumerated value is used when the tensor is used as the activation_type parameter of the MaxPool operator. */ + OH_NN_MAX_POOL_ACTIVATION_TYPE = 40, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Mul operator. */ + OH_NN_MUL_ACTIVATION_TYPE = 41, + + /** This enumerated value is used when the tensor is used as the axis parameter of the OneHot operator. */ + OH_NN_ONE_HOT_AXIS = 42, + + /** This enumerated value is used when the tensor is used as the constant_value parameter of the Pad operator. */ + OH_NN_PAD_CONSTANT_VALUE = 43, + + /** This enumerated value is used when the tensor is used as the activationType parameter of the Scale operator. */ + OH_NN_SCALE_ACTIVATIONTYPE = 44, + /** This enumerated value is used when the tensor is used as the axis parameter of the Scale operator. */ + OH_NN_SCALE_AXIS = 45, + + /** This enumerated value is used when the tensor is used as the axis parameter of the Softmax operator. */ + OH_NN_SOFTMAX_AXIS = 46, + + /** This enumerated value is used when the tensor is used as the BlockShape parameter of the SpaceToBatchND operator. */ + OH_NN_SPACE_TO_BATCH_ND_BLOCK_SHAPE = 47, + /** This enumerated value is used when the tensor is used as the Paddings parameter of the SpaceToBatchND operator. */ + OH_NN_SPACE_TO_BATCH_ND_PADDINGS = 48, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Split operator. */ + OH_NN_SPLIT_AXIS = 49, + /** This enumerated value is used when the tensor is used as the OutputNum parameter of the Split operator. */ + OH_NN_SPLIT_OUTPUT_NUM = 50, + /** This enumerated value is used when the tensor is used as the SizeSplits parameter of the Split operator. */ + OH_NN_SPLIT_SIZE_SPLITS = 51, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Squeeze operator. */ + OH_NN_SQUEEZE_AXIS = 52, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Stack operator. */ + OH_NN_STACK_AXIS = 53, + + /** This enumerated value is used when the tensor is used as the BeginMask parameter of the StridedSlice operator. */ + OH_NN_STRIDED_SLICE_BEGIN_MASK = 54, + /** This enumerated value is used when the tensor is used as the EndMask parameter of the StridedSlice operator. */ + OH_NN_STRIDED_SLICE_END_MASK = 55, + /** This enumerated value is used when the tensor is used as the EllipsisMask parameter of the StridedSlice operator. */ + OH_NN_STRIDED_SLICE_ELLIPSIS_MASK = 56, + /** This enumerated value is used when the tensor is used as the NewAxisMask parameter of the StridedSlice operator. */ + OH_NN_STRIDED_SLICE_NEW_AXIS_MASK = 57, + /** This enumerated value is used when the tensor is used as the ShrinkAxisMask parameter of the StridedSlice operator. */ + OH_NN_STRIDED_SLICE_SHRINK_AXIS_MASK = 58, + + /** This enumerated value is used when the tensor is used as the ActivationType parameter of the Sub operator. */ + OH_NN_SUB_ACTIVATIONTYPE = 59, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceMean operator. */ + OH_NN_REDUCE_MEAN_KEEP_DIMS = 60, + + /** This enumerated value is used when the tensor is used as the new_height parameter of the ResizeBilinear operator. */ + OH_NN_RESIZE_BILINEAR_NEW_HEIGHT = 61, + /** This enumerated value is used when the tensor is used as the new_width parameter of the ResizeBilinear operator. */ + OH_NN_RESIZE_BILINEAR_NEW_WIDTH = 62, + /** This enumerated value is used when the tensor is used as the preserve_aspect_ratio parameter of the ResizeBilinear operator. */ + OH_NN_RESIZE_BILINEAR_PRESERVE_ASPECT_RATIO = 63, + /** This enumerated value is used when the tensor is used as the coordinate_transform_mode parameter of the ResizeBilinear operator. */ + OH_NN_RESIZE_BILINEAR_COORDINATE_TRANSFORM_MODE = 64, + /** This enumerated value is used when the tensor is used as the exclude_outside parameter of the ResizeBilinear operator. */ + OH_NN_RESIZE_BILINEAR_EXCLUDE_OUTSIDE = 65, + + /** This enumerated value is used when the tensor is used as the beginNormAxis parameter of the LayerNorm operator. */ + OH_NN_LAYER_NORM_BEGIN_NORM_AXIS = 66, + /** This enumerated value is used when the tensor is used as the epsilon parameter of the LayerNorm operator. */ + OH_NN_LAYER_NORM_EPSILON = 67, + /** This enumerated value is used when the tensor is used as the beginParamsAxis parameter of the LayerNorm operator. */ + OH_NN_LAYER_NORM_BEGIN_PARAM_AXIS = 68, + /** This enumerated value is used when the tensor is used as the elementwiseAffine parameter of the LayerNorm operator. */ + OH_NN_LAYER_NORM_ELEMENTWISE_AFFINE = 69, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceProd operator. */ + OH_NN_REDUCE_PROD_KEEP_DIMS = 70, + + /** This enumerated value is used when the tensor is used as the keep_dims parameter of the ReduceAll operator. */ + OH_NN_REDUCE_ALL_KEEP_DIMS = 71, + + /** This enumerated value is used when the tensor is used as the src_t parameter of the QuantDTypeCast operator. */ + OH_NN_QUANT_DTYPE_CAST_SRC_T = 72, + /** This enumerated value is used when the tensor is used as the dst_t parameter of the QuantDTypeCast operator. */ + OH_NN_QUANT_DTYPE_CAST_DST_T = 73, + + /** This enumerated value is used when the tensor is used as the Sorted parameter of the Topk operator. */ + OH_NN_TOP_K_SORTED = 74, + + /** This enumerated value is used when the tensor is used as the axis parameter of the ArgMax operator. */ + OH_NN_ARG_MAX_AXIS = 75, + /** This enumerated value is used when the tensor is used as the keepDims parameter of the ArgMax operator. */ + OH_NN_ARG_MAX_KEEPDIMS = 76, + + /** This enumerated value is used when the tensor is used as the Axis parameter of the Unsqueeze operator. */ + OH_NN_UNSQUEEZE_AXIS = 77, +} OH_NN_TensorType; + +/** + * @brief This structure is used to store a 32-bit unsigned integer array. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NN_UInt32Array { + /** Pointer to the unsigned integer array */ + uint32_t *data; + /** Array length */ + uint32_t size; +} OH_NN_UInt32Array; + +/** + * @brief Quantization information. + * + * In quantization scenarios, the 32-bit floating-point data type is quantized into the fixed-point data type according to the following formula: + \f[ + q = clamp(round(\frac{r}{s}+z), q_{min}, q_{max}) + \f] + * s and z are quantization parameters, which are stored by scale and zeroPoint in {@link OH_NN_QuantParam}. + * r is a floating point number, q is the quantization result, q_min is the lower bound of the quantization result, and + * q_max is an upper bound of a quantization result. The calculation method is as follows: + * + \f[ + \text{clamp}(x,min,max) = + \begin{cases} + q_{min} = -(1 << (numBits - 1)) \\ + q_{max} = (1 << (numBits - 1)) \\ + \end{cases} + \f] + * The clamp function is defined as follows: + \f[ + \text{clamp}(x,min,max) = + \begin{cases} + \text{max} & \text{ if } x > \text{ max } \\ + \text{min} & \text{ if } x < \text{ min } \\ + x & \text{ otherwise } \\ + \end{cases} + \f] + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NN_QuantParam { + /** Specifies the length of the numBits, scale, and zeroPoint arrays. In the per-layer quantization scenario, + * quantCount is usually set to 1. That is, all channels of a tensor share a set of quantization parameters. + * In the per-channel quantization scenario, quantCount is usually the same as the number of tensor channels, + * and each channel uses its own quantization parameters. + */ + uint32_t quantCount; + /** Number of quantization bits */ + const uint32_t *numBits; + /** Pointer to the scale data in the quantization formula */ + const double *scale; + /** Pointer to the zero point data in the quantization formula */ + const int32_t *zeroPoint; +} OH_NN_QuantParam; + +/** + * @brief Defines the tensor structure. + * + * It is usually used to construct data nodes and operator parameters in a model graph. When constructing a tensor, + * you need to specify the data type, number of dimensions, dimension information, and quantization information. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NN_Tensor { + /** Data type of the specified tensor. The value must be an enumerated value of {@link OH_NN_DataType}. */ + OH_NN_DataType dataType; + /** Number of dimensions of the specified tensor */ + uint32_t dimensionCount; + /** Dimension information (shape) of the specified tensor*/ + const int32_t *dimensions; + /** Quantization information of the specified tensor. The data type must be {@link OH_NN_QuantParam}. */ + const OH_NN_QuantParam *quantParam; + /** Specifies the tensor type. The value of type is related to the tensor usage. + * When the tensor is used as the input or output of the model, set type to {@link OH_NN_TENSOR}. + * When a tensor is used as an operator parameter, select any enumerated value except {@link OH_NN_TENSOR} from {@link OH_NN_TensorType}. + */ + OH_NN_TensorType type; +} OH_NN_Tensor; + +/** + * @brief Defines the memory structure. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NN_Memory { + /** Pointer to the shared memory. The shared memory is usually allocated by the underlying hardware driver. */ + void * const data; + /** Records the length of the shared memory, in bytes. */ + const size_t length; +} OH_NN_Memory; + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** @} */ +#endif // NEURAL_NETWORK_RUNTIME_TYPE_H diff --git a/arkui/ace_engine/native/BUILD.gn b/arkui/ace_engine/native/BUILD.gn new file mode 100644 index 000000000..6ce3291ac --- /dev/null +++ b/arkui/ace_engine/native/BUILD.gn @@ -0,0 +1,74 @@ +# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//foundation/arkui/ace_engine/ace_config.gni") + +if (!is_cross_platform_build) { + ohos_ndk_headers("ace_header") { + dest_dir = "$ndk_headers_out_dir/ace/xcomponent/" + sources = [ + "native_interface_xcomponent.h", + "native_xcomponent_key_event.h", + ] + } + + ohos_ndk_library("libace_ndk") { + ndk_description_file = "./libace.ndk.json" + min_compact_version = "7" + output_name = "ace_ndk" + } +} + +ohos_shared_library("ace_ndk") { + if (current_os == "ohos") { + sanitize = { + integer_overflow = true + boundary_sanitize = true + debug = ace_sanitize_debug + } + } + include_dirs = [ + "//foundation/arkui/ace_engine", + "//foundation/arkui/ace_engine/frameworks", + "//foundation/arkui/ace_engine/interfaces/native", + ] + + sources = [ + "//foundation/arkui/ace_engine/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.cpp", + "native_interface_xcomponent.cpp", + ] + + deps = [ "//third_party/bounds_checking_function:libsec_shared" ] + + cflags_cc = [ "-Wno-missing-braces" ] + + if (target_os == "ohos") { + sources += [ "$ace_root/adapter/ohos/osal/log_wrapper.cpp" ] + deps += [ ":libace_ndk" ] + external_deps = [ "hilog:libhilog" ] + version_script = + get_label_info(":libace_ndk", "target_gen_dir") + "/" + + get_label_info(":libace_ndk", "name") + version_script_suffix + } else if (target_os == "android") { + sources += [ "$ace_root/adapter/android/osal/log_wrapper.cpp" ] + libs = [ "log" ] + } + + subsystem_name = ace_engine_subsystem + part_name = ace_engine_part +} + +group("ace_packages_ndk") { + deps = [ ":ace_ndk" ] +} diff --git a/arkui/ace_engine/native/libace.ndk.json b/arkui/ace_engine/native/libace.ndk.json new file mode 100644 index 000000000..bcc196abd --- /dev/null +++ b/arkui/ace_engine/native/libace.ndk.json @@ -0,0 +1,82 @@ +[ + { + "first_introduced": "8", + "name": "OH_NativeXComponent_GetXComponentId" + }, + { + "first_introduced": "8", + "name": "OH_NativeXComponent_GetXComponentSize" + }, + { + "first_introduced": "8", + "name": "OH_NativeXComponent_RegisterCallback" + }, + { + "first_introduced": "8", + "name": "OH_NativeXComponent_GetTouchEvent" + }, + { + "first_introduced": "8", + "name": "OH_NativeXComponent_GetXComponentOffset" + }, + { + "first_introduced": "9", + "name": "OH_NativeXComponent_GetMouseEvent" + }, + { + "first_introduced": "9", + "name": "OH_NativeXComponent_RegisterMouseEventCallback" + }, + { + "first_introduced": "9", + "name": "OH_NativeXComponent_GetTouchPointToolType" + }, + { + "first_introduced": "9", + "name": "OH_NativeXComponent_GetTouchPointTiltX" + }, + { + "first_introduced": "9", + "name": "OH_NativeXComponent_GetTouchPointTiltY" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_RegisterFocusEventCallback" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_RegisterKeyEventCallback" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_RegisterBlurEventCallback" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetKeyEvent" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetKeyEventAction" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetKeyEventCode" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetKeyEventSourceType" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetKeyEventDeviceId" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetKeyEventTimestamp" + }, + { + "first_introduced": "10", + "name": "OH_NativeXComponent_GetHistoricalPoints" + } +] \ No newline at end of file diff --git a/arkui/ace_engine/native/native_interface_xcomponent.cpp b/arkui/ace_engine/native/native_interface_xcomponent.cpp new file mode 100644 index 000000000..6d2fc3903 --- /dev/null +++ b/arkui/ace_engine/native/native_interface_xcomponent.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "native_interface_xcomponent.h" + +#include "frameworks/core/components/xcomponent/native_interface_xcomponent_impl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t OH_NativeXComponent_GetXComponentId(OH_NativeXComponent* component, char* id, uint64_t* size) +{ + if ((component == nullptr) || (id == nullptr) || (size == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + if (((*size) == 0) || ((*size) > (OH_XCOMPONENT_ID_LEN_MAX + 1))) { + LOGE("The referenced value of 'size' should be in the range (0, OH_XCOMPONENT_ID_LEN_MAX + 1]"); + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetXComponentId(id, size); +} + +int32_t OH_NativeXComponent_GetXComponentSize( + OH_NativeXComponent* component, const void* window, uint64_t* width, uint64_t* height) +{ + if ((component == nullptr) || (window == nullptr) || (width == nullptr) || (height == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetXComponentSize(window, width, height); +} + +int32_t OH_NativeXComponent_GetXComponentOffset( + OH_NativeXComponent* component, const void* window, double* x, double* y) +{ + if ((component == nullptr) || (window == nullptr) || (x == nullptr) || (y == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetXComponentOffset(window, x, y); +} + +int32_t OH_NativeXComponent_GetTouchEvent( + OH_NativeXComponent* component, const void* window, OH_NativeXComponent_TouchEvent* touchEvent) +{ + if ((component == nullptr) || (window == nullptr) || (touchEvent == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetTouchEvent(window, touchEvent); +} + +int32_t OH_NativeXComponent_GetTouchPointToolType( + OH_NativeXComponent* component, uint32_t pointIndex, OH_NativeXComponent_TouchPointToolType* toolType) +{ + if ((component == nullptr) || (toolType == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetToolType(pointIndex, toolType); +} + +int32_t OH_NativeXComponent_GetTouchPointTiltX(OH_NativeXComponent* component, uint32_t pointIndex, float* tiltX) +{ + if ((component == nullptr) || (tiltX == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetTiltX(pointIndex, tiltX); +} + +int32_t OH_NativeXComponent_GetTouchPointTiltY(OH_NativeXComponent* component, uint32_t pointIndex, float* tiltY) +{ + if ((component == nullptr) || (tiltY == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetTiltY(pointIndex, tiltY); +} + +int32_t OH_NativeXComponent_GetHistoricalPoints(OH_NativeXComponent* component, const void* window, + int32_t* size, OH_NativeXComponent_HistoricalPoint** historicalPoints) +{ + if ((component == nullptr) || (window == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetHistoryPoints(window, size, historicalPoints); +} + +int32_t OH_NativeXComponent_GetMouseEvent( + OH_NativeXComponent* component, const void* window, OH_NativeXComponent_MouseEvent* mouseEvent) +{ + if ((component == nullptr) || (window == nullptr) || (mouseEvent == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetMouseEvent(window, mouseEvent); +} + +int32_t OH_NativeXComponent_RegisterCallback(OH_NativeXComponent* component, OH_NativeXComponent_Callback* callback) +{ + if ((component == nullptr) || (callback == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->RegisterCallback(callback); +} + +int32_t OH_NativeXComponent_RegisterMouseEventCallback( + OH_NativeXComponent* component, OH_NativeXComponent_MouseEvent_Callback* callback) +{ + if ((component == nullptr) || (callback == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->RegisterMouseEventCallback(callback); +} + +int32_t OH_NativeXComponent_RegisterFocusEventCallback( + OH_NativeXComponent* component, void (*callback)(OH_NativeXComponent* component, void* window)) +{ + if ((component == nullptr) || (callback == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->RegisterFocusEventCallback(callback); +} + +int32_t OH_NativeXComponent_RegisterKeyEventCallback( + OH_NativeXComponent* component, void (*callback)(OH_NativeXComponent* component, void* window)) +{ + if ((component == nullptr) || (callback == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->RegisterKeyEventCallback(callback); +} + +int32_t OH_NativeXComponent_RegisterBlurEventCallback( + OH_NativeXComponent* component, void (*callback)(OH_NativeXComponent* component, void* window)) +{ + if ((component == nullptr) || (callback == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->RegisterBlurEventCallback(callback); +} + +int32_t OH_NativeXComponent_GetKeyEvent(OH_NativeXComponent* component, OH_NativeXComponent_KeyEvent** keyEvent) +{ + if ((component == nullptr) || (keyEvent == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetKeyEvent(keyEvent); +} + +int32_t OH_NativeXComponent_GetKeyEventAction( + OH_NativeXComponent_KeyEvent* keyEvent, OH_NativeXComponent_KeyAction* action) +{ + if ((keyEvent == nullptr) || (action == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + (*action) = keyEvent->action; + return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; +} + +int32_t OH_NativeXComponent_GetKeyEventCode(OH_NativeXComponent_KeyEvent* keyEvent, OH_NativeXComponent_KeyCode* code) +{ + if ((keyEvent == nullptr) || (code == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + (*code) = keyEvent->code; + return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; +} + +int32_t OH_NativeXComponent_GetKeyEventSourceType( + OH_NativeXComponent_KeyEvent* keyEvent, OH_NativeXComponent_EventSourceType* sourceType) +{ + if ((keyEvent == nullptr) || (sourceType == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + (*sourceType) = keyEvent->sourceType; + return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; +} + +int32_t OH_NativeXComponent_GetKeyEventDeviceId(OH_NativeXComponent_KeyEvent* keyEvent, int64_t* deviceId) +{ + if ((keyEvent == nullptr) || (deviceId == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + (*deviceId) = keyEvent->deviceId; + return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; +} + +int32_t OH_NativeXComponent_GetKeyEventTimestamp(OH_NativeXComponent_KeyEvent* keyEvent, int64_t* timestamp) +{ + if ((keyEvent == nullptr) || (timestamp == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + (*timestamp) = keyEvent->timestamp; + return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; +} +#ifdef __cplusplus +}; +#endif diff --git a/arkui/ace_engine/native/native_interface_xcomponent.h b/arkui/ace_engine/native/native_interface_xcomponent.h new file mode 100644 index 000000000..fbc9a7f71 --- /dev/null +++ b/arkui/ace_engine/native/native_interface_xcomponent.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup OH_NativeXComponent Native XComponent + * @{ + * + * @brief Describes the surface and touch event held by the ArkUI XComponent, which can be used for the EGL/OpenGL ES\n + * and media data input and displayed on the ArkUI XComponent. + * + * @since 8 + * @version 1.0 + */ + +/** + * @file native_interface_xcomponent.h + * + * @brief Declares APIs for accessing a Native XComponent. + * + * @since 8 + * @version 1.0 + */ + +#ifndef _NATIVE_INTERFACE_XCOMPONENT_H_ +#define _NATIVE_INTERFACE_XCOMPONENT_H_ + +#include +#include +#include + +#include "native_xcomponent_key_event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define OH_NATIVE_XCOMPONENT_OBJ ("__NATIVE_XCOMPONENT_OBJ__") + +const uint32_t OH_XCOMPONENT_ID_LEN_MAX = 128; +const uint32_t OH_MAX_TOUCH_POINTS_NUMBER = 10; + +/** + * @brief Enumerates the API access states. + * + * @since 8 + * @version 1.0 + */ +enum { + /** Successful. */ + OH_NATIVEXCOMPONENT_RESULT_SUCCESS = 0, + /** Failed. */ + OH_NATIVEXCOMPONENT_RESULT_FAILED = -1, + /** Invalid parameters. */ + OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER = -2, +}; + +typedef enum { + /** Trigger a touch event when a finger is pressed. */ + OH_NATIVEXCOMPONENT_DOWN = 0, + /** Trigger a touch event when a finger is lifted. */ + OH_NATIVEXCOMPONENT_UP, + /** Trigger a touch event when a finger moves on the screen in pressed state. */ + OH_NATIVEXCOMPONENT_MOVE, + /** Trigger an event when a touch event is canceled. */ + OH_NATIVEXCOMPONENT_CANCEL, + /** Invalid touch type. */ + OH_NATIVEXCOMPONENT_UNKNOWN, +} OH_NativeXComponent_TouchEventType; + +/** + * @brief Represents the touch point tool type. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Indicates invalid tool type. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN = 0, + /** Indicates a finger. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_FINGER, + /** Indicates a stylus. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_PEN, + /** Indicates a eraser. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_RUBBER, + /** Indicates a brush. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_BRUSH, + /** Indicates a pencil. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_PENCIL, + /** Indicates a brush. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_AIRBRUSH, + /** Indicates a mouse. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_MOUSE, + /** Indicates a lens. */ + OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS, +} OH_NativeXComponent_TouchPointToolType; + +/** + * @brief Represents the touch event source type. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + /** Indicates an unknown input source type. */ + OH_NATIVEXCOMPONENT_SOURCE_TYPE_UNKNOWN = 0, + /** Indicates that the input source generates a mouse multi-touch event. */ + OH_NATIVEXCOMPONENT_SOURCE_TYPE_MOUSE, + /** Indicates that the input source generates a touchscreen multi-touch event. */ + OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHSCREEN, + /** Indicates that the input source generates a touchpad multi-touch event. */ + OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHPAD, + /** Indicates that the input source generates a joystick multi-touch event. */ + OH_NATIVEXCOMPONENT_SOURCE_TYPE_JOYSTICK, + /** + * @brief Indicates that the input source generates a keyboard event. + * + * @since 10 + * @version 1.0 + */ + OH_NATIVEXCOMPONENT_SOURCE_TYPE_KEYBOARD, +} OH_NativeXComponent_EventSourceType; + +/** + * @brief Represents the mouse event action. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + OH_NATIVEXCOMPONENT_MOUSE_NONE = 0, + OH_NATIVEXCOMPONENT_MOUSE_PRESS, + OH_NATIVEXCOMPONENT_MOUSE_RELEASE, + OH_NATIVEXCOMPONENT_MOUSE_MOVE, +} OH_NativeXComponent_MouseEventAction; + +/** + * @brief Represents the mouse event button. + * + * @since 9 + * @version 1.0 + */ +typedef enum { + OH_NATIVEXCOMPONENT_NONE_BUTTON = 0, + OH_NATIVEXCOMPONENT_LEFT_BUTTON = 0x01, + OH_NATIVEXCOMPONENT_RIGHT_BUTTON = 0x02, + OH_NATIVEXCOMPONENT_MIDDLE_BUTTON = 0x04, + OH_NATIVEXCOMPONENT_BACK_BUTTON = 0x08, + OH_NATIVEXCOMPONENT_FORWARD_BUTTON = 0x10, +} OH_NativeXComponent_MouseEventButton; + +/** + * @brief Represents the source tool type of TouchEvent + * + * @since 10 + * @version 1.0 + */ +typedef enum { + OH_NATIVEXCOMPONENT_SOURCETOOL_UNKNOWN = 0, + OH_NATIVEXCOMPONENT_SOURCETOOL_FINGER = 1, + OH_NATIVEXCOMPONENT_SOURCETOOL_PEN = 2, + OH_NATIVEXCOMPONENT_SOURCETOOL_RUBBER = 3, + OH_NATIVEXCOMPONENT_SOURCETOOL_BRUSH = 4, + OH_NATIVEXCOMPONENT_SOURCETOOL_PENCIL = 5, + OH_NATIVEXCOMPONENT_SOURCETOOL_AIRBRUSH = 6, + OH_NATIVEXCOMPONENT_SOURCETOOL_MOUSE = 7, + OH_NATIVEXCOMPONENT_SOURCETOOL_LENS = 8, + OH_NATIVEXCOMPONENT_SOURCETOOL_TOUCHPAD = 9, +} OH_NativeXComponent_TouchEvent_SourceTool; + +typedef struct { + /** Unique identifier of a finger. */ + int32_t id; + /** X coordinate of the touch point relative to the left edge of the screen. */ + float screenX; + /** Y coordinate of the touch point relative to the upper edge of the screen. */ + float screenY; + /** X coordinate of the touch point relative to the left edge of the element to touch. */ + float x; + /** Y coordinate of the touch point relative to the upper edge of the element to touch. */ + float y; + /** Touch type of the touch event. */ + OH_NativeXComponent_TouchEventType type; + /** Contact area between the finger pad and the screen. */ + double size; + /** Pressure of the current touch event. */ + float force; + /** Timestamp of the current touch event. */ + int64_t timeStamp; + /** The angle betweenprojection on plane-X-Y and axis-Z of the current touch event. */ + float titlX; + /** The angle betweenprojection on plane-Y-Z and axis-Z of the current touch event. */ + float titlY; + /** The sourceTool of the current touch event. */ + OH_NativeXComponent_TouchEvent_SourceTool sourceTool; +} OH_NativeXComponent_HistoricalPoint; + +typedef struct { + /** Unique identifier of a finger. */ + int32_t id; + /** X coordinate of the touch point relative to the left edge of the screen. */ + float screenX; + /** Y coordinate of the touch point relative to the upper edge of the screen. */ + float screenY; + /** X coordinate of the touch point relative to the left edge of the element to touch. */ + float x; + /** Y coordinate of the touch point relative to the upper edge of the element to touch. */ + float y; + /** Touch type of the touch event. */ + OH_NativeXComponent_TouchEventType type; + /** Contact area between the finger pad and the screen. */ + double size; + /** Pressure of the current touch event. */ + float force; + /** Timestamp of the current touch event. */ + int64_t timeStamp; + /** Whether the current point is pressed. */ + bool isPressed; +} OH_NativeXComponent_TouchPoint; + +// Represents the touch point information. +typedef struct { + /** Unique identifier of a finger. */ + int32_t id; + /** X coordinate of the touch point relative to the left edge of the screen. */ + float screenX; + /** Y coordinate of the touch point relative to the upper edge of the screen. */ + float screenY; + /** X coordinate of the touch point relative to the left edge of the element to touch. */ + float x; + /** Y coordinate of the touch point relative to the upper edge of the element to touch. */ + float y; + /** Touch type of the touch event. */ + OH_NativeXComponent_TouchEventType type; + /** Contact area between the finger pad and the screen. */ + double size; + /** Pressure of the current touch event. */ + float force; + /** ID of the device where the current touch event is generated. */ + int64_t deviceId; + /** Timestamp of the current touch event. */ + int64_t timeStamp; + /** Array of the current touch points. */ + OH_NativeXComponent_TouchPoint touchPoints[OH_MAX_TOUCH_POINTS_NUMBER]; + /** Number of current touch points. */ + uint32_t numPoints; +} OH_NativeXComponent_TouchEvent; + +/** + * @brief Represents the mouse event information. + * + * @since 9 + * @version 1.0 + */ +typedef struct { + /** X coordinate of the mouse point relative to the left edge of the element to mouse. */ + float x; + /** Y coordinate of the mouse point relative to the upper edge of the element to mouse. */ + float y; + /** X coordinate of the mouse point relative to the left edge of the screen. */ + float screenX; + /** Y coordinate of the mouse point relative to the upper edge of the screen. */ + float screenY; + /** Timestamp of the current mouse event. */ + int64_t timestamp; + /** Mouse event action. */ + OH_NativeXComponent_MouseEventAction action; + /** Mouse event button. */ + OH_NativeXComponent_MouseEventButton button; +} OH_NativeXComponent_MouseEvent; + +/** + * @brief Provides an encapsulated OH_NativeXComponent instance. + * + * @since 8 + * @version 1.0 + */ +typedef struct OH_NativeXComponent OH_NativeXComponent; + +/** + * @brief Registers the surface lifecycle and touch event callbacks. + * + * @since 8 + * @version 1.0 + */ +typedef struct OH_NativeXComponent_Callback { + /** Called when the surface is created. */ + void (*OnSurfaceCreated)(OH_NativeXComponent* component, void* window); + /** Called when the surface is changed. */ + void (*OnSurfaceChanged)(OH_NativeXComponent* component, void* window); + /** Called when the surface is destroyed. */ + void (*OnSurfaceDestroyed)(OH_NativeXComponent* component, void* window); + /** Called when a touch event is triggered. */ + void (*DispatchTouchEvent)(OH_NativeXComponent* component, void* window); +} OH_NativeXComponent_Callback; + +/** + * @brief Registers the mouse event callbacks. + * + * @since 9 + * @version 1.0 + */ +typedef struct OH_NativeXComponent_MouseEvent_Callback { + /** Called when a mouse event is triggered. */ + void (*DispatchMouseEvent)(OH_NativeXComponent* component, void* window); + /** Called when a hover event is triggered. */ + void (*DispatchHoverEvent)(OH_NativeXComponent* component, bool isHover); +} OH_NativeXComponent_MouseEvent_Callback; + +struct OH_NativeXComponent_KeyEvent; +/** + * @brief Provides an encapsulated OH_NativeXComponent_KeyEvent instance. + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_NativeXComponent_KeyEvent OH_NativeXComponent_KeyEvent; + +/** + * @brief Obtains the ID of the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param id Indicates the char buffer to keep the ID of this OH_NativeXComponent instance.\n + * Notice that a null-terminator will be appended to the char buffer, so the size of the\n + * char buffer should be at least as large as the size of the real id length plus 1.\n + * It is recommended that the size of the char buffer be [OH_XCOMPONENT_ID_LEN_MAX + 1]. + * @param size Indicates the pointer to the length of id, which you can set and receive. + * @return Returns the status code of the execution. + * @since 8 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetXComponentId(OH_NativeXComponent* component, char* id, uint64_t* size); + +/** + * @brief Obtains the size of the surface held by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param window Indicates the native window handler. + * @param width Indicates the pointer to the width of the current surface. + * @param height Indicates the pointer to the height of the current surface. + * @return Returns the status code of the execution. + * @since 8 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetXComponentSize( + OH_NativeXComponent* component, const void* window, uint64_t* width, uint64_t* height); + +/** + * @brief Obtains the offset of the surface held by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param window Indicates the native window handler. + * @param x Indicates the pointer to the x coordinate of the current surface. + * @param y Indicates the pointer to the y coordinate of the current surface. + * @return Returns the status code of the execution. + * @since 8 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetXComponentOffset( + OH_NativeXComponent* component, const void* window, double* x, double* y); + +/** + * @brief Obtains the touch event dispatched by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param window Indicates the native window handler. + * @param touchEvent Indicates the pointer to the current touch event. + * @return Returns the status code of the execution. + * @since 8 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetTouchEvent( + OH_NativeXComponent* component, const void* window, OH_NativeXComponent_TouchEvent* touchEvent); + +/** + * @brief Obtains the touch pointer tool type by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param pointIndex Indicates the pointer index in the touchPoints. + * @param toolType Indicates the tool Type of the pointer. + * @return Returns the status code of the execution. + * @since 9 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetTouchPointToolType( + OH_NativeXComponent* component, uint32_t pointIndex, OH_NativeXComponent_TouchPointToolType* toolType); + +/** + * @brief Obtains the touch pointer tiltX by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param pointIndex Indicates the pointer index in the touchPoints. + * @param tiltX Indicates the x tilt of the pointer. + * @return Returns the status code of the execution. + * @since 9 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetTouchPointTiltX(OH_NativeXComponent* component, uint32_t pointIndex, float* tiltX); + +/** + * @brief Obtains the touch pointer tiltX by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param pointIndex Indicates the pointer index in the touchPoints. + * @param tiltY Indicates the y tilt of the pointer. + * @return Returns the status code of the execution. + * @since 9 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetTouchPointTiltY(OH_NativeXComponent* component, uint32_t pointIndex, float* tiltY); + +/** + * @brief Obtains the touch event dispatched by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param window Indicates the native window handler. + * @param historicalPoints Indicates the pointer to the current historicalPoints. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetHistoricalPoints(OH_NativeXComponent* component, const void* window, + int32_t* size, OH_NativeXComponent_HistoricalPoint** historicalPoints); + +/** + * @brief Obtains the mouse event dispatched by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param window Indicates the native window handler. + * @param mouseEvent Indicates the pointer to the current mouse event. + * @return Returns the status code of the execution. + * @since 9 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetMouseEvent( + OH_NativeXComponent* component, const void* window, OH_NativeXComponent_MouseEvent* mouseEvent); + +/** + * @brief Registers a callback for this OH_NativeXComponent instance. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param callback Indicates the pointer to a surface lifecycle and touch event callback. + * @return Returns the status code of the execution. + * @since 8 + * @version 1.0 + */ +int32_t OH_NativeXComponent_RegisterCallback(OH_NativeXComponent* component, OH_NativeXComponent_Callback* callback); + +/** + * @brief Registers a callback for this OH_NativeXComponent instance. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param callback Indicates the pointer to a mouse event callback. + * @return Returns the status code of the execution. + * @since 9 + * @version 1.0 + */ +int32_t OH_NativeXComponent_RegisterMouseEventCallback( + OH_NativeXComponent* component, OH_NativeXComponent_MouseEvent_Callback* callback); + +/** + * @brief Registers a callback for this OH_NativeXComponent instance. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param callback Indicates the pointer to a focus event callback. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_RegisterFocusEventCallback( + OH_NativeXComponent* component, void (*callback)(OH_NativeXComponent* component, void* window)); + +/** + * @brief Registers a callback for this OH_NativeXComponent instance. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param callback Indicates the pointer to a key event callback. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_RegisterKeyEventCallback( + OH_NativeXComponent* component, void (*callback)(OH_NativeXComponent* component, void* window)); + +/** + * @brief Registers a callback for this OH_NativeXComponent instance. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param callback Indicates the pointer to a blur event callback. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_RegisterBlurEventCallback( + OH_NativeXComponent* component, void (*callback)(OH_NativeXComponent* component, void* window)); + +/** + * @brief Obtains the key event dispatched by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param keyEvent Indicates the pointer to pointer of OH_NativeXComponent_KeyEvent instance. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetKeyEvent(OH_NativeXComponent* component, OH_NativeXComponent_KeyEvent** keyEvent); + +/** + * @brief Obtains the action of the key event. + * + * @param keyEvent Indicates the pointer to this OH_NativeXComponent_KeyEvent instance. + * @param action Indicates the action of the OH_NativeXComponent_KeyEvent instance. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetKeyEventAction( + OH_NativeXComponent_KeyEvent* keyEvent, OH_NativeXComponent_KeyAction* action); + +/** + * @brief Obtains the keyCode of the key event. + * + * @param keyEvent Indicates the pointer to this OH_NativeXComponent_KeyEvent instance. + * @param code Indicates the keyCode of the OH_NativeXComponent_KeyEvent instance. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetKeyEventCode(OH_NativeXComponent_KeyEvent* keyEvent, OH_NativeXComponent_KeyCode* code); + +/** + * @brief Obtains the sourceType of the key event. + * + * @param keyEvent Indicates the pointer to this OH_NativeXComponent_KeyEvent instance. + * @param sourceType Indicates the sourceType of the OH_NativeXComponent_KeyEvent instance. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetKeyEventSourceType( + OH_NativeXComponent_KeyEvent* keyEvent, OH_NativeXComponent_EventSourceType* sourceType); + +/** + * @brief Obtains the deviceId of the key event. + * + * @param keyEvent Indicates the pointer to this OH_NativeXComponent_KeyEvent instance. + * @param deviceId Indicates the deviceId of the OH_NativeXComponent_KeyEvent instance. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetKeyEventDeviceId(OH_NativeXComponent_KeyEvent* keyEvent, int64_t* deviceId); + +/** + * @brief Obtains the timestamp of the key event. + * + * @param keyEvent Indicates the pointer to this OH_NativeXComponent_KeyEvent instance. + * @param timestamp Indicates the timestamp of the OH_NativeXComponent_KeyEvent instance. + * @return Returns the status code of the execution. + * @since 10 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetKeyEventTimestamp(OH_NativeXComponent_KeyEvent* keyEvent, int64_t* timestamp); + +#ifdef __cplusplus +}; +#endif +#endif // _NATIVE_INTERFACE_XCOMPONENT_H_ diff --git a/arkui/ace_engine/native/native_xcomponent_key_event.h b/arkui/ace_engine/native/native_xcomponent_key_event.h new file mode 100644 index 000000000..5445692b0 --- /dev/null +++ b/arkui/ace_engine/native/native_xcomponent_key_event.h @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup OH_NativeXComponent Native XComponent + * @{ + */ + +/** + * @file native_xcomponent_key_event.h + * + * @brief Declares enums for key event of Native XComponent. + * + * @since 10 + * @version 1.0 + */ + +#ifndef _NATIVE_INTERFACE_XCOMPONENT_KEY_EVENT_H_ +#define _NATIVE_INTERFACE_XCOMPONENT_KEY_EVENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Represents the key event code. + * + * @since 10 + * @version 1.0 + */ +typedef enum { + KEY_UNKNOWN = -1, + KEY_FN = 0, + KEY_HOME = 1, + KEY_BACK = 2, + KEY_MEDIA_PLAY_PAUSE = 10, + KEY_MEDIA_STOP = 11, + KEY_MEDIA_NEXT = 12, + KEY_MEDIA_PREVIOUS = 13, + KEY_MEDIA_REWIND = 14, + KEY_MEDIA_FAST_FORWARD = 15, + KEY_VOLUME_UP = 16, + KEY_VOLUME_DOWN = 17, + KEY_POWER = 18, + KEY_CAMERA = 19, + KEY_VOLUME_MUTE = 22, + KEY_MUTE = 23, + KEY_BRIGHTNESS_UP = 40, + KEY_BRIGHTNESS_DOWN = 41, + KEY_0 = 2000, + KEY_1 = 2001, + KEY_2 = 2002, + KEY_3 = 2003, + KEY_4 = 2004, + KEY_5 = 2005, + KEY_6 = 2006, + KEY_7 = 2007, + KEY_8 = 2008, + KEY_9 = 2009, + KEY_STAR = 2010, + KEY_POUND = 2011, + KEY_DPAD_UP = 2012, + KEY_DPAD_DOWN = 2013, + KEY_DPAD_LEFT = 2014, + KEY_DPAD_RIGHT = 2015, + KEY_DPAD_CENTER = 2016, + KEY_A = 2017, + KEY_B = 2018, + KEY_C = 2019, + KEY_D = 2020, + KEY_E = 2021, + KEY_F = 2022, + KEY_G = 2023, + KEY_H = 2024, + KEY_I = 2025, + KEY_J = 2026, + KEY_K = 2027, + KEY_L = 2028, + KEY_M = 2029, + KEY_N = 2030, + KEY_O = 2031, + KEY_P = 2032, + KEY_Q = 2033, + KEY_R = 2034, + KEY_S = 2035, + KEY_T = 2036, + KEY_U = 2037, + KEY_V = 2038, + KEY_W = 2039, + KEY_X = 2040, + KEY_Y = 2041, + KEY_Z = 2042, + KEY_COMMA = 2043, + KEY_PERIOD = 2044, + KEY_ALT_LEFT = 2045, + KEY_ALT_RIGHT = 2046, + KEY_SHIFT_LEFT = 2047, + KEY_SHIFT_RIGHT = 2048, + KEY_TAB = 2049, + KEY_SPACE = 2050, + KEY_SYM = 2051, + KEY_EXPLORER = 2052, + KEY_ENVELOPE = 2053, + KEY_ENTER = 2054, + KEY_DEL = 2055, + KEY_GRAVE = 2056, + KEY_MINUS = 2057, + KEY_EQUALS = 2058, + KEY_LEFT_BRACKET = 2059, + KEY_RIGHT_BRACKET = 2060, + KEY_BACKSLASH = 2061, + KEY_SEMICOLON = 2062, + KEY_APOSTROPHE = 2063, + KEY_SLASH = 2064, + KEY_AT = 2065, + KEY_PLUS = 2066, + KEY_MENU = 2067, + KEY_PAGE_UP = 2068, + KEY_PAGE_DOWN = 2069, + KEY_ESCAPE = 2070, + KEY_FORWARD_DEL = 2071, + KEY_CTRL_LEFT = 2072, + KEY_CTRL_RIGHT = 2073, + KEY_CAPS_LOCK = 2074, + KEY_SCROLL_LOCK = 2075, + KEY_META_LEFT = 2076, + KEY_META_RIGHT = 2077, + KEY_FUNCTION = 2078, + KEY_SYSRQ = 2079, + KEY_BREAK = 2080, + KEY_MOVE_HOME = 2081, + KEY_MOVE_END = 2082, + KEY_INSERT = 2083, + KEY_FORWARD = 2084, + KEY_MEDIA_PLAY = 2085, + KEY_MEDIA_PAUSE = 2086, + KEY_MEDIA_CLOSE = 2087, + KEY_MEDIA_EJECT = 2088, + KEY_MEDIA_RECORD = 2089, + KEY_F1 = 2090, + KEY_F2 = 2091, + KEY_F3 = 2092, + KEY_F4 = 2093, + KEY_F5 = 2094, + KEY_F6 = 2095, + KEY_F7 = 2096, + KEY_F8 = 2097, + KEY_F9 = 2098, + KEY_F10 = 2099, + KEY_F11 = 2100, + KEY_F12 = 2101, + KEY_NUM_LOCK = 2102, + KEY_NUMPAD_0 = 2103, + KEY_NUMPAD_1 = 2104, + KEY_NUMPAD_2 = 2105, + KEY_NUMPAD_3 = 2106, + KEY_NUMPAD_4 = 2107, + KEY_NUMPAD_5 = 2108, + KEY_NUMPAD_6 = 2109, + KEY_NUMPAD_7 = 2110, + KEY_NUMPAD_8 = 2111, + KEY_NUMPAD_9 = 2112, + KEY_NUMPAD_DIVIDE = 2113, + KEY_NUMPAD_MULTIPLY = 2114, + KEY_NUMPAD_SUBTRACT = 2115, + KEY_NUMPAD_ADD = 2116, + KEY_NUMPAD_DOT = 2117, + KEY_NUMPAD_COMMA = 2118, + KEY_NUMPAD_ENTER = 2119, + KEY_NUMPAD_EQUALS = 2120, + KEY_NUMPAD_LEFT_PAREN = 2121, + KEY_NUMPAD_RIGHT_PAREN = 2122, + KEY_VIRTUAL_MULTITASK = 2210, + KEY_SLEEP = 2600, + KEY_ZENKAKU_HANKAKU = 2601, + KEY_102ND = 2602, + KEY_RO = 2603, + KEY_KATAKANA = 2604, + KEY_HIRAGANA = 2605, + KEY_HENKAN = 2606, + KEY_KATAKANA_HIRAGANA = 2607, + KEY_MUHENKAN = 2608, + KEY_LINEFEED = 2609, + KEY_MACRO = 2610, + KEY_NUMPAD_PLUSMINUS = 2611, + KEY_SCALE = 2612, + KEY_HANGUEL = 2613, + KEY_HANJA = 2614, + KEY_YEN = 2615, + KEY_STOP = 2616, + KEY_AGAIN = 2617, + KEY_PROPS = 2618, + KEY_UNDO = 2619, + KEY_COPY = 2620, + KEY_OPEN = 2621, + KEY_PASTE = 2622, + KEY_FIND = 2623, + KEY_CUT = 2624, + KEY_HELP = 2625, + KEY_CALC = 2626, + KEY_FILE = 2627, + KEY_BOOKMARKS = 2628, + KEY_NEXT = 2629, + KEY_PLAYPAUSE = 2630, + KEY_PREVIOUS = 2631, + KEY_STOPCD = 2632, + KEY_CONFIG = 2634, + KEY_REFRESH = 2635, + KEY_EXIT = 2636, + KEY_EDIT = 2637, + KEY_SCROLLUP = 2638, + KEY_SCROLLDOWN = 2639, + KEY_NEW = 2640, + KEY_REDO = 2641, + KEY_CLOSE = 2642, + KEY_PLAY = 2643, + KEY_BASSBOOST = 2644, + KEY_PRINT = 2645, + KEY_CHAT = 2646, + KEY_FINANCE = 2647, + KEY_CANCEL = 2648, + KEY_KBDILLUM_TOGGLE = 2649, + KEY_KBDILLUM_DOWN = 2650, + KEY_KBDILLUM_UP = 2651, + KEY_SEND = 2652, + KEY_REPLY = 2653, + KEY_FORWARDMAIL = 2654, + KEY_SAVE = 2655, + KEY_DOCUMENTS = 2656, + KEY_VIDEO_NEXT = 2657, + KEY_VIDEO_PREV = 2658, + KEY_BRIGHTNESS_CYCLE = 2659, + KEY_BRIGHTNESS_ZERO = 2660, + KEY_DISPLAY_OFF = 2661, + KEY_BTN_MISC = 2662, + KEY_GOTO = 2663, + KEY_INFO = 2664, + KEY_PROGRAM = 2665, + KEY_PVR = 2666, + KEY_SUBTITLE = 2667, + KEY_FULL_SCREEN = 2668, + KEY_KEYBOARD = 2669, + KEY_ASPECT_RATIO = 2670, + KEY_PC = 2671, + KEY_TV = 2672, + KEY_TV2 = 2673, + KEY_VCR = 2674, + KEY_VCR2 = 2675, + KEY_SAT = 2676, + KEY_CD = 2677, + KEY_TAPE = 2678, + KEY_TUNER = 2679, + KEY_PLAYER = 2680, + KEY_DVD = 2681, + KEY_AUDIO = 2682, + KEY_VIDEO = 2683, + KEY_MEMO = 2684, + KEY_CALENDAR = 2685, + KEY_RED = 2686, + KEY_GREEN = 2687, + KEY_YELLOW = 2688, + KEY_BLUE = 2689, + KEY_CHANNELUP = 2690, + KEY_CHANNELDOWN = 2691, + KEY_LAST = 2692, + KEY_RESTART = 2693, + KEY_SLOW = 2694, + KEY_SHUFFLE = 2695, + KEY_VIDEOPHONE = 2696, + KEY_GAMES = 2697, + KEY_ZOOMIN = 2698, + KEY_ZOOMOUT = 2699, + KEY_ZOOMRESET = 2700, + KEY_WORDPROCESSOR = 2701, + KEY_EDITOR = 2702, + KEY_SPREADSHEET = 2703, + KEY_GRAPHICSEDITOR = 2704, + KEY_PRESENTATION = 2705, + KEY_DATABASE = 2706, + KEY_NEWS = 2707, + KEY_VOICEMAIL = 2708, + KEY_ADDRESSBOOK = 2709, + KEY_MESSENGER = 2710, + KEY_BRIGHTNESS_TOGGLE = 2711, + KEY_SPELLCHECK = 2712, + KEY_COFFEE = 2713, + KEY_MEDIA_REPEAT = 2714, + KEY_IMAGES = 2715, + KEY_BUTTONCONFIG = 2716, + KEY_TASKMANAGER = 2717, + KEY_JOURNAL = 2718, + KEY_CONTROLPANEL = 2719, + KEY_APPSELECT = 2720, + KEY_SCREENSAVER = 2721, + KEY_ASSISTANT = 2722, + KEY_KBD_LAYOUT_NEXT = 2723, + KEY_BRIGHTNESS_MIN = 2724, + KEY_BRIGHTNESS_MAX = 2725, + KEY_KBDINPUTASSIST_PREV = 2726, + KEY_KBDINPUTASSIST_NEXT = 2727, + KEY_KBDINPUTASSIST_PREVGROUP = 2728, + KEY_KBDINPUTASSIST_NEXTGROUP = 2729, + KEY_KBDINPUTASSIST_ACCEPT = 2730, + KEY_KBDINPUTASSIST_CANCEL = 2731, + KEY_FRONT = 2800, + KEY_SETUP = 2801, + KEY_WAKEUP = 2802, + KEY_SENDFILE = 2803, + KEY_DELETEFILE = 2804, + KEY_XFER = 2805, + KEY_PROG1 = 2806, + KEY_PROG2 = 2807, + KEY_MSDOS = 2808, + KEY_SCREENLOCK = 2809, + KEY_DIRECTION_ROTATE_DISPLAY = 2810, + KEY_CYCLEWINDOWS = 2811, + KEY_COMPUTER = 2812, + KEY_EJECTCLOSECD = 2813, + KEY_ISO = 2814, + KEY_MOVE = 2815, + KEY_F13 = 2816, + KEY_F14 = 2817, + KEY_F15 = 2818, + KEY_F16 = 2819, + KEY_F17 = 2820, + KEY_F18 = 2821, + KEY_F19 = 2822, + KEY_F20 = 2823, + KEY_F21 = 2824, + KEY_F22 = 2825, + KEY_F23 = 2826, + KEY_F24 = 2827, + KEY_PROG3 = 2828, + KEY_PROG4 = 2829, + KEY_DASHBOARD = 2830, + KEY_SUSPEND = 2831, + KEY_HP = 2832, + KEY_SOUND = 2833, + KEY_QUESTION = 2834, + KEY_CONNECT = 2836, + KEY_SPORT = 2837, + KEY_SHOP = 2838, + KEY_ALTERASE = 2839, + KEY_SWITCHVIDEOMODE = 2841, + KEY_BATTERY = 2842, + KEY_BLUETOOTH = 2843, + KEY_WLAN = 2844, + KEY_UWB = 2845, + KEY_WWAN_WIMAX = 2846, + KEY_RFKILL = 2847, + KEY_CHANNEL = 3001, + KEY_BTN_0 = 3100, + KEY_BTN_1 = 3101, + KEY_BTN_2 = 3102, + KEY_BTN_3 = 3103, + KEY_BTN_4 = 3104, + KEY_BTN_5 = 3105, + KEY_BTN_6 = 3106, + KEY_BTN_7 = 3107, + KEY_BTN_8 = 3108, + KEY_BTN_9 = 3109, +} OH_NativeXComponent_KeyCode; + +/** + * @brief Represents the key event action. + * + * @since 10 + * @version 1.0 + */ +typedef enum { + OH_NATIVEXCOMPONENT_KEY_ACTION_UNKNOWN = -1, + OH_NATIVEXCOMPONENT_KEY_ACTION_DOWN = 0, + OH_NATIVEXCOMPONENT_KEY_ACTION_UP, +} OH_NativeXComponent_KeyAction; + +#ifdef __cplusplus +}; +#endif +#endif // _NATIVE_INTERFACE_XCOMPONENT_KEY_EVENT_H_ diff --git a/arkui/napi/BUILD.gn b/arkui/napi/BUILD.gn new file mode 100644 index 000000000..fb23f3c4b --- /dev/null +++ b/arkui/napi/BUILD.gn @@ -0,0 +1,281 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//foundation/arkui/napi/napi.gni") + +config("ace_napi_config") { + include_dirs = [ + "../../../foundation/arkui/napi/native_engine", + "//foundation/arkui/napi", + "//foundation/arkui/napi/interfaces/inner_api", + "//foundation/arkui/napi/interfaces/kits", + "//third_party/libuv/include", + "//third_party/node/src", + ] +} + +config("module_manager_config") { + include_dirs = [ "../../../foundation/arkui/napi/module_manager" ] +} + +import("//build/ohos.gni") +import("//foundation/arkui/ace_engine/ace_config.gni") + +ohos_source_set("ace_napi_static") { + defines = [] + public_configs = [ ":ace_napi_config" ] + deps = [] + + include_dirs = [ + "../../../napi", + "../../../napi/interfaces/inner_api", + "../../../napi/interfaces/kits", + "//third_party/libuv/include", + "//third_party/node/src", + "../../../base/include", + ] + + sources = napi_sources + + if (current_cpu == "arm64") { + defines += [ "_ARM64_" ] + } + if (current_os == "ohos" && current_cpu == "x86_64") { + defines += [ "SIMULATOR" ] + } + if (use_mingw_win || use_mac || use_linux) { + defines += [ "PREVIEW" ] + } + if (use_mingw_win) { + defines += [ "WINDOWS_PLATFORM" ] + } else if (use_mac) { + defines += [ "MAC_PLATFORM" ] + } else if (use_linux) { + defines += [ "LINUX_PLATFORM" ] + } else if (is_cross_platform_build && target_os == "ios") { + defines += [ "IOS_PLATFORM" ] + if (napi_enable_container_scope) { + deps += [ ":ace_container_scope_static" ] + defines += [ "ENABLE_CONTAINER_SCOPE" ] + } + } else if (is_cross_platform_build && target_os == "android") { + defines += [ "ANDROID_PLATFORM" ] + if (napi_enable_container_scope) { + deps += [ ":ace_container_scope_static" ] + defines += [ "ENABLE_CONTAINER_SCOPE" ] + } + libs = [ "log" ] + } else { + if (is_standard_system) { + external_deps = [ + "hilog:libhilog", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + "init:libbegetutil", + ] + defines += [ "ENABLE_HITRACE" ] + if (product_name != "ohos-sdk") { + if (napi_enable_container_scope) { + if (target_os == "ios") { + deps += [ ":ace_container_scope_static" ] + } else { + deps += [ ":ace_container_scope" ] + } + defines += [ "ENABLE_CONTAINER_SCOPE" ] + } + } + } else { + external_deps = [ "hilog:libhilog" ] + } + } + + deps += [ + "//third_party/bounds_checking_function:libsec_static", + "//third_party/libuv:uv", + ] + + # Use static libuv for cross build + if (is_cross_platform_build) { + deps -= [ "//third_party/libuv:uv" ] + deps += [ "//third_party/libuv:uv_static" ] + } + + cflags_cc = [ "-Wno-missing-braces" ] + + subsystem_name = "arkui" + part_name = "napi" +} + +if (is_cross_platform_build) { + ohos_source_set("ace_napi") { + deps = [ ":ace_napi_static" ] + public_configs = [ ":ace_napi_config" ] + subsystem_name = "arkui" + part_name = "napi" + } +} else { + ohos_shared_library("ace_napi") { + deps = [ ":ace_napi_static" ] + public_configs = [ + ":ace_napi_config", + ":module_manager_config", + ] + if (!is_cross_platform_build) { + public_deps = [ "//third_party/libuv:uv" ] + } + subsystem_name = "arkui" + innerapi_tags = [ "platformsdk" ] + part_name = "napi" + } +} + +config("container_scope_config") { + visibility = [ ":*" ] + include_dirs = [ "$ace_root/frameworks" ] +} + +ohos_shared_library("ace_container_scope") { + public_configs = [ ":container_scope_config" ] + + configs = [ "$ace_root:ace_config" ] + + sources = [ "$ace_root/frameworks/core/common/container_scope.cpp" ] + + subsystem_name = "arkui" + innerapi_tags = [ "platformsdk_indirect" ] + part_name = "napi" +} + +ohos_source_set("ace_container_scope_static") { + public_configs = [ ":container_scope_config" ] + + configs = [ "$ace_root:ace_config" ] + + sources = [ "$ace_root/frameworks/core/common/container_scope.cpp" ] +} + +template("ace_napi_lib") { + forward_variables_from(invoker, "*") + if (defined(use_js_debug) && use_js_debug) { + deps_ = [ + "native_engine/impl/${engine_path}:ace_napi_impl_${engine_path}_debug", + ] + } else { + deps_ = [ "native_engine/impl/${engine_path}:ace_napi_impl_${engine_path}" ] + } + + if (is_cross_platform_build) { + ohos_source_set(target_name) { + public_configs = + [ "native_engine/impl/${engine_path}:ace_napi_${engine_path}_config" ] + deps = deps_ + if (defined(use_icu) && use_icu) { + deps += [ + "//third_party/icu/icu4c:static_icui18n", + "//third_party/icu/icu4c:static_icuuc", + ] + } + subsystem_name = "arkui" + part_name = "napi" + } + } else { + ohos_shared_library(target_name) { + public_configs = + [ "native_engine/impl/${engine_path}:ace_napi_${engine_path}_config" ] + deps = deps_ + if (defined(use_icu) && use_icu) { + deps += [ "//third_party/icu/icu4c:shared_icuuc" ] + } + + if (target_name == "ark" || target_name == "quickjs") { + deps -= [ "//third_party/libuv:uv" ] + } + + subsystem_name = "arkui" + part_name = "napi" + } + } +} +napi_libs = [] + +foreach(item, ace_platforms) { + if (item.name == "ohos" || is_cross_platform_build) { + engine_config = { + } + support_engines = { + } + engine_config = item.config + support_engines = engine_config.js_engines + foreach(engine, support_engines) { + if (engine.engine_name != "ark") { + ace_napi_lib("ace_napi_${engine.engine_path}") { + engine_path = engine.engine_path + } + napi_libs += [ ":ace_napi_${engine.engine_path}" ] + if (defined(engine.have_debug) && engine.have_debug) { + ace_napi_lib("ace_napi_${engine.engine_path}_debug") { + engine_path = engine.engine_path + use_js_debug = true + } + napi_libs += [ ":ace_napi_${engine.engine_path}_debug" ] + } + } else if (engine.engine_name == "ark") { + ace_napi_lib("ace_napi_${engine.engine_name}") { + engine_path = engine.engine_name + use_icu = true + } + napi_libs += [ ":ace_napi_${engine.engine_name}" ] + } + } + } +} + +group("napi_packages") { + deps = [ ":ace_napi" ] + deps += napi_libs +} + +ohos_ndk_library("libnapi_ndk") { + ndk_description_file = "./libnapi.ndk.json" + min_compact_version = "1" + output_name = "ace_napi" +} + +ohos_ndk_headers("napi_header") { + dest_dir = "$ndk_headers_out_dir/napi" + sources = [ + "interfaces/kits/napi/common.h", + "interfaces/kits/napi/native_api.h", + ] +} + +group("napi_packages_ndk") { + deps = [ ":libnapi_ndk" ] +} + +if (!build_ohos_ndk && !is_cross_platform_build) { + group("napi_packages_test") { + testonly = true + + deps = [ + "sample/native_module_calc:calc", + "sample/native_module_calc:number", + "sample/native_module_callback:callback", + "sample/native_module_demo:demo", + "sample/native_module_netserver:netserver", + "sample/native_module_storage:storage", + "test/fuzztest:fuzztest", + "test/unittest:unittest", + ] + } +} diff --git a/arkui/napi/common.h b/arkui/napi/common.h new file mode 100644 index 000000000..8b7df91a6 --- /dev/null +++ b/arkui/napi/common.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_COMMON_H +#define FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_COMMON_H + +typedef enum { + napi_qos_background = 0, + napi_qos_utility = 1, + napi_qos_default = 2, + napi_qos_user_initiated = 3, +} napi_qos_t; + +#endif /* FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H */ \ No newline at end of file diff --git a/arkui/napi/libnapi.ndk.json b/arkui/napi/libnapi.ndk.json new file mode 100644 index 000000000..dbc43ff83 --- /dev/null +++ b/arkui/napi/libnapi.ndk.json @@ -0,0 +1,135 @@ +[ + {"name": "napi_module_register"}, + {"name": "napi_get_last_error_info"}, + {"name": "napi_throw"}, + {"name": "napi_throw_error"}, + {"name": "napi_throw_type_error"}, + {"name": "napi_throw_range_error"}, + {"name": "napi_is_error"}, + {"name": "napi_create_error"}, + {"name": "napi_create_type_error"}, + {"name": "napi_create_range_error"}, + {"name": "napi_get_and_clear_last_exception"}, + {"name": "napi_is_exception_pending"}, + {"name": "napi_fatal_error"}, + {"name": "napi_open_handle_scope"}, + {"name": "napi_close_handle_scope"}, + {"name": "napi_open_escapable_handle_scope"}, + {"name": "napi_close_escapable_handle_scope"}, + {"name": "napi_escape_handle"}, + {"name": "napi_create_reference"}, + {"name": "napi_delete_reference"}, + {"name": "napi_reference_ref"}, + {"name": "napi_reference_unref"}, + {"name": "napi_get_reference_value"}, + {"name": "napi_create_array"}, + {"name": "napi_create_array_with_length"}, + {"name": "napi_create_arraybuffer"}, + {"name": "napi_create_external"}, + {"name": "napi_create_external_arraybuffer"}, + {"name": "napi_create_object"}, + {"name": "napi_create_symbol"}, + {"name": "napi_create_typedarray"}, + {"name": "napi_create_dataview"}, + {"name": "napi_create_int32"}, + {"name": "napi_create_uint32"}, + {"name": "napi_create_int64"}, + {"name": "napi_create_double"}, + {"name": "napi_create_string_latin1"}, + {"name": "napi_create_string_utf8"}, + {"name": "napi_create_string_utf16"}, + {"name": "napi_get_array_length"}, + {"name": "napi_get_arraybuffer_info"}, + {"name": "napi_get_prototype"}, + {"name": "napi_get_typedarray_info"}, + {"name": "napi_get_dataview_info"}, + {"name": "napi_get_value_bool"}, + {"name": "napi_get_value_double"}, + {"name": "napi_get_value_external"}, + {"name": "napi_get_value_int32"}, + {"name": "napi_get_value_int64"}, + {"name": "napi_get_value_string_latin1"}, + {"name": "napi_get_value_string_utf8"}, + {"name": "napi_get_value_string_utf16"}, + {"name": "napi_get_value_uint32"}, + {"name": "napi_get_boolean"}, + {"name": "napi_get_global"}, + {"name": "napi_get_null"}, + {"name": "napi_get_undefined"}, + {"name": "napi_coerce_to_bool"}, + {"name": "napi_coerce_to_number"}, + {"name": "napi_coerce_to_object"}, + {"name": "napi_coerce_to_string"}, + {"name": "napi_typeof"}, + {"name": "napi_instanceof"}, + {"name": "napi_is_array"}, + {"name": "napi_is_arraybuffer"}, + {"name": "napi_is_typedarray"}, + {"name": "napi_is_dataview"}, + {"name": "napi_is_date"}, + {"name": "napi_strict_equals"}, + {"name": "napi_get_property_names"}, + {"name": "napi_get_all_property_names"}, + {"name": "napi_set_property"}, + {"name": "napi_get_property"}, + {"name": "napi_has_property"}, + {"name": "napi_check_object_type_tag"}, + {"name": "napi_type_tag_object"}, + {"name": "napi_delete_property"}, + {"name": "napi_has_own_property"}, + {"name": "napi_set_named_property"}, + {"name": "napi_get_named_property"}, + {"name": "napi_has_named_property"}, + {"name": "napi_set_element"}, + {"name": "napi_get_element"}, + {"name": "napi_has_element"}, + {"name": "napi_delete_element"}, + {"name": "napi_define_properties"}, + {"name": "napi_call_function"}, + {"name": "napi_create_function"}, + {"name": "napi_get_cb_info"}, + {"name": "napi_get_new_target"}, + {"name": "napi_new_instance"}, + {"name": "napi_define_class"}, + {"name": "napi_wrap"}, + {"name": "napi_unwrap"}, + {"name": "napi_remove_wrap"}, + {"name": "napi_create_async_work"}, + {"name": "napi_delete_async_work"}, + {"name": "napi_queue_async_work"}, + {"name": "napi_cancel_async_work"}, + {"name": "napi_get_node_version"}, + {"name": "napi_get_version"}, + {"name": "napi_create_promise"}, + {"name": "napi_resolve_deferred"}, + {"name": "napi_reject_deferred"}, + {"name": "napi_is_promise"}, + {"name": "napi_run_script"}, + {"name": "napi_get_uv_event_loop"}, + {"name": "napi_run_script_path"}, + {"name": "napi_create_threadsafe_function"}, + {"name": "napi_get_threadsafe_function_context"}, + {"name": "napi_call_threadsafe_function"}, + {"name": "napi_acquire_threadsafe_function"}, + {"name": "napi_release_threadsafe_function"}, + {"name": "napi_unref_threadsafe_function"}, + {"name": "napi_ref_threadsafe_function"}, + {"name": "napi_create_date"}, + {"name": "napi_get_date_value"}, + {"name": "napi_create_bigint_int64"}, + {"name": "napi_create_bigint_uint64"}, + {"name": "napi_create_bigint_words"}, + {"name": "napi_get_value_bigint_int64"}, + {"name": "napi_get_value_bigint_uint64"}, + {"name": "napi_get_value_bigint_words"}, + {"name": "napi_object_freeze"}, + {"name": "napi_object_seal"}, + {"name": "napi_detach_arraybuffer"}, + {"name": "napi_is_detached_arraybuffer"}, + {"name": "napi_is_buffer"}, + {"name": "napi_create_buffer"}, + {"name": "napi_create_buffer_copy"}, + {"name": "napi_create_external_buffer"}, + {"name": "napi_get_buffer_info"}, + {"name": "napi_queue_async_work_with_qos"} +] \ No newline at end of file diff --git a/arkui/napi/native_api.h b/arkui/napi/native_api.h new file mode 100644 index 000000000..b4f5d1c6b --- /dev/null +++ b/arkui/napi/native_api.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H +#define FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H + +#ifndef NAPI_VERSION +#define NAPI_VERSION 8 +#endif + +#ifndef NAPI_EXPERIMENTAL +#define NAPI_EXPERIMENTAL +#endif + +#include "common.h" +#include "node_api.h" + +#ifdef NAPI_TEST +#ifdef _WIN32 +#define NAPI_INNER_EXTERN __declspec(dllexport) +#else +#define NAPI_INNER_EXTERN __attribute__((visibility("default"))) +#endif +#else +#ifdef _WIN32 +#define NAPI_INNER_EXTERN __declspec(deprecated) +#else +#define NAPI_INNER_EXTERN __attribute__((__deprecated__)) +#endif +#endif + +NAPI_INNER_EXTERN napi_status napi_set_instance_data(napi_env env, + void* data, + napi_finalize finalize_cb, + void* finalize_hint); + +NAPI_INNER_EXTERN napi_status napi_get_instance_data(napi_env env, + void** data); + +NAPI_INNER_EXTERN napi_status napi_fatal_exception(napi_env env, napi_value err); + +NAPI_INNER_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env, + void (*fun)(void* arg), + void* arg); + +NAPI_INNER_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env, + void (*fun)(void* arg), + void* arg); + +NAPI_INNER_EXTERN napi_status napi_add_async_cleanup_hook( + napi_env env, + napi_async_cleanup_hook hook, + void* arg, + napi_async_cleanup_hook_handle* remove_handle); + +NAPI_INNER_EXTERN napi_status napi_remove_async_cleanup_hook( + napi_async_cleanup_hook_handle remove_handle); + +NAPI_EXTERN napi_status napi_create_string_utf16(napi_env env, + const char16_t* str, + size_t length, + napi_value* result); + +NAPI_EXTERN napi_status napi_get_value_string_utf16(napi_env env, + napi_value value, + char16_t* buf, + size_t bufsize, + size_t* result); + +NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, + napi_value value, + const napi_type_tag* type_tag); + +NAPI_EXTERN napi_status napi_check_object_type_tag(napi_env env, + napi_value value, + const napi_type_tag* type_tag, + bool* result); + +NAPI_INNER_EXTERN napi_status napi_add_finalizer(napi_env env, + napi_value js_object, + void* native_object, + napi_finalize finalize_cb, + void* finalize_hint, + napi_ref* result); + +NAPI_INNER_EXTERN napi_status napi_async_init(napi_env env, + napi_value async_resource, + napi_value async_resource_name, + napi_async_context* result); + +NAPI_INNER_EXTERN napi_status napi_async_destroy(napi_env env, + napi_async_context async_context); + +NAPI_INNER_EXTERN napi_status napi_open_callback_scope(napi_env env, + napi_value resource_object, + napi_async_context context, + napi_callback_scope* result); + +NAPI_INNER_EXTERN napi_status napi_close_callback_scope(napi_env env, + napi_callback_scope scope); + +NAPI_INNER_EXTERN napi_status napi_adjust_external_memory(napi_env env, + int64_t change_in_bytes, + int64_t* adjusted_value); + +NAPI_INNER_EXTERN napi_status node_api_get_module_file_name(napi_env env, const char** result); + +#ifdef __cplusplus +extern "C" { +#endif + +NAPI_EXTERN napi_status napi_run_script_path(napi_env env, const char* path, napi_value* result); +NAPI_EXTERN napi_status napi_queue_async_work_with_qos(napi_env env, napi_async_work work, napi_qos_t qos); + +#ifdef __cplusplus +} +#endif +#endif /* FOUNDATION_ACE_NAPI_INTERFACES_KITS_NAPI_NATIVE_API_H */ diff --git a/bundlemanager/bundle_framework/bundle/BUILD.gn b/bundlemanager/bundle_framework/bundle/BUILD.gn new file mode 100644 index 000000000..a4e8f0900 --- /dev/null +++ b/bundlemanager/bundle_framework/bundle/BUILD.gn @@ -0,0 +1,71 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("../../../../appexecfwk.gni") + +config("bundle_ndk_config") { + include_dirs = [ "include" ] +} +ohos_ndk_headers("bundle_header") { + dest_dir = "$ndk_headers_out_dir/bundle/" + sources = [ "./include/native_interface_bundle.h" ] +} + +ohos_ndk_library("libbundle_ndk") { + ndk_description_file = "./libbundle.ndk.json" + min_compact_version = "9" + output_name = "bundle_ndk" +} + +ohos_shared_library("bundle_ndk") { + public_configs = [ ":bundle_ndk_config" ] + include_dirs = [ + "${common_path}/log/include", + "${inner_api_path}/appexecfwk_base/include", + "${inner_api_path}/appexecfwk_base/include/quick_fix", + "${inner_api_path}/appexecfwk_base/include/overlay", + "//third_party/json/include", + ] + defines = [ + "APP_LOG_TAG = \"BundleMgrService\"", + "LOG_DOMAIN = 0xD001120", + ] + sources = [ + "${inner_api_path}/appexecfwk_base/src/ability_info.cpp", + "${inner_api_path}/appexecfwk_base/src/application_info.cpp", + "${inner_api_path}/appexecfwk_base/src/bundle_info.cpp", + "${inner_api_path}/appexecfwk_base/src/compatible_application_info.cpp", + "${inner_api_path}/appexecfwk_base/src/extension_ability_info.cpp", + "${inner_api_path}/appexecfwk_base/src/hap_module_info.cpp", + "${inner_api_path}/appexecfwk_base/src/module_info.cpp", + "${inner_api_path}/appexecfwk_base/src/overlay/overlay_bundle_info.cpp", + "${inner_api_path}/appexecfwk_base/src/overlay/overlay_module_info.cpp", + "${inner_api_path}/appexecfwk_base/src/quick_fix/app_quick_fix.cpp", + "${inner_api_path}/appexecfwk_base/src/quick_fix/appqf_info.cpp", + "${inner_api_path}/appexecfwk_base/src/quick_fix/hqf_info.cpp", + "src/bundle_mgr_proxy_native.cpp", + "src/native_interface_bundle.cpp", + ] + + deps = [ "${common_path}:libappexecfwk_common" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} diff --git a/bundlemanager/bundle_framework/bundle/include/bundle_mgr_proxy_native.h b/bundlemanager/bundle_framework/bundle/include/bundle_mgr_proxy_native.h new file mode 100644 index 000000000..6cf1c4470 --- /dev/null +++ b/bundlemanager/bundle_framework/bundle/include/bundle_mgr_proxy_native.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef FOUNDATION_APPEXECFWK_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_BUNDLE_MGR_PROXY_NATIVE_H +#define FOUNDATION_APPEXECFWK_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_BUNDLE_MGR_PROXY_NATIVE_H + +#include + +#include "application_info.h" +#include "bundle_info.h" +#include "iremote_broker.h" +#include "iremote_object.h" + +namespace OHOS { +namespace AppExecFwk { +class BundleMgrProxyNative { +public: + BundleMgrProxyNative() = default; + virtual ~BundleMgrProxyNative() = default; + + /** + * @brief Obtains the BundleInfo based on calling uid. + * @param bundleName Indicates the application bundle name to be queried. + * @param flags Indicates the information contained in the BundleInfo object to be returned. + * @param bundleInfo Indicates the obtained BundleInfo object. + * @param userId Indicates the user ID. + * @return Returns true if the BundleInfo is successfully obtained; returns false otherwise. + */ + bool GetBundleInfoForSelf(int32_t flags, BundleInfo &bundleInfo); + + enum { + GET_BUNDLE_INFO_FOR_SELF_NATIVE = 98 + }; +private: + sptr GetBmsProxy(); + template + bool GetParcelableInfo(uint32_t code, MessageParcel &data, T &parcelableInfo); + bool SendTransactCmd(uint32_t code, MessageParcel &data, MessageParcel &reply); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_BUNDLE_MGR_PROXY_NATIVE_H \ No newline at end of file diff --git a/bundlemanager/bundle_framework/bundle/include/native_interface_bundle.h b/bundlemanager/bundle_framework/bundle/include/native_interface_bundle.h new file mode 100644 index 000000000..d318f8670 --- /dev/null +++ b/bundlemanager/bundle_framework/bundle/include/native_interface_bundle.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup Native_Bundle + * @{ + * + * @brief Describes the Native Bundle. + * + * @since 9 + * @version 1.0 + */ + +/** + * @file native_interface_bundle.h + * + * @brief Declares the Bundle-specific function, including function for obtaining application info. + * + * @since 9 + * @version 1.0 + */ +#ifndef FOUNDATION_APPEXECFWK_STANDARD_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_NATIVE_INTERFACE_BUNDLE_H +#define FOUNDATION_APPEXECFWK_STANDARD_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_NATIVE_INTERFACE_BUNDLE_H + +#ifdef __cplusplus +extern "C" { +#endif +struct OH_NativeBundle_ApplicationInfo { + char* bundleName; + + char* fingerprint; +}; + +/** + * @brief Obtains the application info based on the The current bundle. + * + * @return Returns the application info. + * @since 9 + * @version 1.0 + */ +OH_NativeBundle_ApplicationInfo OH_NativeBundle_GetCurrentApplicationInfo(); + +#ifdef __cplusplus +}; +#endif +#endif // FOUNDATION_APPEXECFWK_STANDARD_KITS_APPKIT_NATIVE_BUNDLE_INCLUDE_NATIVE_INTERFACE_BUNDLE_H diff --git a/bundlemanager/bundle_framework/bundle/libbundle.ndk.json b/bundlemanager/bundle_framework/bundle/libbundle.ndk.json new file mode 100644 index 000000000..c40f8ee41 --- /dev/null +++ b/bundlemanager/bundle_framework/bundle/libbundle.ndk.json @@ -0,0 +1,6 @@ +[ + { + "first_introduced": "9", + "name": "OH_NativeBundle_GetCurrentApplicationInfo" + } +] diff --git a/bundlemanager/bundle_framework/bundle/src/bundle_mgr_proxy_native.cpp b/bundlemanager/bundle_framework/bundle/src/bundle_mgr_proxy_native.cpp new file mode 100644 index 000000000..50bf7a331 --- /dev/null +++ b/bundlemanager/bundle_framework/bundle/src/bundle_mgr_proxy_native.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "bundle_mgr_proxy_native.h" + +#include "app_log_wrapper.h" +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "string_ex.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { + const std::u16string BMS_PROXY_INTERFACE_TOKEN = u"ohos.appexecfwk.BundleMgr"; +} + +sptr BundleMgrProxyNative::GetBmsProxy() +{ + auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgrProxy == nullptr) { + APP_LOGE("fail to get samgr."); + return nullptr; + } + return samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); +} + +bool BundleMgrProxyNative::GetBundleInfoForSelf(int32_t flags, BundleInfo &bundleInfo) +{ + APP_LOGI("begin to get bundle info for self"); + MessageParcel data; + if (!data.WriteInterfaceToken(BMS_PROXY_INTERFACE_TOKEN)) { + APP_LOGE("fail to GetBundleInfoForSelf due to write InterfaceToken fail"); + return false; + } + if (!data.WriteInt32(flags)) { + APP_LOGE("fail to GetBundleInfoForSelf due to write flag fail"); + return false; + } + if (!GetParcelableInfo(GET_BUNDLE_INFO_FOR_SELF_NATIVE, data, bundleInfo)) { + APP_LOGE("fail to GetBundleInfoForSelf from server"); + return false; + } + return true; +} + +bool BundleMgrProxyNative::SendTransactCmd(uint32_t code, MessageParcel &data, MessageParcel &reply) +{ + MessageOption option(MessageOption::TF_SYNC); + + sptr remote = GetBmsProxy(); + if (remote == nullptr) { + APP_LOGE("fail to send transact cmd %{public}d due to remote object", code); + return false; + } + int32_t result = remote->SendRequest(static_cast(code), data, reply, option); + if (result != NO_ERROR) { + APP_LOGE("receive error transact code %{public}d in transact cmd %{public}d", result, code); + return false; + } + return true; +} + +template +bool BundleMgrProxyNative::GetParcelableInfo(uint32_t code, MessageParcel &data, T &parcelableInfo) +{ + MessageParcel reply; + if (!SendTransactCmd(code, data, reply)) { + return false; + } + + int32_t res = reply.ReadInt32(); + if (res != NO_ERROR) { + APP_LOGE("reply result failed"); + return false; + } + std::unique_ptr info(reply.ReadParcelable()); + if (info == nullptr) { + APP_LOGE("readParcelableInfo failed"); + return false; + } + parcelableInfo = *info; + APP_LOGD("get parcelable info success"); + return true; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/bundlemanager/bundle_framework/bundle/src/native_interface_bundle.cpp b/bundlemanager/bundle_framework/bundle/src/native_interface_bundle.cpp new file mode 100644 index 000000000..8c639bb80 --- /dev/null +++ b/bundlemanager/bundle_framework/bundle/src/native_interface_bundle.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "native_interface_bundle.h" + +#include +#include + +#include "application_info.h" +#include "bundle_info.h" +#include "app_log_wrapper.h" +#include "bundle_mgr_proxy_native.h" +#include "ipc_skeleton.h" +#include "securec.h" +namespace { + const size_t CHAR_MAX_LENGTH = 10240; +} + +OH_NativeBundle_ApplicationInfo OH_NativeBundle_GetCurrentApplicationInfo() +{ + OH_NativeBundle_ApplicationInfo nativeApplicationInfo; + OHOS::AppExecFwk::BundleMgrProxyNative bundleMgrProxyNative; + OHOS::AppExecFwk::BundleInfo bundleInfo; + auto bundleInfoFlag = static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION); + + if (!bundleMgrProxyNative.GetBundleInfoForSelf(bundleInfoFlag, bundleInfo)) { + APP_LOGE("can not get bundleInfo for self"); + return nativeApplicationInfo; + }; + OHOS::AppExecFwk::ApplicationInfo applicationInfo = bundleInfo.applicationInfo; + + size_t bundleNameLen = applicationInfo.bundleName.size(); + if ((bundleNameLen == 0) || (bundleNameLen + 1) > CHAR_MAX_LENGTH) { + APP_LOGE("failed due to the length of bundleName is 0 or to long"); + return nativeApplicationInfo; + } + nativeApplicationInfo.bundleName = static_cast(malloc(bundleNameLen + 1)); + if (nativeApplicationInfo.bundleName == nullptr) { + APP_LOGE("failed due to malloc error"); + return nativeApplicationInfo; + } + + if (strcpy_s(nativeApplicationInfo.bundleName, bundleNameLen + 1, applicationInfo.bundleName.c_str()) != EOK) { + APP_LOGE("failed due to strcpy_s error"); + free(nativeApplicationInfo.bundleName); + nativeApplicationInfo.bundleName = nullptr; + return nativeApplicationInfo; + } + + size_t fingerprintLen = applicationInfo.fingerprint.size(); + if ((fingerprintLen == 0) || (fingerprintLen + 1) > CHAR_MAX_LENGTH) { + APP_LOGE("failed due to the length of fingerprint is 0 or to long"); + free(nativeApplicationInfo.bundleName); + nativeApplicationInfo.bundleName = nullptr; + return nativeApplicationInfo; + } + nativeApplicationInfo.fingerprint = static_cast(malloc(fingerprintLen + 1)); + if (nativeApplicationInfo.fingerprint == nullptr) { + APP_LOGE("failed due to malloc error"); + free(nativeApplicationInfo.bundleName); + nativeApplicationInfo.bundleName = nullptr; + return nativeApplicationInfo; + } + + if (strcpy_s(nativeApplicationInfo.fingerprint, fingerprintLen + 1, applicationInfo.fingerprint.c_str()) != EOK) { + APP_LOGE("failed due to strcpy_s error"); + free(nativeApplicationInfo.bundleName); + nativeApplicationInfo.bundleName = nullptr; + free(nativeApplicationInfo.fingerprint); + nativeApplicationInfo.fingerprint = nullptr; + return nativeApplicationInfo; + } + APP_LOGI("OH_NativeBundle_GetCurrentApplicationInfo success"); + return nativeApplicationInfo; +} diff --git a/commonlibrary/memory_utils/libpurgeablemem/BUILD.gn b/commonlibrary/memory_utils/libpurgeablemem/BUILD.gn new file mode 100644 index 000000000..6ffd6731c --- /dev/null +++ b/commonlibrary/memory_utils/libpurgeablemem/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_headers("purgeable_memory_header") { + dest_dir = "$ndk_headers_out_dir/purgeable_memory" + sources = [ "./purgeable_memory.h" ] +} + +ohos_ndk_library("libpurgeable_memory_ndk") { + output_name = "purgeable_memory_ndk" + output_extension = "z.so" + ndk_description_file = "./libpurgeable_memory.ndk.json" + system_capability = "SystemCapability.CommonLibrary.Memory.PurgeableMemory" + system_capability = "purgeable_memory/purgeable_memory.h" +} diff --git a/commonlibrary/memory_utils/libpurgeablemem/libpurgeable_memory.ndk.json b/commonlibrary/memory_utils/libpurgeablemem/libpurgeable_memory.ndk.json new file mode 100644 index 000000000..02b15f017 --- /dev/null +++ b/commonlibrary/memory_utils/libpurgeablemem/libpurgeable_memory.ndk.json @@ -0,0 +1,11 @@ +[ + { "name": "OH_PurgeableMemory_Create" }, + { "name": "OH_PurgeableMemory_Destroy" }, + { "name": "OH_PurgeableMemory_BeginRead" }, + { "name": "OH_PurgeableMemory_EndRead" }, + { "name": "OH_PurgeableMemory_BeginWrite" }, + { "name": "OH_PurgeableMemory_EndWrite" }, + { "name": "OH_PurgeableMemory_GetContent" }, + { "name": "OH_PurgeableMemory_ContentSize" }, + { "name": "OH_PurgeableMemory_AppendModify" } +] \ No newline at end of file diff --git a/commonlibrary/memory_utils/libpurgeablemem/purgeable_memory.h b/commonlibrary/memory_utils/libpurgeablemem/purgeable_memory.h new file mode 100644 index 000000000..a22804434 --- /dev/null +++ b/commonlibrary/memory_utils/libpurgeablemem/purgeable_memory.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup memory + * + * @brief provides memory management capabilities + * + * provides features include operations such as memory alloction, memory free, and so on + * + * @since 10 + * @version 1.0 + */ + +/** + * @file purgeable_memory.h + * + * @brief provides memory management capabilities of purgeable memory. + * + * provides features include create, begin read ,end read, begin write, end write, rebuild, and so on. + * when using, it is necessary to link libpurgeable_memory_ndk.z.so + * + * @since 10 + * @version 1.0 + */ + +#ifndef OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H +#define OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H + +#include /* bool */ +#include /* size_t */ + +#ifdef __cplusplus +extern "C" { +#endif /* End of #ifdef __cplusplus */ + +/* + * @brief Purgeable mem struct + * + * @since 10 + * @version 1.0 + */ +typedef struct PurgMem OH_PurgeableMemory; + +/* + * @brief: function pointer, it points to a function which is used to build content of a PurgMem obj. + * + * + * @param void *: data ptr, points to start address of a PurgMem obj's content. + * @param size_t: data size of the content. + * @param void *: other private parameters. + * @return: build content result, true means success, while false is fail. + * + * @since 10 + * @version 1.0 + */ +typedef bool (*OH_PurgeableMemory_ModifyFunc)(void *, size_t, void *); + +/* + * @brief: create a PurgMem obj. + * + * + * @param size: data size of a PurgMem obj's content. + * @param func: function pointer, it is used to recover data when the PurgMem obj's content is purged. + * @param funcPara: parameters used by @func. + * @return: a PurgMem obj. + * + * @since 10 + * @version 1.0 + */ +OH_PurgeableMemory *OH_PurgeableMemory_Create( + size_t size, OH_PurgeableMemory_ModifyFunc func, void *funcPara); + +/* + * @brief: destroy a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj to be destroyed. + * @return: true is success, while false is fail. return true if @purgObj is NULL. + * If return true, @purgObj will be set to NULL to avoid Use-After-Free. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_Destroy(OH_PurgeableMemory *purgObj); + +/* + * @brief: begin read a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return true if @purgObj's content is present. + * If content is purged(no present), system will recover its data, + * return false if content is purged and recovered failed. + * While return true if content recover success. + * OS cannot reclaim the memory of @purgObj's content when this + * function return true, until PurgMemEndRead() is called. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_BeginRead(OH_PurgeableMemory *purgObj); + +/* + * @brief: end read a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * OS may reclaim the memory of @purgObj's content + * at a later time when this function returns. + * + * @since 10 + * @version 1.0 + */ +void OH_PurgeableMemory_EndRead(OH_PurgeableMemory *purgObj); + +/* + * @brief: begin write a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return true if @purgObj's content is present. + * if content is purged(no present), system will recover its data, + * return false if content is purged and recovered failed. + * While return true if content is successfully recovered. + * OS cannot reclaim the memory of @purgObj's content when this + * function return true, until PurgMemEndWrite() is called. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_BeginWrite(OH_PurgeableMemory *purgObj); + +/* + * @brief: end write a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * OS may reclaim the memory of @purgObj's content + * at a later time when this function returns. + * + * @since 10 + * @version 1.0 + */ +void OH_PurgeableMemory_EndWrite(OH_PurgeableMemory *purgObj); + +/* + * @brief: get content ptr of a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return start address of a PurgMem obj's content. + * Return NULL if @purgObj is NULL. + * This function should be protect by PurgMemBeginRead()/PurgMemEndRead() + * or PurgMemBeginWrite()/PurgMemEndWrite() + * + * @since 10 + * @version 1.0 + */ +void *OH_PurgeableMemory_GetContent(OH_PurgeableMemory *purgObj); + +/* + * @brief: get content size of a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return content size of @purgObj. + * Return 0 if @purgObj is NULL. + * + * @since 10 + * @version 1.0 + */ +size_t OH_PurgeableMemory_ContentSize(OH_PurgeableMemory *purgObj); + +/* + * @brief: append a modify to a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @param size: data size of a PurgMem obj's content. + * @param func: function pointer, it will modify content of @PurgMem. + * @param funcPara: parameters used by @func. + * @return: append result, true is success, while false is fail. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_AppendModify(OH_PurgeableMemory *purgObj, + OH_PurgeableMemory_ModifyFunc func, void *funcPara); + +#ifdef __cplusplus +} +#endif /* End of #ifdef __cplusplus */ +#endif /* OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H */ \ No newline at end of file diff --git a/distributeddatamgr/relational_store/BUILD.gn b/distributeddatamgr/relational_store/BUILD.gn new file mode 100644 index 000000000..51d6323e4 --- /dev/null +++ b/distributeddatamgr/relational_store/BUILD.gn @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/distributeddatamgr/relational_store/relational_store.gni") + +ohos_ndk_headers("native_rdb_ndk_header") { + dest_dir = "$ndk_headers_out_dir/database/rdb/" + sources = [ + "./include/oh_cursor.h", + "./include/oh_predicates.h", + "./include/oh_value_object.h", + "./include/oh_values_bucket.h", + "./include/relational_store.h", + "./include/relational_store_error_code.h", + ] +} + +ohos_ndk_library("libnative_rdb_ndk") { + output_name = "native_rdb_ndk" + system_capability = + "SystemCapability.DistributedDataManager.RelationalStore.Core" + ndk_description_file = "./libnative_rdb.ndk.json" + min_compact_version = "10" + system_capability_headers = [ + "$ndk_headers_out_dir/database/rdb/oh_cursor.h", + "$ndk_headers_out_dir/database/rdb/oh_predicates.h", + "$ndk_headers_out_dir/database/rdb/oh_value_object.h", + "$ndk_headers_out_dir/database/rdb/oh_values_bucket.h", + "$ndk_headers_out_dir/database/rdb/relational_store.h", + "$ndk_headers_out_dir/database/rdb/relational_store_error_code.h", + ] +} diff --git a/distributeddatamgr/relational_store/include/oh_cursor.h b/distributeddatamgr/relational_store/include/oh_cursor.h new file mode 100644 index 000000000..165da158e --- /dev/null +++ b/distributeddatamgr/relational_store/include/oh_cursor.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OH_CURSOR_H +#define OH_CURSOR_H + +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + +/** + * @file oh_cursor.h + * + * @brief Provides functions and enumerations related to the resultSet. + * + * @since 10 + */ + +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Indicates the column type. + * + * @since 10 + */ +typedef enum OH_ColumnType { + /** + * Indicates the column type is NULL. + */ + TYPE_NULL = 0, + /** + * Indicates the column type is INT64. + */ + TYPE_INT64, + /** + * Indicates the column type is REAL. + */ + TYPE_REAL, + /** + * Indicates the column type is TEXT. + */ + TYPE_TEXT, + /** + * Indicates the column type is BLOB. + */ + TYPE_BLOB, +} OH_ColumnType; + +/** + * @brief Define the OH_Cursor structure type. + * + * Provides methods for accessing a database result set generated by query the database. + * + * @since 10 + */ +typedef struct OH_Cursor { + /** + * The id used to uniquely identify the OH_Cursor struct. + */ + int64_t id; + /** + * @brief Function pointer. Obtains the total number of columns. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param count This parameter is the output parameter, and the number of columns is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getColumnCount)(OH_Cursor *cursor, int *count); + + /** + * @brief Function pointer. Obtains data type of the given column's value. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based index of the target column. + * @param columnType This parameter is the output parameter, and the column value type is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor, OH_ColumnType. + * @since 10 + */ + int (*getColumnType)(OH_Cursor *cursor, int32_t columnIndex, OH_ColumnType *columnType); + + /** + * @brief Function pointer. Obtains the zero-based index for the given column name. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param name Indicates the name of the column. + * @param columnIndex This parameter is the output parameter, + * and the column index for the given column is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getColumnIndex)(OH_Cursor *cursor, const char *name, int *columnIndex); + + /** + * @brief Function pointer. Obtains the column name at the given column index. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param name This parameter is the output parameter, + * and the column name for the given index is written to this variable. + * @param length Indicates the length of the name. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getColumnName)(OH_Cursor *cursor, int32_t columnIndex, char *name, int length); + + /** + * @brief Function pointer. Obtains the numbers of rows in the result set. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param count This parameter is the output parameter, + * and the numbers of rows in the result set is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getRowCount)(OH_Cursor *cursor, int *count); + + /** + * @brief Function pointer. Move the cursor to the next row. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*goToNextRow)(OH_Cursor *cursor); + + /** + * @brief Function pointer. Obtains the size of blob or text. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param size This parameter is the output parameter, + * and the value size of the requested column is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getSize)(OH_Cursor *cursor, int32_t columnIndex, size_t *size); + + /** + * @brief Function pointer. Obtains the value of the requested column as a string. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param value This parameter is the output parameter, + * and the value of the requested column as a char * is written to this variable. + * @param length Indicates the length of the value, it can be obtained through the OH_Cursor_GetSize function. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getText)(OH_Cursor *cursor, int32_t columnIndex, char *value, int length); + + /** + * @brief Function pointer. Obtains the value of the requested column as a int64_t. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param value This parameter is the output parameter, + * and the value of the requested column as a int64_t is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getInt64)(OH_Cursor *cursor, int32_t columnIndex, int64_t *value); + + /** + * @brief Function pointer. Obtains the value of the requested column as a double. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param value This parameter is the output parameter, + * and the value of the requested column as a double is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getReal)(OH_Cursor *cursor, int32_t columnIndex, double *value); + + /** + * @brief Function pointer. Obtains the value of the requested column as a byte array. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param value This parameter is the output parameter, + * and the value of the requested column as a byte array is written to this variable. + * @param length Indicates the length of the value, it can be obtained through the OH_Cursor_GetSize function. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*getBlob)(OH_Cursor *cursor, int32_t columnIndex, unsigned char *value, int length); + + /** + * @brief Function pointer. Obtains Whether the value of the requested column is null. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @param columnIndex Indicates the zero-based column index. + * @param isNull This parameter is the output parameter, + * and the value whether the column value is null is written to this variable. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*isNull)(OH_Cursor *cursor, int32_t columnIndex, bool *isNull); + + /** + * @brief Function pointer. Destroy the result set, releasing all of its resources and making it completely invalid. + * + * @param cursor Represents a pointer to an {@link OH_Cursor} instance. + * @return Returns the status code of the execution. + * @see OH_Cursor. + * @since 10 + */ + int (*destroy)(OH_Cursor *cursor); +} OH_Cursor; + +#ifdef __cplusplus +}; +#endif + +#endif // OH_CURSOR_H diff --git a/distributeddatamgr/relational_store/include/oh_predicates.h b/distributeddatamgr/relational_store/include/oh_predicates.h new file mode 100644 index 000000000..28808e30b --- /dev/null +++ b/distributeddatamgr/relational_store/include/oh_predicates.h @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OH_PREDICATES_H +#define OH_PREDICATES_H + +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + +/** + * @file oh_predicates.h + * + * @brief Declared predicate related functions and enumerations. + * + * @since 10 + */ + +#include +#include +#include "oh_value_object.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Result set sort type. + * + * @since 10 + */ +typedef enum OH_OrderType { + /** + * Ascend order. + */ + ASC = 0, + /** + * Descend order. + */ + DESC = 1, +} OH_OrderType; + +/** + * @brief Define the OH_Predicates structure type. + * + * @since 10 + */ +typedef struct OH_Predicates { + /** + * The id used to uniquely identify the OH_Predicates struct. + */ + int64_t id; + + /** + * @brief Function pointer. Restricts the value of the field to be equal to the specified value to the predicates. + * + * This method is similar to = of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*equalTo)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Restricts the value of the field to be not equal to the specified value to the predicates. + * + * This method is similar to != of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*notEqualTo)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. Add left parenthesis to predicate. + * + * This method is similar to ( of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*beginWrap)(OH_Predicates *predicates); + + /** + * @brief Function pointer. Add right parenthesis to predicate. + * + * This method is similar to ) of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*endWrap)(OH_Predicates *predicates); + + /** + * @brief Function pointer. Adds an or condition to the predicates. + * + * This method is similar to OR of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*orOperate)(OH_Predicates *predicates); + + /** + * @brief Function pointer. Adds an and condition to the predicates. + * + * This method is similar to AND of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*andOperate)(OH_Predicates *predicates); + + /** + * @brief Function pointer. Restricts the value of the field which is null to the predicates. + * + * This method is similar to IS NULL of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*isNull)(OH_Predicates *predicates, const char *field); + + /** + * @brief Function pointer. Restricts the value of the field which is not null to the predicates. + * + * This method is similar to IS NOT NULL of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*isNotNull)(OH_Predicates *predicates, const char *field); + + /** + * @brief Function pointer. Restricts the value of the field to be like the specified value to the predicates. + * + * This method is similar to LIKE of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*like)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. Restricts the value of the field to be between the specified value to the predicates. + * + * This method is similar to BETWEEN of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*between)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Restricts the value of the field to be not between the specified value to the predicates. + * + * This method is similar to NOT BETWEEN of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*notBetween)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Restricts the value of the field to be greater than the specified value to the predicates. + * + * This method is similar to > of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*greaterThan)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Restricts the value of the field to be less than the specified value to the predicates. + * + * This method is similar to < of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*lessThan)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Restricts the value of the field to be greater than or equal to the specified value to the predicates. + * + * This method is similar to >= of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*greaterThanOrEqualTo)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Restricts the value of the field to be less than or equal to the specified value to the predicates. + * + * This method is similar to <= of the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*lessThanOrEqualTo)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. Restricts the ascending or descending order of the return list. + * When there are several orders, the one close to the head has the highest priority. + * + * This method is similar ORDER BY the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param type Indicates the sort {@link OH_OrderType} type. + * @return Returns the self. + * @see OH_Predicates, OH_OrderType. + * @since 10 + */ + OH_Predicates *(*orderBy)(OH_Predicates *predicates, const char *field, OH_OrderType type); + + /** + * @brief Function pointer. Configure predicates to filter duplicate records and retain only one of them. + * + * This method is similar DISTINCT the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*distinct)(OH_Predicates *predicates); + + /** + * @brief Function pointer. Predicate for setting the maximum number of data records. + * + * This method is similar LIMIT the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param value Indicates the maximum number of records. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*limit)(OH_Predicates *predicates, unsigned int value); + + /** + * @brief Function pointer. Configure the predicate to specify the starting position of the returned result. + * + * This method is similar OFFSET the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param rowOffset Indicates the number of rows to offset from the beginning. The value is a positive integer. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*offset)(OH_Predicates *predicates, unsigned int rowOffset); + + /** + * @brief Function pointer. Configure predicates to group query results by specified columns. + * + * This method is similar GROUP BY the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param fields Indicates the column names that the grouping depends on. + * @param length Indicates the length of fields. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*groupBy)(OH_Predicates *predicates, char const *const *fields, int length); + + /** + * @brief Function pointer. + * Configure the predicate to match the specified field and the value within the given array range. + * + * This method is similar IN the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*in)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. + * Configure the predicate to match the specified field and the value not within the given array range. + * + * This method is similar NOT IN the SQL statement. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @param field Indicates the column name in the database table. + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the self. + * @see OH_Predicates, OH_VObject. + * @since 10 + */ + OH_Predicates *(*notIn)(OH_Predicates *predicates, const char *field, OH_VObject *valueObject); + + /** + * @brief Function pointer. Initialize OH_Predicates object. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the self. + * @see OH_Predicates. + * @since 10 + */ + OH_Predicates *(*clear)(OH_Predicates *predicates); + + /** + * @brief Destroy the {@link OH_Predicates} object and reclaim the memory occupied by the object. + * + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * @return Returns the status code of the execution.. + * @see OH_Predicates. + * @since 10 + */ + int (*destroy)(OH_Predicates *predicates); +} OH_Predicates; + +#ifdef __cplusplus +}; +#endif + +#endif // OH_PREDICATES_H diff --git a/distributeddatamgr/relational_store/include/oh_value_object.h b/distributeddatamgr/relational_store/include/oh_value_object.h new file mode 100644 index 000000000..f8ddd1a66 --- /dev/null +++ b/distributeddatamgr/relational_store/include/oh_value_object.h @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* 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. +*/ + +#ifndef OH_VALUE_OBJECT_H +#define OH_VALUE_OBJECT_H + +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + +/** + * @file oh_value_object.h + * + * @brief Provides numeric type conversion functions. + * + * @since 10 + */ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Define the OH_VObject structure type. + * + * @since 10 + */ +typedef struct OH_VObject { + /** + * The id used to uniquely identify the OH_VObject struct. + */ + int64_t id; + + /** + * @brief Convert the int64 input parameter to a value of type {@link OH_VObject}. + * + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @param value Represents a pointer to an int64_t input parameter or the array of type int64_t. + * @param count If value is a pointer to a single numerical value, count = 1; + * if value is a pointer to an array, count is the size of the array. + * @return Returns the status code of the execution. + * @see OH_VObject. + * @since 10 + */ + int (*putInt64)(OH_VObject *valueObject, int64_t *value, uint32_t count); + + /** + * @brief Convert the double input parameter to a value of type {@link OH_VObject}. + * + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @param value Represents a pointer to an double input parameter or the array of type double. + * @param count If value is a pointer to a single numerical value, count = 1; + * if value is a pointer to an array, count is the size of the array. + * @return Returns the status code of the execution. + * @see OH_VObject. + * @since 10 + */ + int (*putDouble)(OH_VObject *valueObject, double *value, uint32_t count); + + /** + * @brief Convert the char input parameter to a value of type {@link OH_VObject}. + * + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @param value Indicates the const char * input parameter. + * @return Returns the status code of the execution. + * @see OH_VObject. + * @since 10 + */ + int (*putText)(OH_VObject *valueObject, const char *value); + + /** + * @brief Convert the char * array input parameter to a value of type {@link OH_VObject}. + * + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @param value Indicates the const char * array input parameter. + * @param count Indicates the size of the value. + * @return Returns the status code of the execution. + * @see OH_VObject. + * @since 10 + */ + int (*putTexts)(OH_VObject *valueObject, const char **value, uint32_t count); + + /** + * @brief Destroy the {@link OH_VObject} object and reclaim the memory occupied by the object. + * + * @param valueObject Represents a pointer to an {@link OH_VObject} instance. + * @return Returns the status code of the execution. + * @see OH_VObject. + * @since 10 + */ + int (*destroy)(OH_VObject *valueObject); +} OH_VObject; + +#ifdef __cplusplus +}; +#endif + +#endif // OH_VALUE_OBJECT_H diff --git a/distributeddatamgr/relational_store/include/oh_values_bucket.h b/distributeddatamgr/relational_store/include/oh_values_bucket.h new file mode 100644 index 000000000..e966956b6 --- /dev/null +++ b/distributeddatamgr/relational_store/include/oh_values_bucket.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OH_VALUES_BUCKET_H +#define OH_VALUES_BUCKET_H + +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + +/** + * @file oh_values_bucket.h + * + * @brief Define the type of stored key value pairs. + * + * @since 10 + */ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Define the OH_VBucket structure type. + * + * @since 10 + */ +typedef struct OH_VBucket { + /** + * The id used to uniquely identify the OH_VBucket struct. + */ + int64_t id; + + /** + * Indicates the capability of OH_VBucket. + */ + uint16_t capability; + + /** + * @brief Put the const char * value to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @param value Indicates the const char * value. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*putText)(OH_VBucket *bucket, const char *field, const char *value); + + /** + * @brief Put the int64 value to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @param value Indicates the int64 value. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*putInt64)(OH_VBucket *bucket, const char *field, int64_t value); + + /** + * @brief Put the double value to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @param value Indicates the double value. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*putReal)(OH_VBucket *bucket, const char *field, double value); + + /** + * @brief Put the const uint8_t * value to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @param value Indicates the const uint8_t * value. + * @param size Indicates the size of value. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*putBlob)(OH_VBucket *bucket, const char *field, const uint8_t *value, uint32_t size); + + /** + * @brief Put NULL to this {@link OH_VBucket} object for the given column name. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @param field Indicates the name of the column. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*putNull)(OH_VBucket *bucket, const char *field); + + /** + * @brief Clear the {@link OH_VBucket} object's values. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*clear)(OH_VBucket *bucket); + + /** + * @brief Destroy the {@link OH_VBucket} object and reclaim the memory occupied by the object. + * + * @param bucket Represents a pointer to an {@link OH_VBucket} instance. + * @return Returns the status code of the execution. + * @see OH_VBucket. + * @since 10 + */ + int (*destroy)(OH_VBucket *bucket); +} OH_VBucket; + +#ifdef __cplusplus +}; +#endif + +#endif // OH_VALUES_BUCKET_H diff --git a/distributeddatamgr/relational_store/include/relational_store.h b/distributeddatamgr/relational_store/include/relational_store.h new file mode 100644 index 000000000..7b009ec34 --- /dev/null +++ b/distributeddatamgr/relational_store/include/relational_store.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef RELATIONAL_STORE_H +#define RELATIONAL_STORE_H + +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + +/** + * @file relational_store.h + * + * @brief Provides database related functions and enumerations. + * + * @since 10 + */ + +#include "oh_cursor.h" +#include "oh_predicates.h" +#include "oh_value_object.h" +#include "oh_values_bucket.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Describe the security level of the database. + * + * @since 10 + */ +typedef enum OH_Rdb_SecurityLevel { + /** + * @brief Low-level security. Data leaks have a minor impact. + */ + S1 = 1, + /** + * @brief Medium-level security. Data leaks have a major impact. + */ + S2, + /** + * @brief High-level security. Data leaks have a severe impact. + */ + S3, + /** + * @brief Critical-level security. Data leaks have a critical impact. + */ + S4 +} OH_Rdb_SecurityLevel; + +/** + * @brief Manages relational database configurations. + * + * @since 10 + */ +#pragma pack(1) +typedef struct { + /** + * Indicates the size of the {@link OH_Rdb_Config}. It is mandatory. + */ + int selfSize; + /** + * Indicates the directory of the database. + */ + const char *dataBaseDir; + /** + * Indicates the name of the database. + */ + const char *storeName; + /** + * Indicates the bundle name of the application. + */ + const char *bundleName; + /** + * Indicates the module name of the application. + */ + const char *moduleName; + /** + * Indicates whether the database is encrypted. + */ + bool isEncrypt; + /** + * Indicates the security level {@link OH_Rdb_SecurityLevel} of the database. + */ + int securityLevel; +} OH_Rdb_Config; +#pragma pack() + +/** + * @brief Define OH_Rdb_Store type. + * + * @since 10 + */ +typedef struct { + /** + * The id used to uniquely identify the OH_Rdb_Store struct. + */ + int64_t id; +} OH_Rdb_Store; + +/** + * @brief Creates an {@link OH_VObject} instance. + * + * @return If the creation is successful, a pointer to the instance of the @link OH_VObject} structure is returned, + * otherwise NULL is returned. + * @see OH_VObject. + * @since 10 + */ +OH_VObject *OH_Rdb_CreateValueObject(); + +/** + * @brief Creates an {@link OH_VBucket} object. + * + * @return If the creation is successful, a pointer to the instance of the @link OH_VBucket} structure is returned, + * otherwise NULL is returned. + * @see OH_VBucket. + * @since 10 + */ +OH_VBucket *OH_Rdb_CreateValuesBucket(); + +/** + * @brief Creates an {@link OH_Predicates} instance. + * + * @param table Indicates the table name. + * @return If the creation is successful, a pointer to the instance of the @link OH_Predicates} structure is returned, + * otherwise NULL is returned. + * @see OH_Predicates. + * @since 10 + */ +OH_Predicates *OH_Rdb_CreatePredicates(const char *table); + +/** + * @brief Obtains an RDB store. + * + * You can set parameters of the RDB store as required. In general, + * this method is recommended to obtain a rdb store. + * + * @param config Represents a pointer to an {@link OH_Rdb_Config} instance. + * Indicates the configuration of the database related to this RDB store. + * @param errCode This parameter is the output parameter, + * and the execution status of a function is written to this variable. + * @return If the creation is successful, a pointer to the instance of the @link OH_Rdb_Store} structure is returned, + * otherwise NULL is returned. + * @see OH_Rdb_Config, OH_Rdb_Store. + * @since 10 + */ +OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode); + +/** + * @brief Close the {@link OH_Rdb_Store} object and reclaim the memory occupied by the object. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @return Returns the status code of the execution. Successful execution returns RDB_OK, + * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_Store, OH_Rdb_ErrCode. + * @since 10 + */ +int OH_Rdb_CloseStore(OH_Rdb_Store *store); + +/** + * @brief Deletes the database with a specified path. + * + * @param config Represents a pointer to an {@link OH_Rdb_Config} instance. + * Indicates the configuration of the database related to this RDB store. + * @return Returns the status code of the execution. Successful execution returns RDB_OK, + * while failure returns a specific error code. Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_ErrCode. + * @since 10 + */ +int OH_Rdb_DeleteStore(const OH_Rdb_Config *config); + +/** + * @brief Inserts a row of data into the target table. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param table Indicates the target table. + * @param valuesBucket Indicates the row of data {@link OH_VBucket} to be inserted into the table. + * @return Returns the rowId if success, returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_Store, OH_VBucket, OH_Rdb_ErrCode. + * @since 10 + */ +int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket); + +/** + * @brief Updates data in the database based on specified conditions. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param valuesBucket Indicates the row of data {@link OH__VBucket} to be updated in the database + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * Indicates the specified update condition. + * @return Returns the number of rows changed if success, otherwise, returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_Store, OH_Bucket, OH_Predicates, OH_Rdb_ErrCode. + * @since 10 + */ +int OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates *predicates); + +/** + * @brief Deletes data from the database based on specified conditions. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * Indicates the specified delete condition. + * @return Returns the number of rows changed if success, otherwise, returns a specific error code. + * Specific error codes can be referenced {@link OH_Rdb_ErrCode}. + * @see OH_Rdb_Store, OH_Predicates, OH_Rdb_ErrCode. + * @since 10 + */ +int OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates); + +/** + * @brief Queries data in the database based on specified conditions. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param predicates Represents a pointer to an {@link OH_Predicates} instance. + * Indicates the specified query condition. + * @param columnNames Indicates the columns to query. If the value is empty array, the query applies to all columns. + * @param length Indicates the length of columnNames. + * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned, + * otherwise NULL is returned. + * @see OH_Rdb_Store, OH_Predicates, OH_Cursor. + * @since 10 + */ +OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length); + +/** + * @brief Executes an SQL statement. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param sql Indicates the SQL statement to execute. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql); + +/** + * @brief Queries data in the database based on an SQL statement. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param sql Indicates the SQL statement to execute. + * @return If the query is successful, a pointer to the instance of the @link OH_Cursor} structure is returned, + * otherwise NULL is returned. + * @see OH_Rdb_Store. + * @since 10 + */ +OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql); + +/** + * @brief Begins a transaction in EXCLUSIVE mode. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_BeginTransaction(OH_Rdb_Store *store); + +/** + * @brief Rolls back a transaction in EXCLUSIVE mode. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_RollBack(OH_Rdb_Store *store); + +/** + * @brief Commits a transaction in EXCLUSIVE mode. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_Commit(OH_Rdb_Store *store); + +/** + * @brief Backs up a database on specified path. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param databasePath Indicates the database file path. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath); + +/** + * @brief Restores a database from a specified database file. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param databasePath Indicates the database file path. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath); + +/** + * @brief Gets the version of a database. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param version Indicates the version number. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version); + +/** + * @brief Sets the version of a database. + * + * @param store Represents a pointer to an {@link OH_Rdb_Store} instance. + * @param version Indicates the version number. + * @return Returns the status code of the execution. + * @see OH_Rdb_Store. + * @since 10 + */ +int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version); + +#ifdef __cplusplus +}; +#endif + +#endif // RELATIONAL_STORE_H diff --git a/distributeddatamgr/relational_store/include/relational_store_error_code.h b/distributeddatamgr/relational_store/include/relational_store_error_code.h new file mode 100644 index 000000000..6efa0ee28 --- /dev/null +++ b/distributeddatamgr/relational_store/include/relational_store_error_code.h @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef RELATIONAL_STORE_ERRNO_CODE_H +#define RELATIONAL_STORE_ERRNO_CODE_H + +/** + * @addtogroup RDB + * @{ + * + * @brief The relational database (RDB) store manages data based on relational models. + * With the underlying SQLite database, the RDB store provides a complete mechanism for managing local databases. + * To satisfy different needs in complicated scenarios, the RDB store offers a series of APIs for performing operations + * such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + * + * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core + * @since 10 + */ + + +/** + * @file relational_store_error_code.h + * + * @brief Declaration error code information. + * + * @since 10 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Indicates the error code information. + * + * @since 10 + */ +typedef enum OH_Rdb_ErrCode { + /** + * Indicates that the function execution exception. + */ + RDB_ERR = -1, + + /** + * The error code in the correct case. + */ + RDB_OK = 0, + + /** + * @brief The base code of the exception error code. + */ + E_BASE = 14800000, + + /** + * @brief The error when the capability not supported. + */ + RDB_E_NOT_SUPPORTED = 801, + + /** + * @brief The error code for common exceptions. + */ + RDB_E_ERROR = E_BASE, + + /** + * @brief The error code for common invalid args. + */ + RDB_E_INVALID_ARGS = (E_BASE + 1), + + /** + * @brief The error code for upgrade the read-only store. + */ + RDB_E_CANNOT_UPDATE_READONLY = (E_BASE + 2), + + /** + * @brief The error code when deleting a file fails. + */ + RDB_E_REMOVE_FILE = (E_BASE + 3), + + /** + * @brief The error code for a table name is empty. + */ + RDB_E_EMPTY_TABLE_NAME = (E_BASE + 5), + + /** + * @brief The error code for a values bucket is empty. + */ + RDB_E_EMPTY_VALUES_BUCKET = (E_BASE + 6), + + /** + * @brief The error code when the sql is not select. + */ + RDB_E_EXECUTE_IN_STEP_QUERY = (E_BASE + 7), + + /** + * @brief The error code for the column index is invalid. + */ + RDB_E_INVALID_COLUMN_INDEX = (E_BASE + 8), + + /** + * @brief The error code for the column type is invalid. + */ + RDB_E_INVALID_COLUMN_TYPE = (E_BASE + 9), + + /** + * @brief The error code for a file name is empty. + */ + RDB_E_EMPTY_FILE_NAME = (E_BASE + 10), + + /** + * @brief The error for the current file path is invalid. + */ + RDB_E_INVALID_FILE_PATH = (E_BASE + 11), + + /** + * @brief The error code when using transactions. + */ + RDB_E_TRANSACTION_IN_EXECUTE = (E_BASE + 12), + + /** + * @brief The error code for the current status is invalid. + */ + RDB_E_INVALID_STATEMENT = (E_BASE + 13), + + /** + * @brief The error code when execute write operation in read connection. + */ + RDB_E_EXECUTE_WRITE_IN_READ_CONNECTION = (E_BASE + 14), + + /** + * @brief The error code for execute begin transaction operation in read connection. + */ + RDB_E_BEGIN_TRANSACTION_IN_READ_CONNECTION = (E_BASE + 15), + + /** + * @brief The error code for there are no transactions in this connection. + */ + RDB_E_NO_TRANSACTION_IN_SESSION = (E_BASE + 16), + + /** + * @brief The error code when begin more step query in one session. + */ + RDB_E_MORE_STEP_QUERY_IN_ONE_SESSION = (E_BASE + 17), + + /** + * @brief The error code when the current statement doesn't contains one row result data. + */ + RDB_E_NO_ROW_IN_QUERY = (E_BASE + 18), + + /** + * @brief The error code for the bind arguments count is invalid. + */ + RDB_E_INVALID_BIND_ARGS_COUNT = (E_BASE + 19), + + /** + * @brief The error code for the object type is invalid. + */ + RDB_E_INVALID_OBJECT_TYPE = (E_BASE + 20), + + /** + * @brief The error code for the conflict flag is invalid. + */ + RDB_E_INVALID_CONFLICT_FLAG = (E_BASE + 21), + + /** + * @brief The error code for having clause not in group. + */ + RDB_E_HAVING_CLAUSE_NOT_IN_GROUP_BY = (E_BASE + 22), + + /** + * @brief The error code for not supported by step result set. + */ + RDB_E_NOT_SUPPORTED_BY_STEP_RESULT_SET = (E_BASE + 23), + + /** + * @brief The error code for step result current tid not equal to object's tid. + */ + RDB_E_STEP_RESULT_SET_CROSS_THREADS = (E_BASE + 24), + + /** + * @brief The error code when the result query was not executed. + */ + RDB_E_STEP_RESULT_QUERY_NOT_EXECUTED = (E_BASE + 25), + + /** + * @brief The error code for the result set cursor is after the last row. + */ + RDB_E_STEP_RESULT_IS_AFTER_LAST = (E_BASE + 26), + + /** + * @brief The error code for the result set query exceeded. + */ + RDB_E_STEP_RESULT_QUERY_EXCEEDED = (E_BASE + 27), + + /** + * @brief The error code for the statement not prepared. + */ + RDB_E_STATEMENT_NOT_PREPARED = (E_BASE + 28), + + /** + * @brief The error code for the result set is incorrect. + */ + RDB_E_EXECUTE_RESULT_INCORRECT = (E_BASE + 29), + + /** + * @brief The error code when the result set is closed. + */ + RDB_E_STEP_RESULT_CLOSED = (E_BASE + 30), + + /** + * @brief The error code when input relative path. + */ + RDB_E_RELATIVE_PATH = (E_BASE + 31), + + /** + * @brief The error code for the new encrypt key is empty. + */ + RDB_E_EMPTY_NEW_ENCRYPT_KEY = (E_BASE + 32), + + /** + * @brief The error code for change unencrypted to encrypted. + */ + RDB_E_CHANGE_UNENCRYPTED_TO_ENCRYPTED = (E_BASE + 33), + + /** + * @brief The error code for change encrypt in busy. + */ + RDB_E_CHANGE_ENCRYPT_KEY_IN_BUSY = (E_BASE + 34), + + /** + * @brief The error code when the statement not initialized. + */ + RDB_E_STEP_STATEMENT_NOT_INIT = (E_BASE + 35), + + /** + * @brief The error code for the attach is not supported in WAL journal mode. + */ + RDB_E_NOT_SUPPORTED_ATTACH_IN_WAL_MODE = (E_BASE + 36), + + /** + * @brief The error code when create folder failed. + */ + RDB_E_CREATE_FOLDER_FAIL = (E_BASE + 37), + + /** + * @brief The error for SQL builder normalize failed. + */ + RDB_E_SQLITE_SQL_BUILDER_NORMALIZE_FAIL = (E_BASE + 38), + + /** + * @brief The error for store session not give connection temporarily. + */ + RDB_E_STORE_SESSION_NOT_GIVE_CONNECTION_TEMPORARILY = (E_BASE + 39), + + /** + * @brief The error for store session not current transaction. + */ + RDB_E_STORE_SESSION_NO_CURRENT_TRANSACTION = (E_BASE + 40), + + /** + * @brief The error for not supported the current operation. + */ + RDB_E_NOT_SUPPORT = (E_BASE + 41), + + /** + * @brief The error for the current parcel is invalid. + */ + RDB_E_INVALID_PARCEL = (E_BASE + 42), + + /** + * @brief The error code when using sqlite3_step function failed. + */ + RDB_E_QUERY_IN_EXECUTE = (E_BASE + 43), + + /** + * @brief The error for set persist WAL. + */ + RDB_E_SET_PERSIST_WAL = (E_BASE + 44), + + /** + * @brief The error when the database does not exist. + */ + RDB_E_DB_NOT_EXIST = (E_BASE + 45), + + /** + * @brief The error when the read connection count is overload. + */ + RDB_E_ARGS_READ_CON_OVERLOAD = (E_BASE + 46), + + /** + * @brief The error when the wal file size over default limit. + */ + RDB_E_WAL_SIZE_OVER_LIMIT = (E_BASE + 47), + + /** + * @brief The error when the connection count is used up. + */ + RDB_E_CON_OVER_LIMIT = (E_BASE + 48) +} OH_Rdb_ErrCode; + +#ifdef __cplusplus +}; +#endif + +#endif // RELATIONAL_STORE_ERRNO_CODE_H \ No newline at end of file diff --git a/distributeddatamgr/relational_store/libnative_rdb.ndk.json b/distributeddatamgr/relational_store/libnative_rdb.ndk.json new file mode 100644 index 000000000..84901bb54 --- /dev/null +++ b/distributeddatamgr/relational_store/libnative_rdb.ndk.json @@ -0,0 +1,21 @@ +[ + {"name":"OH_Rdb_CreatePredicates" }, + {"name":"OH_Rdb_CreateValueObject" }, + {"name":"OH_Rdb_CreateValuesBucket" }, + {"name":"OH_Rdb_GetOrOpen" }, + {"name":"OH_Rdb_CloseStore" }, + {"name":"OH_Rdb_DeleteStore" }, + {"name":"OH_Rdb_Insert" }, + {"name":"OH_Rdb_Update" }, + {"name":"OH_Rdb_Delete" }, + {"name":"OH_Rdb_Query" }, + {"name":"OH_Rdb_Execute" }, + {"name":"OH_Rdb_ExecuteQuery" }, + {"name":"OH_Rdb_BeginTransaction" }, + {"name":"OH_Rdb_RollBack" }, + {"name":"OH_Rdb_Commit" }, + {"name":"OH_Rdb_Backup" }, + {"name":"OH_Rdb_Restore"}, + {"name":"OH_Rdb_GetVersion"}, + {"name":"OH_Rdb_SetVersion"} +] \ No newline at end of file diff --git a/drivers/external_device_manager/usb/BUILD.gn b/drivers/external_device_manager/usb/BUILD.gn new file mode 100644 index 000000000..36f24db18 --- /dev/null +++ b/drivers/external_device_manager/usb/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_headers("usb_header") { + dest_dir = "$ndk_headers_out_dir/usb/" + sources = [ + "usb_ddk_api.h", + "usb_ddk_types.h", + ] +} + +ohos_ndk_library("libusb_ndk") { + ndk_description_file = "./libusb.ndk.json" + min_compact_version = "9" + output_name = "usb_ndk" + system_capability = "SystemCapability.Driver.USB.Extension" + system_capability_headers = [ + "usb/usb_ddk_api.h", + "usb/usb_ddk_types.h", + ] +} diff --git a/drivers/external_device_manager/usb/libusb.ndk.json b/drivers/external_device_manager/usb/libusb.ndk.json new file mode 100644 index 000000000..4cc70335e --- /dev/null +++ b/drivers/external_device_manager/usb/libusb.ndk.json @@ -0,0 +1,44 @@ +[ + { + "name": "OH_Usb_Init" + }, + { + "name": "OH_Usb_Release" + }, + { + "name": "OH_Usb_GetDeviceDescriptor" + }, + { + "name": "OH_Usb_GetConfigDescriptor" + }, + { + "name": "OH_Usb_FreeConfigDescriptor" + }, + { + "name": "OH_Usb_ClaimInterface" + }, + { + "name": "OH_Usb_ReleaseInterface" + }, + { + "name": "OH_Usb_SelectInterfaceSetting" + }, + { + "name": "OH_Usb_GetCurrentInterfaceSetting" + }, + { + "name": "OH_Usb_SendControlReadRequest" + }, + { + "name": "OH_Usb_SendControlWriteRequest" + }, + { + "name": "OH_Usb_SendPipeRequest" + }, + { + "name": "OH_Usb_CreateDeviceMemMap" + }, + { + "name": "OH_Usb_DestroyDeviceMemMap" + } +] \ No newline at end of file diff --git a/drivers/external_device_manager/usb/usb_ddk_api.h b/drivers/external_device_manager/usb/usb_ddk_api.h new file mode 100644 index 000000000..e7b08a575 --- /dev/null +++ b/drivers/external_device_manager/usb/usb_ddk_api.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +#ifndef USB_DDK_API_H +#define USB_DDK_API_H + +/** + * @addtogroup UsbDdk + * @{ + * + * @brief Provides USB DDK APIs to open and close USB interfaces, perform non-isochronous and isochronous\n + * data transfer over USB pipes, and implement control transfer and interrupt transfer, etc. + * + * @syscap SystemCapability.Driver.USB.Extension + * @since 10 + * @version 1.0 + */ + +/** + * @file usb_ddk_api.h + * + * @brief Declares the USB DDK APIs used by the USB host to access USB devices. + * + * @since 10 + * @version 1.0 + */ + +#include + +#include "usb_ddk_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Initializes the DDK. + * + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_Init(void); + +/** + * @brief Releases the DDK. + * + * @since 10 + * @version 1.0 + */ +void OH_Usb_Release(void); + +/** + * @brief Obtains the USB device descriptor. + * + * @param deviceId ID of the device whose descriptor is to be obtained. + * @param desc Standard device descriptor defined in the USB protocol. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_GetDeviceDescriptor(uint64_t deviceId, struct UsbDeviceDescriptor *desc); + +/** + * @brief Obtains the configuration descriptor. To avoid memory leakage, use OH_Usb_FreeConfigDescriptor\n + * to release a descriptor after use. + * + * @param deviceId ID of the device whose configuration descriptor is to be obtained. + * @param configIndex Configuration index, which corresponds to bConfigurationValue in the USB protocol. + * @param config Configuration descriptor, which includes the standard configuration descriptor defined in the\n + * USB protocol and the associated interface descriptor and endpoint descriptor. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_GetConfigDescriptor( + uint64_t deviceId, uint8_t configIndex, struct UsbDdkConfigDescriptor ** const config); + +/** + * @brief Releases the configuration descriptor. To avoid memory leakage, use OH_Usb_FreeConfigDescriptor\n + * to release a descriptor after use. + * + * @param config Configuration descriptor obtained by calling OH_Usb_GetConfigDescriptor. + * @since 10 + * @version 1.0 + */ +void OH_Usb_FreeConfigDescriptor(struct UsbDdkConfigDescriptor * const config); + +/** + * @brief Claims a USB interface. + * + * @param deviceId ID of the device to be operated. + * @param interfaceIndex Interface index, which corresponds to bInterfaceNumber in the USB protocol. + * @param interfaceHandle Interface operation handle. After the interface is claimed successfully, a value will be\n + * assigned to this parameter. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_ClaimInterface(uint64_t deviceId, uint8_t interfaceIndex, uint64_t *interfaceHandle); + +/** + * @brief Releases a USB interface. + * + * @param interfaceHandle Interface operation handle. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_ReleaseInterface(uint64_t interfaceHandle); + +/** + * @brief Activates the alternate setting of the USB interface. + * + * @param interfaceHandle Interface operation handle. + * @param settingIndex Index of the alternate setting, which corresponds to bAlternateSetting\n + * in the USB protocol. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_SelectInterfaceSetting(uint64_t interfaceHandle, uint8_t settingIndex); + +/** + * @brief Obtains the activated alternate setting of the USB interface. + * + * @param interfaceHandle Interface operation handle. + * @param settingIndex Index of the alternate setting, which corresponds to bAlternateSetting\n + * in the USB protocol. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_GetCurrentInterfaceSetting(uint64_t interfaceHandle, uint8_t *settingIndex); + +/** + * @brief Sends a control read transfer request. This API works in a synchronous manner. + * + * @param interfaceHandle Interface operation handle. + * @param setup Request data, which corresponds to Setup Data in the USB protocol. + * @param timeout Timeout duration, in milliseconds. + * @param data Data to be transferred. + * @param dataLen Data length. The return value indicates the length of the actually read data. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_SendControlReadRequest(uint64_t interfaceHandle, const struct UsbControlRequestSetup *setup, + uint32_t timeout, uint8_t *data, uint32_t *dataLen); + +/** + * @brief Sends a control write transfer request. This API works in a synchronous manner. + * + * @param interfaceHandle Interface operation handle. + * @param setup Request data, which corresponds to Setup Data in the USB protocol. + * @param timeout Timeout duration, in milliseconds. + * @param data Data to be transferred. + * @param dataLen Data length. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_SendControlWriteRequest(uint64_t interfaceHandle, const struct UsbControlRequestSetup *setup, + uint32_t timeout, const uint8_t *data, uint32_t dataLen); + +/** + * @brief Sends a pipe request. This API works in a synchronous manner. This API applies to interrupt transfer\n + * and bulk transfer. + * + * @param pipe Pipe used to transfer data. + * @param devMmap Device memory map, which can be obtained by calling OH_Usb_CreateDeviceMemMap. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_SendPipeRequest(const struct UsbRequestPipe *pipe, UsbDeviceMemMap *devMmap); + +/** + * @brief Creates a buffer. To avoid resource leakage, destroy a buffer by calling\n + * OH_Usb_DestroyDeviceMemMap after use. + * + * @param deviceId ID of the device for which the buffer is to be created. + * @param size Buffer size. + * @param devMmap Data memory map, through which the created buffer is returned to the caller. + * @return 0 if the operation is successful; a negative value otherwise. + * @since 10 + * @version 1.0 + */ +int32_t OH_Usb_CreateDeviceMemMap(uint64_t deviceId, size_t size, UsbDeviceMemMap **devMmap); + +/** + * @brief Destroys a buffer. To avoid resource leakage, destroy a buffer in time after use. + * + * @param devMmap Device memory map created by calling OH_Usb_CreateDeviceMemMap. + * @since 10 + * @version 1.0 + */ +void OH_Usb_DestroyDeviceMemMap(UsbDeviceMemMap *devMmap); +/** @} */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // USB_DDK_API_H \ No newline at end of file diff --git a/drivers/external_device_manager/usb/usb_ddk_types.h b/drivers/external_device_manager/usb/usb_ddk_types.h new file mode 100644 index 000000000..db511e064 --- /dev/null +++ b/drivers/external_device_manager/usb/usb_ddk_types.h @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef USB_DDK_TYPES_H +#define USB_DDK_TYPES_H +/** + * @addtogroup UsbDdk + * @{ + * + * @brief Provides USB DDK types and declares the macros, enumerated variables, and\n + * data structures required by the USB DDK APIs. + * + * @syscap SystemCapability.Driver.USB.Extension + * @since 10 + * @version 1.0 + */ + +/** + * @file usb_ddk_types.h + * + * @brief Provides the enumerated variables, structures, and macros used in USB DDK APIs. + * + * @since 10 + * @version 1.0 + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/** + * @brief Setup data for control transfer. It corresponds to Setup Data in the USB protocol. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbControlRequestSetup { + /** Request type. */ + uint8_t bmRequestType; + /** Request command. */ + uint8_t bRequest; + /** Its meaning varies according to the request. */ + uint16_t wValue; + /** It is usually used to transfer the index or offset.\n + * Its meaning varies according to the request. + */ + uint16_t wIndex; + /** Data length. If data is transferred,\n + * this field indicates the number of transferred bytes. + */ + uint16_t wLength; +} __attribute__((aligned(8))) UsbControlRequestSetup; + +/** + * @brief Standard device descriptor, corresponding to Standard Device Descriptor in the USB protocol. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbDeviceDescriptor { + /** Size of the descriptor, in bytes. */ + uint8_t bLength; + /** Descriptor type. */ + uint8_t bDescriptorType; + /** USB protocol release number. */ + uint16_t bcdUSB; + /** Device class code allocated by the USB-IF. */ + uint8_t bDeviceClass; + /** Device subclass code allocated by USB-IF. The value is limited by that of bDeviceClass. */ + uint8_t bDeviceSubClass; + /** Protocol code allocated by USB-IF. The value is limited by that of bDeviceClass and bDeviceSubClass. */ + uint8_t bDeviceProtocol; + /** Maximum packet size of endpoint 0. Only values 8, 16, 32, and 64 are valid. */ + uint8_t bMaxPacketSize0; + /** Vendor ID allocated by USB-IF. */ + uint16_t idVendor; + /** Product ID allocated by the vendor. */ + uint16_t idProduct; + /** Device release number. */ + uint16_t bcdDevice; + /** Index of the string descriptor that describes the vendor. */ + uint8_t iManufacturer; + /** Index of the string descriptor that describes the product. */ + uint8_t iProduct; + /** Index of the string descriptor that describes the device SN. */ + uint8_t iSerialNumber; + /** Configuration quantity. */ + uint8_t bNumConfigurations; +} __attribute__((aligned(8))) UsbDeviceDescriptor; + +/** + * @brief Standard configuration descriptor, corresponding to Standard Configuration Descriptor\n + * in the USB protocol. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbConfigDescriptor { + /** Size of the descriptor, in bytes. */ + uint8_t bLength; + /** Descriptor type. */ + uint8_t bDescriptorType; + /** Total length of the configuration descriptor, including the configuration, interface, endpoint,\n + * and class- or vendor-specific descriptors. + */ + uint16_t wTotalLength; + /** Number of interfaces supported by the configuration. */ + uint8_t bNumInterfaces; + /** Configuration index, which is used to select the configuration. */ + uint8_t bConfigurationValue; + /** Index of the string descriptor that describes the configuration. */ + uint8_t iConfiguration; + /** Configuration attributes, including the power mode and remote wakeup. */ + uint8_t bmAttributes; + /** Maximum power consumption of the bus-powered USB device, in 2 mA. */ + uint8_t bMaxPower; +} __attribute__((packed)) UsbConfigDescriptor; + +/** + * @brief Standard interface descriptor, corresponding to Standard Interface Descriptor + * in the USB protocol. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbInterfaceDescriptor { + /** Size of the descriptor, in bytes. */ + uint8_t bLength; + /** Descriptor type. */ + uint8_t bDescriptorType; + /** Interface number. */ + uint8_t bInterfaceNumber; + /** Value used to select the alternate setting of the interface. */ + uint8_t bAlternateSetting; + /** Number of endpoints (excluding endpoint 0) used by the interface. */ + uint8_t bNumEndpoints; + /** Interface class code allocated by the USB-IF. */ + uint8_t bInterfaceClass; + /** Interface subclass code allocated by USB-IF. The value is limited by that of bInterfaceClass. */ + uint8_t bInterfaceSubClass; + /** Protocol code allocated by USB-IF. The value is limited by that of bInterfaceClass and bInterfaceSubClass. */ + uint8_t bInterfaceProtocol; + /** Index of the string descriptor that describes the interface. */ + uint8_t iInterface; +} __attribute__((packed)) UsbInterfaceDescriptor; + +/** + * @brief Standard endpoint descriptor, corresponding to Standard Endpoint Descriptor in the USB protocol. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbEndpointDescriptor { + /** Size of the descriptor, in bytes. */ + uint8_t bLength; + /** Descriptor type. */ + uint8_t bDescriptorType; + /** Endpoint address, including the endpoint number and endpoint direction. */ + uint8_t bEndpointAddress; + /** Endpoint attributes, including the transfer type, synchronization type, and usage type. */ + uint8_t bmAttributes; + /** Maximum packet size supported by an endpoint. */ + uint16_t wMaxPacketSize; + /** Interval for polling endpoints for data transfer. */ + uint8_t bInterval; + /** Refresh rate for audio devices. */ + uint8_t bRefresh; + /** Endpoint synchronization address for audio devices. */ + uint8_t bSynchAddress; +} __attribute__((packed)) UsbEndpointDescriptor; + +/** + * @brief Endpoint descriptor. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbDdkEndpointDescriptor { + /** Standard endpoint descriptor. */ + struct UsbEndpointDescriptor endpointDescriptor; + /** Unresolved descriptor, including class- or vendor-specific descriptors. */ + const uint8_t *extra; + /** Length of the unresolved descriptor. */ + uint32_t extraLength; +} UsbDdkEndpointDescriptor; + +/** + * @brief Interface descriptor. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbDdkInterfaceDescriptor { + /** Standard interface descriptor. */ + struct UsbInterfaceDescriptor interfaceDescriptor; + /** Endpoint descriptor contained in the interface. */ + struct UsbDdkEndpointDescriptor *endPoint; + /** Unresolved descriptor, including class- or vendor-specific descriptors. */ + const uint8_t *extra; + /** Length of the unresolved descriptor. */ + uint32_t extraLength; +} UsbDdkInterfaceDescriptor; + +/** + * @brief USB interface. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbDdkInterface { + /** Number of alternate settings of the interface. */ + uint8_t numAltsetting; + /** Alternate setting of the interface. */ + struct UsbDdkInterfaceDescriptor *altsetting; +} UsbDdkInterface; + +/** + * @brief Configuration descriptor. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbDdkConfigDescriptor { + /** Standard configuration descriptor. */ + struct UsbConfigDescriptor configDescriptor; + /** Interfaces contained in the configuration. */ + struct UsbDdkInterface *interface; + /** Unresolved descriptor, including class- or vendor-specific descriptors. */ + const uint8_t *extra; + /** Length of the unresolved descriptor. */ + uint32_t extraLength; +} UsbDdkConfigDescriptor; + +/** + * @brief Request pipe. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbRequestPipe { + /** Interface operation handle. */ + uint64_t interfaceHandle; + /** Timeout duration, in milliseconds. */ + uint32_t timeout; + /** Endpoint address. */ + uint8_t endpoint; +} __attribute__((aligned(8))) UsbRequestPipe; + +/** + * @brief Device memory map created by calling OH_Usb_CreateDeviceMemMap.\n + * A buffer using the device memory map can provide better performance. + * + * @since 10 + * @version 1.0 + */ +typedef struct UsbDeviceMemMap { + /** Buffer address. */ + uint8_t * const address; + /** Buffer size. */ + const size_t size; + /** Offset of the used buffer. The default value is 0, indicating that there is no offset\n + * and the buffer starts from the specified address. + */ + uint32_t offset; + /** Length of the used buffer. By default, the value is equal to the size, indicating that\n + * the entire buffer is used. + */ + uint32_t bufferLength; + /** Length of the transferred data. */ + uint32_t transferedLength; +} UsbDeviceMemMap; + +/** + * @brief Defines error codes for USB DDK. + * + * @since 10 + * @version 1.0 + */ +typedef enum { + /** The operation is successful. */ + USB_DDK_SUCCESS = 0, + /** The operation failed. */ + USB_DDK_FAILED = -1, + /** Invalid parameter. */ + USB_DDK_INVALID_PARAMETER = -2, + /** Memory-related error, for example, insufficient memory, memory data copy failure, or memory application failure. + */ + USB_DDK_MEMORY_ERROR = -3, + /** Invalid operation. */ + USB_DDK_INVALID_OPERATION = -4, + /** Null pointer exception */ + USB_DDK_NULL_PTR = -5, + /** Device busy. */ + USB_DDK_DEVICE_BUSY = -6, + /** Transmission timeout. */ + USB_DDK_TIMEOUT = -7 +} UsbDdkErrCode; +#ifdef __cplusplus +} +/** @} */ +#endif /* __cplusplus */ +#endif // USB_DDK_TYPES_H \ No newline at end of file diff --git a/global/resource_management/BUILD.gn b/global/resource_management/BUILD.gn new file mode 100644 index 000000000..d5c9057ab --- /dev/null +++ b/global/resource_management/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("librawfile_ndk") { + ndk_description_file = "./librawfile.ndk.json" + min_compact_version = "1" + output_name = "rawfile" +} + +ohos_ndk_headers("rawfile_header") { + dest_dir = "$ndk_headers_out_dir/rawfile" + sources = [ + "./include/raw_dir.h", + "./include/raw_file.h", + "./include/raw_file_manager.h", + ] +} diff --git a/global/resource_management/include/raw_dir.h b/global/resource_management/include/raw_dir.h new file mode 100644 index 000000000..76a618ecc --- /dev/null +++ b/global/resource_management/include/raw_dir.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup rawfile + * @{ + * + * @brief Provides native functions for the resource manager to operate raw file directories and their raw files. + * + * You can use the resource manager to traverse, open, seek, read, and close raw files. + * + * @since 8 + * @version 1.0 + */ + +/** + * @file raw_dir.h + * + * @brief Declares native functions related to raw file directories. + * + * For example, you can use the functions to traverse and close a raw file directory, and reset its index. + * + * @since 8 + * @version 1.0 + */ +#ifndef GLOBAL_RAW_DIR_H +#define GLOBAL_RAW_DIR_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct RawDir; + +/** + * @brief Provides access to a raw file directory. + * + * + * + * @since 8 + * @version 1.0 + */ +typedef struct RawDir RawDir; + +/** + * @brief Obtains the name of the file according to the index. + * + * You can use this method to traverse a raw file directory. + * + * @param rawDir Indicates the pointer to {@link RawDir}. + * @param index Indicates the file index in {@link RawDir}. + * @return Returns the name of the file according to the index, + * which can be passed to {@link OH_ResourceManager_OpenRawFile} as an input parameter; + * returns NULL if all files are returned. + * @see OH_ResourceManager_OpenRawFile + * @since 8 + * @version 1.0 + */ +const char *OH_ResourceManager_GetRawFileName(RawDir *rawDir, int index); + +/** + * @brief get the count of the raw files in {@link RawDir}. + * + * You can use this method to get the valid index of {@link OH_ResourceManager_GetRawFileName}. + * + * @param rawDir Indicates the pointer to {@link RawDir}. + * @see OH_ResourceManager_GetRawFileName + * @since 8 + * @version 1.0 + */ +int OH_ResourceManager_GetRawFileCount(RawDir *rawDir); + +/** + * @brief Closes an opened {@link RawDir} and releases all associated resources. + * + * + * + * @param rawDir Indicates the pointer to {@link RawDir}. + * @see OH_ResourceManager_OpenRawDir + * @since 8 + * @version 1.0 + */ +void OH_ResourceManager_CloseRawDir(RawDir *rawDir); + +#ifdef __cplusplus +}; +#endif + +/** @} */ +#endif // GLOBAL_RAW_DIR_H diff --git a/global/resource_management/include/raw_file.h b/global/resource_management/include/raw_file.h new file mode 100644 index 000000000..3b58a7fb0 --- /dev/null +++ b/global/resource_management/include/raw_file.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup rawfile + * @{ + * + * @brief Provides native functions for the resource manager to operate raw file directories and their raw files. + * + * You can use the resource manager to traverse, open, seek, read, and close raw files. + * + * @since 8 + * @version 1.0 + */ + +/** + * @file raw_file.h + * + * @brief Declares native functions related to raw file. + * + * For example, you can use the functions to search for, read, and close raw files. + * + * @since 8 + * @version 1.0 + */ +#ifndef GLOBAL_RAW_FILE_H +#define GLOBAL_RAW_FILE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct RawFile; + +/** + * @brief Provides access to a raw file. + * + * + * + * @since 8 + * @version 1.0 + */ +typedef struct RawFile RawFile; + +/** + * @brief Represent the raw file descriptor's info. + * + * The RawFileDescriptor is an output parameter in the {@link OH_ResourceManager_GetRawFileDescriptor}, + * and describes the raw file's file descriptor, start position and the length in the HAP. + * + * @since 8 + * @version 1.0 + */ +typedef struct { + /** the raw file fd */ + int fd; + + /** the offset from where the raw file starts in the HAP */ + long start; + + /** the length of the raw file in the HAP. */ + long length; +} RawFileDescriptor; + +/** + * @brief Reads a raw file. + * + * This function attempts to read data of length bytes from the current offset. + * + * @param rawFile Indicates the pointer to {@link RawFile}. + * @param buf Indicates the pointer to the buffer for receiving the data read. + * @param length Indicates the number of bytes to read. + * @return Returns the number of bytes read if any; returns 0 if the number reaches the end of file (EOF). + * @since 8 + * @version 1.0 + */ +int OH_ResourceManager_ReadRawFile(const RawFile *rawFile, void *buf, size_t length); + +/** + * @brief Uses the 32-bit data type to seek a data read/write position based on the specified offset within a raw file. + * + * @param rawFile Indicates the pointer to {@link RawFile}. + * @param offset Indicates the specified offset. + * @param whence Indicates the new read/write position, which can be one of the following values: \n + * 0: The new read/write position is set to offset. \n + * 1: The read/write position is set to the current position plus offset. \n + * 2: The read/write position is set to the end of file (EOF) plus offset. + * @return Returns the new read/write position if the operation is successful; returns (long) -1 if an error + * occurs. + * @since 8 + * @version 1.0 + */ +int OH_ResourceManager_SeekRawFile(const RawFile *rawFile, long offset, int whence); + +/** + * @brief Obtains the raw file length represented by an int32_t. + * + * @param rawFile Indicates the pointer to {@link RawFile}. + * @return Returns the total length of the raw file. + * @since 8 + * @version 1.0 + */ +long OH_ResourceManager_GetRawFileSize(RawFile *rawFile); + +/** + * @brief Closes an opened {@link RawFile} and releases all associated resources. + * + * + * + * @param rawFile Indicates the pointer to {@link RawFile}. + * @see OH_ResourceManager_OpenRawFile + * @since 8 + * @version 1.0 + */ +void OH_ResourceManager_CloseRawFile(RawFile *rawFile); + +/** + * @brief Obtains the current offset of a raw file, represented by an int32_t. + * + * The current offset of a raw file. + * + * @param rawFile Indicates the pointer to {@link RawFile}. + * @return Returns the current offset of a raw file. + * @since 8 + * @version 1.0 + */ +long OH_ResourceManager_GetRawFileOffset(const RawFile *rawFile); + +/** + * @brief Opens the file descriptor of a raw file based on the int32_t offset and file length. + * + * The opened raw file descriptor is used to read the raw file. + * + * @param rawFile Indicates the pointer to {@link RawFile}. + * @param descriptor Indicates the raw file's file descriptor, start position and the length in the HAP. + * @return Returns true: open the raw file descriptor successfully, false: the raw file is not allowed to access. + * @since 8 + * @version 1.0 + */ +bool OH_ResourceManager_GetRawFileDescriptor(const RawFile *rawFile, RawFileDescriptor &descriptor); + +/** + * @brief Closes the file descriptor of a raw file. + * + * The opened raw file descriptor must be released after used to avoid the file descriptor leak. + * + * @param descriptor Indicates the raw file's file descriptor, start position and the length in the HAP. + * @return Returns true: closes the raw file descriptor successfully, false: closes the raw file descriptor failed. + * @since 8 + * @version 1.0 + */ +bool OH_ResourceManager_ReleaseRawFileDescriptor(const RawFileDescriptor &descriptor); + +#ifdef __cplusplus +}; +#endif + +/** @} */ +#endif // GLOBAL_RAW_FILE_H diff --git a/global/resource_management/include/raw_file_manager.h b/global/resource_management/include/raw_file_manager.h new file mode 100644 index 000000000..f76a9c8cf --- /dev/null +++ b/global/resource_management/include/raw_file_manager.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup rawfile + * @{ + * + * @brief Provides native functions for the resource manager to operate raw file directories and their raw files. + * + * You can use the resource manager to traverse, open, seek, read, and close raw files. + * + * @since 8 + * @version 1.0 + */ + +/** + * @file raw_file_manager.h + * + * @brief Declares native functions for the resource manager. + * + * You can use the resource manager to open raw files for subsequent operations, such as seeking and reading. + * + * @since 8 + * @version 1.0 + */ +#ifndef GLOBAL_NATIVE_RESOURCE_MANAGER_H +#define GLOBAL_NATIVE_RESOURCE_MANAGER_H + +#include "napi/native_api.h" +#include "raw_dir.h" +#include "raw_file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct NativeResourceManager; + +/** + * @brief Presents the resource manager. + * + * This class encapsulates the native implementation of the JavaScript resource manager. The pointer to a + * ResourceManager object can be obtained by calling {@link OH_ResourceManager_InitNativeResourceManager}. + * + * @since 8 + * @version 1.0 + */ +typedef struct NativeResourceManager NativeResourceManager; + +/** + * @brief Obtains the native resource manager based on the JavaScipt resource manager. + * + * You need to obtain the resource manager to process raw files as required. + * + * @param env Indicates the pointer to the JavaScipt Native Interface (napi) environment. + * @param jsResMgr Indicates the JavaScipt resource manager. + * @return Returns the pointer to {@link NativeResourceManager}. + * @since 8 + * @version 1.0 + */ +NativeResourceManager *OH_ResourceManager_InitNativeResourceManager(napi_env env, napi_value jsResMgr); + +/** + * @brief Releases the native resource manager. + * + * + * + * @param resMgr Indicates the pointer to {@link RawDir}. + * @since 8 + * @version 1.0 + */ +void OH_ResourceManager_ReleaseNativeResourceManager(NativeResourceManager *resMgr); + +/** + * @brief Opens a raw file directory. + * + * After it is opened, you can traverse its raw files. + * + * @param mgr Indicates the pointer to {@link NativeResourceManager} obtained by calling + * {@link OH_ResourceManager_InitNativeResourceManager}. + * @param dirName Indicates the name of the raw file directory to open. You can pass an empty string to open the + * top-level raw file directory. + * @return Returns the pointer to {@link RawDir}. After you finish using the pointer, call + * {@link OH_ResourceManager_CloseRawDir} to release it. + * @see OH_ResourceManager_InitNativeResourceManager + * @see OH_ResourceManager_CloseRawDir + * @since 8 + * @version 1.0 + */ +RawDir *OH_ResourceManager_OpenRawDir(const NativeResourceManager *mgr, const char *dirName); + +/** + * @brief Opens a raw file. + * + * After it is opened, you can read its data. + * + * @param mgr Indicates the pointer to {@link NativeResourceManager} obtained by calling + * {@link OH_ResourceManager_InitNativeResourceManager}. + * @param fileName Indicates the file path relative to the top-level raw file directory. + * @return Returns the pointer to {@link RawFile}. After you finish using the pointer, call + * {@link OH_ResourceManager_CloseRawFile} to release it. + * @see OH_ResourceManager_InitNativeResourceManager + * @see OH_ResourceManager_CloseRawFile + * @since 8 + * @version 1.0 + */ +RawFile *OH_ResourceManager_OpenRawFile(const NativeResourceManager *mgr, const char *fileName); + +#ifdef __cplusplus +}; +#endif + +/** @} */ +#endif // GLOBAL_NATIVE_RESOURCE_MANAGER_H diff --git a/global/resource_management/librawfile.ndk.json b/global/resource_management/librawfile.ndk.json new file mode 100644 index 000000000..411dbc53d --- /dev/null +++ b/global/resource_management/librawfile.ndk.json @@ -0,0 +1,44 @@ +[ + { + "name": "OH_ResourceManager_InitNativeResourceManager" + }, + { + "name": "OH_ResourceManager_ReleaseNativeResourceManager" + }, + { + "name": "OH_ResourceManager_OpenRawDir" + }, + { + "name": "OH_ResourceManager_OpenRawFile" + }, + { + "name": "OH_ResourceManager_GetRawFileName" + }, + { + "name": "OH_ResourceManager_GetRawFileCount" + }, + { + "name": "OH_ResourceManager_CloseRawDir" + }, + { + "name": "OH_ResourceManager_ReadRawFile" + }, + { + "name": "OH_ResourceManager_SeekRawFile" + }, + { + "name": "OH_ResourceManager_GetRawFileSize" + }, + { + "name": "OH_ResourceManager_CloseRawFile" + }, + { + "name": "OH_ResourceManager_GetRawFileOffset" + }, + { + "name": "OH_ResourceManager_GetRawFileDescriptor" + }, + { + "name": "OH_ResourceManager_ReleaseRawFileDescriptor" + } +] \ No newline at end of file diff --git a/graphic/graphic_2d/EGL/BUILD.gn b/graphic/graphic_2d/EGL/BUILD.gn new file mode 100644 index 000000000..eb2e08830 --- /dev/null +++ b/graphic/graphic_2d/EGL/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("EGL_header") { + dest_dir = "$ndk_headers_out_dir/EGL" + sources = [ + "//third_party/EGL/api/EGL/egl.h", + "//third_party/EGL/api/EGL/eglext.h", + "//third_party/EGL/api/EGL/eglplatform.h", + ] +} + +ohos_ndk_library("libEGL_ndk") { + output_name = "EGL" + output_extension = "so" + ndk_description_file = "./libEGL.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.EGL" + system_capability_headers = [ + "EGL/egl.h", + "EGL/eglext.h", + "EGL/eglplatform.h", + ] +} diff --git a/graphic/graphic_2d/EGL/libEGL.ndk.json b/graphic/graphic_2d/EGL/libEGL.ndk.json new file mode 100644 index 000000000..505448778 --- /dev/null +++ b/graphic/graphic_2d/EGL/libEGL.ndk.json @@ -0,0 +1,46 @@ +[ + { "name": "eglChooseConfig" }, + { "name": "eglCopyBuffers" }, + { "name": "eglCreateContext" }, + { "name": "eglCreatePbufferSurface" }, + { "name": "eglCreatePixmapSurface" }, + { "name": "eglCreateWindowSurface" }, + { "name": "eglDestroyContext" }, + { "name": "eglDestroySurface" }, + { "name": "eglGetConfigAttrib" }, + { "name": "eglGetConfigs" }, + { "name": "eglGetCurrentDisplay" }, + { "name": "eglGetCurrentSurface" }, + { "name": "eglGetDisplay" }, + { "name": "eglGetError" }, + { "name": "eglGetProcAddress" }, + { "name": "eglInitialize" }, + { "name": "eglMakeCurrent" }, + { "name": "eglQueryContext" }, + { "name": "eglQueryString" }, + { "name": "eglQuerySurface" }, + { "name": "eglSwapBuffers" }, + { "name": "eglTerminate" }, + { "name": "eglWaitGL" }, + { "name": "eglWaitNative" }, + { "name": "eglBindTexImage" }, + { "name": "eglReleaseTexImage" }, + { "name": "eglSurfaceAttrib" }, + { "name": "eglSwapInterval" }, + { "name": "eglBindAPI" }, + { "name": "eglQueryAPI" }, + { "name": "eglCreatePbufferFromClientBuffer" }, + { "name": "eglReleaseThread" }, + { "name": "eglWaitClient" }, + { "name": "eglGetCurrentContext" }, + { "name": "eglCreateSync" }, + { "name": "eglDestroySync" }, + { "name": "eglClientWaitSync" }, + { "name": "eglGetSyncAttrib" }, + { "name": "eglCreateImage" }, + { "name": "eglDestroyImage" }, + { "name": "eglGetPlatformDisplay" }, + { "name": "eglCreatePlatformWindowSurface" }, + { "name": "eglCreatePlatformPixmapSurface" }, + { "name": "eglWaitSync" } +] diff --git a/graphic/graphic_2d/GLES3/BUILD.gn b/graphic/graphic_2d/GLES3/BUILD.gn new file mode 100644 index 000000000..a2bbdbd80 --- /dev/null +++ b/graphic/graphic_2d/GLES3/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("GLES3_header") { + dest_dir = "$ndk_headers_out_dir/GLES3" + sources = [ + "//third_party/openGLES/api/GLES3/gl3.h", + "//third_party/openGLES/api/GLES3/gl31.h", + "//third_party/openGLES/api/GLES3/gl32.h", + "//third_party/openGLES/api/GLES3/gl3platform.h", + ] +} + +ohos_ndk_library("libGLESv3_ndk") { + output_name = "GLESv3" + output_extension = "so" + ndk_description_file = "./libGLESv3.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.GLES3" + system_capability_headers = [ + "GLES3/gl3.h", + "GLES3/gl31.h", + "GLES3/gl32.h", + "GLES3/gl3platform.h", + ] +} diff --git a/graphic/graphic_2d/GLES3/libGLESv3.ndk.json b/graphic/graphic_2d/GLES3/libGLESv3.ndk.json new file mode 100644 index 000000000..ee6870afe --- /dev/null +++ b/graphic/graphic_2d/GLES3/libGLESv3.ndk.json @@ -0,0 +1,360 @@ +[ + { "name": "glActiveShaderProgram" }, + { "name": "glActiveTexture" }, + { "name": "glAttachShader" }, + { "name": "glBeginQuery" }, + { "name": "glBeginTransformFeedback" }, + { "name": "glBindAttribLocation" }, + { "name": "glBindBuffer" }, + { "name": "glBindBufferBase" }, + { "name": "glBindBufferRange" }, + { "name": "glBindFramebuffer" }, + { "name": "glBindImageTexture" }, + { "name": "glBindProgramPipeline" }, + { "name": "glBindRenderbuffer" }, + { "name": "glBindSampler" }, + { "name": "glBindTexture" }, + { "name": "glBindTransformFeedback" }, + { "name": "glBindVertexArray" }, + { "name": "glBindVertexBuffer" }, + { "name": "glBlendBarrier" }, + { "name": "glBlendColor" }, + { "name": "glBlendEquation" }, + { "name": "glBlendEquationi" }, + { "name": "glBlendEquationSeparate" }, + { "name": "glBlendEquationSeparatei" }, + { "name": "glBlendFunc" }, + { "name": "glBlendFunci" }, + { "name": "glBlendFuncSeparate" }, + { "name": "glBlendFuncSeparatei" }, + { "name": "glBlitFramebuffer" }, + { "name": "glBufferData" }, + { "name": "glBufferSubData" }, + { "name": "glCheckFramebufferStatus" }, + { "name": "glClear" }, + { "name": "glClearBufferfi" }, + { "name": "glClearBufferfv" }, + { "name": "glClearBufferiv" }, + { "name": "glClearBufferuiv" }, + { "name": "glClearColor" }, + { "name": "glClearDepthf" }, + { "name": "glClearStencil" }, + { "name": "glClientWaitSync" }, + { "name": "glColorMask" }, + { "name": "glColorMaski" }, + { "name": "glCompileShader" }, + { "name": "glCompressedTexImage2D" }, + { "name": "glCompressedTexImage3D" }, + { "name": "glCompressedTexSubImage2D" }, + { "name": "glCompressedTexSubImage3D" }, + { "name": "glCopyBufferSubData" }, + { "name": "glCopyImageSubData" }, + { "name": "glCopyTexImage2D" }, + { "name": "glCopyTexSubImage2D" }, + { "name": "glCopyTexSubImage3D" }, + { "name": "glCreateProgram" }, + { "name": "glCreateShader" }, + { "name": "glCreateShaderProgramv" }, + { "name": "glCullFace" }, + { "name": "glDebugMessageCallback" }, + { "name": "glDebugMessageControl" }, + { "name": "glDebugMessageInsert" }, + { "name": "glDeleteBuffers" }, + { "name": "glDeleteFramebuffers" }, + { "name": "glDeleteProgram" }, + { "name": "glDeleteProgramPipelines" }, + { "name": "glDeleteQueries" }, + { "name": "glDeleteRenderbuffers" }, + { "name": "glDeleteSamplers" }, + { "name": "glDeleteShader" }, + { "name": "glDeleteSync" }, + { "name": "glDeleteTextures" }, + { "name": "glDeleteTransformFeedbacks" }, + { "name": "glDeleteVertexArrays" }, + { "name": "glDepthFunc" }, + { "name": "glDepthMask" }, + { "name": "glDepthRangef" }, + { "name": "glDetachShader" }, + { "name": "glDisable" }, + { "name": "glDisablei" }, + { "name": "glDisableVertexAttribArray" }, + { "name": "glDispatchCompute" }, + { "name": "glDispatchComputeIndirect" }, + { "name": "glDrawArrays" }, + { "name": "glDrawArraysIndirect" }, + { "name": "glDrawArraysInstanced" }, + { "name": "glDrawBuffers" }, + { "name": "glDrawElements" }, + { "name": "glDrawElementsBaseVertex" }, + { "name": "glDrawElementsIndirect" }, + { "name": "glDrawElementsInstanced" }, + { "name": "glDrawElementsInstancedBaseVertex" }, + { "name": "glDrawRangeElements" }, + { "name": "glDrawRangeElementsBaseVertex" }, + { "name": "glEnable" }, + { "name": "glEnablei" }, + { "name": "glEnableVertexAttribArray" }, + { "name": "glEndQuery" }, + { "name": "glEndTransformFeedback" }, + { "name": "glFenceSync" }, + { "name": "glFinish" }, + { "name": "glFlush" }, + { "name": "glFlushMappedBufferRange" }, + { "name": "glFramebufferParameteri" }, + { "name": "glFramebufferRenderbuffer" }, + { "name": "glFramebufferTexture" }, + { "name": "glFramebufferTexture2D" }, + { "name": "glFramebufferTextureLayer" }, + { "name": "glFrontFace" }, + { "name": "glGenBuffers" }, + { "name": "glGenerateMipmap" }, + { "name": "glGenFramebuffers" }, + { "name": "glGenProgramPipelines" }, + { "name": "glGenQueries" }, + { "name": "glGenRenderbuffers" }, + { "name": "glGenSamplers" }, + { "name": "glGenTextures" }, + { "name": "glGenTransformFeedbacks" }, + { "name": "glGenVertexArrays" }, + { "name": "glGetActiveAttrib" }, + { "name": "glGetActiveUniform" }, + { "name": "glGetActiveUniformBlockiv" }, + { "name": "glGetActiveUniformBlockName" }, + { "name": "glGetActiveUniformsiv" }, + { "name": "glGetAttachedShaders" }, + { "name": "glGetAttribLocation" }, + { "name": "glGetBooleani_v" }, + { "name": "glGetBooleanv" }, + { "name": "glGetBufferParameteri64v" }, + { "name": "glGetBufferParameteriv" }, + { "name": "glGetBufferPointerv" }, + { "name": "glGetDebugMessageLog" }, + { "name": "glGetError" }, + { "name": "glGetFloatv" }, + { "name": "glGetFragDataLocation" }, + { "name": "glGetFramebufferAttachmentParameteriv" }, + { "name": "glGetFramebufferParameteriv" }, + { "name": "glGetGraphicsResetStatus" }, + { "name": "glGetInteger64i_v" }, + { "name": "glGetInteger64v" }, + { "name": "glGetIntegeri_v" }, + { "name": "glGetIntegerv" }, + { "name": "glGetInternalformativ" }, + { "name": "glGetMultisamplefv" }, + { "name": "glGetnUniformfv" }, + { "name": "glGetnUniformiv" }, + { "name": "glGetnUniformuiv" }, + { "name": "glGetObjectLabel" }, + { "name": "glGetObjectPtrLabel" }, + { "name": "glGetPointerv" }, + { "name": "glGetProgramBinary" }, + { "name": "glGetProgramInfoLog" }, + { "name": "glGetProgramInterfaceiv" }, + { "name": "glGetProgramiv" }, + { "name": "glGetProgramPipelineInfoLog" }, + { "name": "glGetProgramPipelineiv" }, + { "name": "glGetProgramResourceIndex" }, + { "name": "glGetProgramResourceiv" }, + { "name": "glGetProgramResourceLocation" }, + { "name": "glGetProgramResourceName" }, + { "name": "glGetQueryiv" }, + { "name": "glGetQueryObjectuiv" }, + { "name": "glGetRenderbufferParameteriv" }, + { "name": "glGetSamplerParameterfv" }, + { "name": "glGetSamplerParameterIiv" }, + { "name": "glGetSamplerParameterIuiv" }, + { "name": "glGetSamplerParameteriv" }, + { "name": "glGetShaderInfoLog" }, + { "name": "glGetShaderiv" }, + { "name": "glGetShaderPrecisionFormat" }, + { "name": "glGetShaderSource" }, + { "name": "glGetString" }, + { "name": "glGetStringi" }, + { "name": "glGetSynciv" }, + { "name": "glGetTexLevelParameterfv" }, + { "name": "glGetTexLevelParameteriv" }, + { "name": "glGetTexParameterfv" }, + { "name": "glGetTexParameterIiv" }, + { "name": "glGetTexParameterIuiv" }, + { "name": "glGetTexParameteriv" }, + { "name": "glGetTransformFeedbackVarying" }, + { "name": "glGetUniformBlockIndex" }, + { "name": "glGetUniformfv" }, + { "name": "glGetUniformIndices" }, + { "name": "glGetUniformiv" }, + { "name": "glGetUniformLocation" }, + { "name": "glGetUniformuiv" }, + { "name": "glGetVertexAttribfv" }, + { "name": "glGetVertexAttribIiv" }, + { "name": "glGetVertexAttribIuiv" }, + { "name": "glGetVertexAttribiv" }, + { "name": "glGetVertexAttribPointerv" }, + { "name": "glHint" }, + { "name": "glInvalidateFramebuffer" }, + { "name": "glInvalidateSubFramebuffer" }, + { "name": "glIsBuffer" }, + { "name": "glIsEnabled" }, + { "name": "glIsEnabledi" }, + { "name": "glIsFramebuffer" }, + { "name": "glIsProgram" }, + { "name": "glIsProgramPipeline" }, + { "name": "glIsQuery" }, + { "name": "glIsRenderbuffer" }, + { "name": "glIsSampler" }, + { "name": "glIsShader" }, + { "name": "glIsSync" }, + { "name": "glIsTexture" }, + { "name": "glIsTransformFeedback" }, + { "name": "glIsVertexArray" }, + { "name": "glLineWidth" }, + { "name": "glLinkProgram" }, + { "name": "glMapBufferRange" }, + { "name": "glMemoryBarrier" }, + { "name": "glMemoryBarrierByRegion" }, + { "name": "glMinSampleShading" }, + { "name": "glObjectLabel" }, + { "name": "glObjectPtrLabel" }, + { "name": "glPatchParameteri" }, + { "name": "glPauseTransformFeedback" }, + { "name": "glPixelStorei" }, + { "name": "glPolygonOffset" }, + { "name": "glPopDebugGroup" }, + { "name": "glPrimitiveBoundingBox" }, + { "name": "glProgramBinary" }, + { "name": "glProgramParameteri" }, + { "name": "glProgramUniform1f" }, + { "name": "glProgramUniform1fv" }, + { "name": "glProgramUniform1i" }, + { "name": "glProgramUniform1iv" }, + { "name": "glProgramUniform1ui" }, + { "name": "glProgramUniform1uiv" }, + { "name": "glProgramUniform2f" }, + { "name": "glProgramUniform2fv" }, + { "name": "glProgramUniform2i" }, + { "name": "glProgramUniform2iv" }, + { "name": "glProgramUniform2ui" }, + { "name": "glProgramUniform2uiv" }, + { "name": "glProgramUniform3f" }, + { "name": "glProgramUniform3fv" }, + { "name": "glProgramUniform3i" }, + { "name": "glProgramUniform3iv" }, + { "name": "glProgramUniform3ui" }, + { "name": "glProgramUniform3uiv" }, + { "name": "glProgramUniform4f" }, + { "name": "glProgramUniform4fv" }, + { "name": "glProgramUniform4i" }, + { "name": "glProgramUniform4iv" }, + { "name": "glProgramUniform4ui" }, + { "name": "glProgramUniform4uiv" }, + { "name": "glProgramUniformMatrix2fv" }, + { "name": "glProgramUniformMatrix2x3fv" }, + { "name": "glProgramUniformMatrix2x4fv" }, + { "name": "glProgramUniformMatrix3fv" }, + { "name": "glProgramUniformMatrix3x2fv" }, + { "name": "glProgramUniformMatrix3x4fv" }, + { "name": "glProgramUniformMatrix4fv" }, + { "name": "glProgramUniformMatrix4x2fv" }, + { "name": "glProgramUniformMatrix4x3fv" }, + { "name": "glPushDebugGroup" }, + { "name": "glReadBuffer" }, + { "name": "glReadnPixels" }, + { "name": "glReadPixels" }, + { "name": "glReleaseShaderCompiler" }, + { "name": "glRenderbufferStorage" }, + { "name": "glRenderbufferStorageMultisample" }, + { "name": "glResumeTransformFeedback" }, + { "name": "glSampleCoverage" }, + { "name": "glSampleMaski" }, + { "name": "glSamplerParameterf" }, + { "name": "glSamplerParameterfv" }, + { "name": "glSamplerParameteri" }, + { "name": "glSamplerParameterIiv" }, + { "name": "glSamplerParameterIuiv" }, + { "name": "glSamplerParameteriv" }, + { "name": "glScissor" }, + { "name": "glShaderBinary" }, + { "name": "glShaderSource" }, + { "name": "glStencilFunc" }, + { "name": "glStencilFuncSeparate" }, + { "name": "glStencilMask" }, + { "name": "glStencilMaskSeparate" }, + { "name": "glStencilOp" }, + { "name": "glStencilOpSeparate" }, + { "name": "glTexBuffer" }, + { "name": "glTexBufferRange" }, + { "name": "glTexImage2D" }, + { "name": "glTexImage3D" }, + { "name": "glTexParameterf" }, + { "name": "glTexParameterfv" }, + { "name": "glTexParameteri" }, + { "name": "glTexParameterIiv" }, + { "name": "glTexParameterIuiv" }, + { "name": "glTexParameteriv" }, + { "name": "glTexStorage2D" }, + { "name": "glTexStorage2DMultisample" }, + { "name": "glTexStorage3D" }, + { "name": "glTexStorage3DMultisample" }, + { "name": "glTexSubImage2D" }, + { "name": "glTexSubImage3D" }, + { "name": "glTransformFeedbackVaryings" }, + { "name": "glUniform1f" }, + { "name": "glUniform1fv" }, + { "name": "glUniform1i" }, + { "name": "glUniform1iv" }, + { "name": "glUniform1ui" }, + { "name": "glUniform1uiv" }, + { "name": "glUniform2f" }, + { "name": "glUniform2fv" }, + { "name": "glUniform2i" }, + { "name": "glUniform2iv" }, + { "name": "glUniform2ui" }, + { "name": "glUniform2uiv" }, + { "name": "glUniform3f" }, + { "name": "glUniform3fv" }, + { "name": "glUniform3i" }, + { "name": "glUniform3iv" }, + { "name": "glUniform3ui" }, + { "name": "glUniform3uiv" }, + { "name": "glUniform4f" }, + { "name": "glUniform4fv" }, + { "name": "glUniform4i" }, + { "name": "glUniform4iv" }, + { "name": "glUniform4ui" }, + { "name": "glUniform4uiv" }, + { "name": "glUniformBlockBinding" }, + { "name": "glUniformMatrix2fv" }, + { "name": "glUniformMatrix2x3fv" }, + { "name": "glUniformMatrix2x4fv" }, + { "name": "glUniformMatrix3fv" }, + { "name": "glUniformMatrix3x2fv" }, + { "name": "glUniformMatrix3x4fv" }, + { "name": "glUniformMatrix4fv" }, + { "name": "glUniformMatrix4x2fv" }, + { "name": "glUniformMatrix4x3fv" }, + { "name": "glUnmapBuffer" }, + { "name": "glUseProgram" }, + { "name": "glUseProgramStages" }, + { "name": "glValidateProgram" }, + { "name": "glValidateProgramPipeline" }, + { "name": "glVertexAttrib1f" }, + { "name": "glVertexAttrib1fv" }, + { "name": "glVertexAttrib2f" }, + { "name": "glVertexAttrib2fv" }, + { "name": "glVertexAttrib3f" }, + { "name": "glVertexAttrib3fv" }, + { "name": "glVertexAttrib4f" }, + { "name": "glVertexAttrib4fv" }, + { "name": "glVertexAttribBinding" }, + { "name": "glVertexAttribDivisor" }, + { "name": "glVertexAttribFormat" }, + { "name": "glVertexAttribI4i" }, + { "name": "glVertexAttribI4iv" }, + { "name": "glVertexAttribI4ui" }, + { "name": "glVertexAttribI4uiv" }, + { "name": "glVertexAttribIFormat" }, + { "name": "glVertexAttribIPointer" }, + { "name": "glVertexAttribPointer" }, + { "name": "glVertexBindingDivisor" }, + { "name": "glViewport" }, + { "name": "glWaitSync" } +] \ No newline at end of file diff --git a/graphic/graphic_2d/KHR/BUILD.gn b/graphic/graphic_2d/KHR/BUILD.gn new file mode 100644 index 000000000..12f1e02eb --- /dev/null +++ b/graphic/graphic_2d/KHR/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("KHR_header") { + dest_dir = "$ndk_headers_out_dir/KHR" + sources = [ "//third_party/EGL/api/KHR/khrplatform.h" ] +} diff --git a/graphic/graphic_2d/native_buffer/BUILD.gn b/graphic/graphic_2d/native_buffer/BUILD.gn new file mode 100644 index 000000000..85ef1c177 --- /dev/null +++ b/graphic/graphic_2d/native_buffer/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("native_buffer_header") { + dest_dir = "$ndk_headers_out_dir/native_buffer" + sources = [ "//foundation/graphic/graphic_2d/interfaces/inner_api/surface/native_buffer.h" ] +} + +ohos_ndk_library("libnative_buffer_ndk") { + output_name = "native_buffer" + output_extension = "so" + ndk_description_file = "./libnative_buffer.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.NativeBuffer" + system_capability_headers = [ "native_buffer/native_buffer.h" ] +} diff --git a/graphic/graphic_2d/native_buffer/libnative_buffer.ndk.json b/graphic/graphic_2d/native_buffer/libnative_buffer.ndk.json new file mode 100644 index 000000000..722ba7b08 --- /dev/null +++ b/graphic/graphic_2d/native_buffer/libnative_buffer.ndk.json @@ -0,0 +1,9 @@ +[ + { "name": "OH_NativeBuffer_Alloc" }, + { "name": "OH_NativeBuffer_Reference" }, + { "name": "OH_NativeBuffer_Unreference" }, + { "name": "OH_NativeBuffer_GetConfig" }, + { "name": "OH_NativeBuffer_Map" }, + { "name": "OH_NativeBuffer_Unmap" }, + { "name": "OH_NativeBuffer_GetSeqNum" } +] \ No newline at end of file diff --git a/graphic/graphic_2d/native_drawing/BUILD.gn b/graphic/graphic_2d/native_drawing/BUILD.gn new file mode 100644 index 000000000..ed5e236e9 --- /dev/null +++ b/graphic/graphic_2d/native_drawing/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("native_drawing_header") { + dest_dir = "$ndk_headers_out_dir/native_drawing" + sources = [ + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_bitmap.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_brush.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_canvas.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_color.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_font_collection.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_path.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_pen.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_text_declaration.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_text_typography.h", + "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include/c/drawing_types.h", + ] +} + +ohos_ndk_library("libnative_drawing_ndk") { + output_name = "native_drawing" + output_extension = "so" + ndk_description_file = "./libnative_drawing.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.NativeDrawing" + system_capability_headers = [ + "native_drawing/drawing_bitmap.h", + "native_drawing/drawing_brush.h", + "native_drawing/drawing_canvas.h", + "native_drawing/drawing_color.h", + "native_drawing/drawing_font_collection.h", + "native_drawing/drawing_path.h", + "native_drawing/drawing_pen.h", + "native_drawing/drawing_text_declaration.h", + "native_drawing/drawing_text_typography.h", + "native_drawing/drawing_types.h", + ] +} diff --git a/graphic/graphic_2d/native_drawing/libnative_drawing.ndk.json b/graphic/graphic_2d/native_drawing/libnative_drawing.ndk.json new file mode 100644 index 000000000..44c3452f8 --- /dev/null +++ b/graphic/graphic_2d/native_drawing/libnative_drawing.ndk.json @@ -0,0 +1,85 @@ +[ + { "name": "OH_Drawing_BitmapCreate" }, + { "name": "OH_Drawing_BitmapDestroy" }, + { "name": "OH_Drawing_BitmapBuild" }, + { "name": "OH_Drawing_BitmapGetWidth" }, + { "name": "OH_Drawing_BitmapGetHeight" }, + { "name": "OH_Drawing_BitmapGetPixels" }, + { "name": "OH_Drawing_BrushCreate" }, + { "name": "OH_Drawing_BrushDestroy" }, + { "name": "OH_Drawing_BrushIsAntiAlias" }, + { "name": "OH_Drawing_BrushSetAntiAlias" }, + { "name": "OH_Drawing_BrushGetColor" }, + { "name": "OH_Drawing_BrushSetColor" }, + { "name": "OH_Drawing_CanvasCreate" }, + { "name": "OH_Drawing_CanvasDestroy" }, + { "name": "OH_Drawing_CanvasBind" }, + { "name": "OH_Drawing_CanvasAttachPen" }, + { "name": "OH_Drawing_CanvasDetachPen" }, + { "name": "OH_Drawing_CanvasAttachBrush" }, + { "name": "OH_Drawing_CanvasDetachBrush" }, + { "name": "OH_Drawing_CanvasSave" }, + { "name": "OH_Drawing_CanvasRestore" }, + { "name": "OH_Drawing_CanvasDrawLine" }, + { "name": "OH_Drawing_CanvasDrawPath" }, + { "name": "OH_Drawing_CanvasClear" }, + { "name": "OH_Drawing_PathCreate" }, + { "name": "OH_Drawing_PathDestroy" }, + { "name": "OH_Drawing_PathMoveTo" }, + { "name": "OH_Drawing_PathLineTo" }, + { "name": "OH_Drawing_PathArcTo" }, + { "name": "OH_Drawing_PathQuadTo" }, + { "name": "OH_Drawing_PathCubicTo" }, + { "name": "OH_Drawing_PathClose" }, + { "name": "OH_Drawing_PathReset" }, + { "name": "OH_Drawing_PenCreate" }, + { "name": "OH_Drawing_PenDestroy" }, + { "name": "OH_Drawing_PenIsAntiAlias" }, + { "name": "OH_Drawing_PenSetAntiAlias" }, + { "name": "OH_Drawing_PenGetColor" }, + { "name": "OH_Drawing_PenSetColor" }, + { "name": "OH_Drawing_PenGetWidth" }, + { "name": "OH_Drawing_PenSetWidth" }, + { "name": "OH_Drawing_PenGetMiterLimit" }, + { "name": "OH_Drawing_PenSetMiterLimit" }, + { "name": "OH_Drawing_PenGetCap" }, + { "name": "OH_Drawing_PenSetCap" }, + { "name": "OH_Drawing_PenGetJoin" }, + { "name": "OH_Drawing_PenSetJoin" }, + { "name": "OH_Drawing_ColorSetArgb" }, + { "name": "OH_Drawing_CreateFontCollection" }, + { "name": "OH_Drawing_DestroyFontCollection" }, + { "name": "OH_Drawing_CreateTypographyStyle" }, + { "name": "OH_Drawing_DestroyTypographyStyle" }, + { "name": "OH_Drawing_SetTypographyTextDirection" }, + { "name": "OH_Drawing_SetTypographyTextAlign" }, + { "name": "OH_Drawing_SetTypographyTextMaxLines" }, + { "name": "OH_Drawing_CreateTextStyle" }, + { "name": "OH_Drawing_DestroyTextStyle" }, + { "name": "OH_Drawing_SetTextStyleColor" }, + { "name": "OH_Drawing_SetTextStyleFontSize" }, + { "name": "OH_Drawing_SetTextStyleFontWeight" }, + { "name": "OH_Drawing_SetTextStyleBaseLine" }, + { "name": "OH_Drawing_SetTextStyleDecoration" }, + { "name": "OH_Drawing_SetTextStyleDecorationColor" }, + { "name": "OH_Drawing_SetTextStyleFontHeight" }, + { "name": "OH_Drawing_SetTextStyleFontFamilies" }, + { "name": "OH_Drawing_SetTextStyleFontStyle" }, + { "name": "OH_Drawing_SetTextStyleLocale" }, + { "name": "OH_Drawing_CreateTypographyHandler" }, + { "name": "OH_Drawing_DestroyTypographyHandler" }, + { "name": "OH_Drawing_TypographyHandlerPushTextStyle" }, + { "name": "OH_Drawing_TypographyHandlerAddText" }, + { "name": "OH_Drawing_TypographyHandlerPopTextStyle" }, + { "name": "OH_Drawing_CreateTypography" }, + { "name": "OH_Drawing_DestroyTypography" }, + { "name": "OH_Drawing_TypographyLayout" }, + { "name": "OH_Drawing_TypographyPaint" }, + { "name": "OH_Drawing_TypographyGetMaxWidth" }, + { "name": "OH_Drawing_TypographyGetHeight" }, + { "name": "OH_Drawing_TypographyGetLongestLine" }, + { "name": "OH_Drawing_TypographyGetMinIntrinsicWidth" }, + { "name": "OH_Drawing_TypographyGetMaxIntrinsicWidth" }, + { "name": "OH_Drawing_TypographyGetAlphabeticBaseline" }, + { "name": "OH_Drawing_TypographyGetIdeographicBaseline" } +] \ No newline at end of file diff --git a/graphic/graphic_2d/native_image/BUILD.gn b/graphic/graphic_2d/native_image/BUILD.gn new file mode 100644 index 000000000..915f89786 --- /dev/null +++ b/graphic/graphic_2d/native_image/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("native_image_header") { + dest_dir = "$ndk_headers_out_dir/native_image" + sources = [ "//foundation/graphic/graphic_2d/interfaces/inner_api/surface/native_image.h" ] +} + +ohos_ndk_library("libnative_image_ndk") { + output_name = "native_image" + output_extension = "so" + ndk_description_file = "./libnative_image.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.NativeImage" + system_capability_headers = [ "native_image/native_image.h" ] +} diff --git a/graphic/graphic_2d/native_image/libnative_image.ndk.json b/graphic/graphic_2d/native_image/libnative_image.ndk.json new file mode 100644 index 000000000..537d83d3e --- /dev/null +++ b/graphic/graphic_2d/native_image/libnative_image.ndk.json @@ -0,0 +1,10 @@ +[ + { "name": "OH_NativeImage_Create" }, + { "name": "OH_NativeImage_AcquireNativeWindow" }, + { "name": "OH_NativeImage_AttachContext" }, + { "name": "OH_NativeImage_DetachContext" }, + { "name": "OH_NativeImage_UpdateSurfaceImage" }, + { "name": "OH_NativeImage_GetTimestamp" }, + { "name": "OH_NativeImage_GetTransformMatrix" }, + { "name": "OH_NativeImage_Destroy" } +] \ No newline at end of file diff --git a/graphic/graphic_2d/native_vsync/BUILD.gn b/graphic/graphic_2d/native_vsync/BUILD.gn new file mode 100644 index 000000000..9c903df79 --- /dev/null +++ b/graphic/graphic_2d/native_vsync/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("native_vsync_header") { + dest_dir = "$ndk_headers_out_dir/native_vsync" + sources = [ "//foundation/graphic/graphic_2d/interfaces/inner_api/composer/native_vsync.h" ] +} + +ohos_ndk_library("libnative_vsync_ndk") { + output_name = "native_vsync" + output_extension = "so" + ndk_description_file = "./libnative_vsync.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.NativeVSync" + system_capability_headers = [ "native_vsync/native_vsync.h" ] +} diff --git a/graphic/graphic_2d/native_vsync/libnative_vsync.ndk.json b/graphic/graphic_2d/native_vsync/libnative_vsync.ndk.json new file mode 100644 index 000000000..e2c78daa5 --- /dev/null +++ b/graphic/graphic_2d/native_vsync/libnative_vsync.ndk.json @@ -0,0 +1,5 @@ +[ + { "name": "OH_NativeVSync_Create" }, + { "name": "OH_NativeVSync_Destroy" }, + { "name": "OH_NativeVSync_RequestFrame" } +] \ No newline at end of file diff --git a/graphic/graphic_2d/native_window/BUILD.gn b/graphic/graphic_2d/native_window/BUILD.gn new file mode 100644 index 000000000..2d02f1b72 --- /dev/null +++ b/graphic/graphic_2d/native_window/BUILD.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/graphic/graphic_2d/graphic_config.gni") + +ohos_ndk_headers("native_window_header") { + dest_dir = "$ndk_headers_out_dir/native_window" + sources = [ + "$graphic_2d_root/frameworks/surface/include/buffer_handle.h", + "$graphic_2d_root/interfaces/inner_api/surface/external_window.h", + ] +} + +ohos_ndk_library("libnative_window_ndk") { + output_name = "native_window" + output_extension = "so" + ndk_description_file = "./libnative_window.ndk.json" + system_capability = "SystemCapability.Graphic.Graphic2D.NativeWindow" + system_capability_headers = [ + "native_window/buffer_handle.h", + "native_window/external_window.h", + ] +} diff --git a/graphic/graphic_2d/native_window/libnative_window.ndk.json b/graphic/graphic_2d/native_window/libnative_window.ndk.json new file mode 100644 index 000000000..95e138ee2 --- /dev/null +++ b/graphic/graphic_2d/native_window/libnative_window.ndk.json @@ -0,0 +1,18 @@ +[ + { "name": "OH_NativeWindow_CreateNativeWindow" }, + { "name": "OH_NativeWindow_DestroyNativeWindow" }, + { "name": "OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer" }, + { "name": "OH_NativeWindow_DestroyNativeWindowBuffer" }, + { "name": "OH_NativeWindow_NativeWindowRequestBuffer" }, + { "name": "OH_NativeWindow_NativeWindowFlushBuffer" }, + { "name": "OH_NativeWindow_NativeWindowAbortBuffer" }, + { "name": "OH_NativeWindow_NativeWindowHandleOpt" }, + { "name": "OH_NativeWindow_GetBufferHandleFromNative" }, + { "name": "OH_NativeWindow_NativeObjectReference" }, + { "name": "OH_NativeWindow_NativeObjectUnreference" }, + { "name": "OH_NativeWindow_GetNativeObjectMagic" }, + { "name": "OH_NativeWindow_NativeWindowSetScalingMode" }, + { "name": "OH_NativeWindow_NativeWindowSetMetaData" }, + { "name": "OH_NativeWindow_NativeWindowSetMetaDataSet" }, + { "name": "OH_NativeWindow_NativeWindowSetTunnelHandle" } +] \ No newline at end of file diff --git a/graphic/graphic_2d/vulkan/BUILD.gn b/graphic/graphic_2d/vulkan/BUILD.gn new file mode 100644 index 000000000..627b3f0ba --- /dev/null +++ b/graphic/graphic_2d/vulkan/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") + +ohos_ndk_headers("vulkan_header") { + dest_dir = "$ndk_headers_out_dir/vulkan" + sources = [ + "//third_party/vulkan-headers/include/vulkan/vk_platform.h", + "//third_party/vulkan-headers/include/vulkan/vulkan.h", + "//third_party/vulkan-headers/include/vulkan/vulkan_core.h", + "//third_party/vulkan-headers/include/vulkan/vulkan_ohos.h", + ] +} + +ohos_ndk_library("libvulkan_ndk") { + output_name = "vulkan" + output_extension = "so" + ndk_description_file = "./libvulkan.ndk.json" + system_capability = "SystemCapability.Graphic.Vulkan" + system_capability_headers = [ + "vulkan/vk_platform.h", + "vulkan/vulkan.h", + "vulkan/vulkan_core.h", + "vulkan/vulkan_ohos.h", + ] +} diff --git a/graphic/graphic_2d/vulkan/libvulkan.ndk.json b/graphic/graphic_2d/vulkan/libvulkan.ndk.json new file mode 100644 index 000000000..46896ac1f --- /dev/null +++ b/graphic/graphic_2d/vulkan/libvulkan.ndk.json @@ -0,0 +1,248 @@ +[ + { "name": "vkAcquireNextImage2KHR" }, + { "name": "vkAcquireNextImageKHR" }, + { "name": "vkAllocateCommandBuffers" }, + { "name": "vkAllocateDescriptorSets" }, + { "name": "vkAllocateMemory" }, + { "name": "vkBeginCommandBuffer" }, + { "name": "vkBindBufferMemory" }, + { "name": "vkBindBufferMemory2" }, + { "name": "vkBindImageMemory" }, + { "name": "vkBindImageMemory2" }, + { "name": "vkCmdBeginQuery" }, + { "name": "vkCmdBeginRendering" }, + { "name": "vkCmdBeginRenderPass" }, + { "name": "vkCmdBeginRenderPass2" }, + { "name": "vkCmdBindDescriptorSets" }, + { "name": "vkCmdBindIndexBuffer" }, + { "name": "vkCmdBindPipeline" }, + { "name": "vkCmdBindVertexBuffers" }, + { "name": "vkCmdBindVertexBuffers2" }, + { "name": "vkCmdBlitImage" }, + { "name": "vkCmdBlitImage2" }, + { "name": "vkCmdClearAttachments" }, + { "name": "vkCmdClearColorImage" }, + { "name": "vkCmdClearDepthStencilImage" }, + { "name": "vkCmdCopyBuffer" }, + { "name": "vkCmdCopyBuffer2" }, + { "name": "vkCmdCopyBufferToImage" }, + { "name": "vkCmdCopyBufferToImage2" }, + { "name": "vkCmdCopyImage" }, + { "name": "vkCmdCopyImage2" }, + { "name": "vkCmdCopyImageToBuffer" }, + { "name": "vkCmdCopyImageToBuffer2" }, + { "name": "vkCmdCopyQueryPoolResults" }, + { "name": "vkCmdDispatch" }, + { "name": "vkCmdDispatchBase" }, + { "name": "vkCmdDispatchIndirect" }, + { "name": "vkCmdDraw" }, + { "name": "vkCmdDrawIndexed" }, + { "name": "vkCmdDrawIndexedIndirect" }, + { "name": "vkCmdDrawIndexedIndirectCount" }, + { "name": "vkCmdDrawIndirect" }, + { "name": "vkCmdDrawIndirectCount" }, + { "name": "vkCmdEndQuery" }, + { "name": "vkCmdEndRendering" }, + { "name": "vkCmdEndRenderPass" }, + { "name": "vkCmdEndRenderPass2" }, + { "name": "vkCmdExecuteCommands" }, + { "name": "vkCmdFillBuffer" }, + { "name": "vkCmdNextSubpass" }, + { "name": "vkCmdNextSubpass2" }, + { "name": "vkCmdPipelineBarrier" }, + { "name": "vkCmdPipelineBarrier2" }, + { "name": "vkCmdPushConstants" }, + { "name": "vkCmdResetEvent" }, + { "name": "vkCmdResetEvent2" }, + { "name": "vkCmdResetQueryPool" }, + { "name": "vkCmdResolveImage" }, + { "name": "vkCmdResolveImage2" }, + { "name": "vkCmdSetBlendConstants" }, + { "name": "vkCmdSetCullMode" }, + { "name": "vkCmdSetDepthBias" }, + { "name": "vkCmdSetDepthBiasEnable" }, + { "name": "vkCmdSetDepthBounds" }, + { "name": "vkCmdSetDepthBoundsTestEnable" }, + { "name": "vkCmdSetDepthCompareOp" }, + { "name": "vkCmdSetDepthTestEnable" }, + { "name": "vkCmdSetDepthWriteEnable" }, + { "name": "vkCmdSetDeviceMask" }, + { "name": "vkCmdSetEvent" }, + { "name": "vkCmdSetEvent2" }, + { "name": "vkCmdSetFrontFace" }, + { "name": "vkCmdSetLineWidth" }, + { "name": "vkCmdSetPrimitiveRestartEnable" }, + { "name": "vkCmdSetPrimitiveTopology" }, + { "name": "vkCmdSetRasterizerDiscardEnable" }, + { "name": "vkCmdSetScissor" }, + { "name": "vkCmdSetScissorWithCount" }, + { "name": "vkCmdSetStencilCompareMask" }, + { "name": "vkCmdSetStencilOp" }, + { "name": "vkCmdSetStencilReference" }, + { "name": "vkCmdSetStencilTestEnable" }, + { "name": "vkCmdSetStencilWriteMask" }, + { "name": "vkCmdSetViewport" }, + { "name": "vkCmdSetViewportWithCount" }, + { "name": "vkCmdUpdateBuffer" }, + { "name": "vkCmdWaitEvents" }, + { "name": "vkCmdWaitEvents2" }, + { "name": "vkCmdWriteTimestamp" }, + { "name": "vkCmdWriteTimestamp2" }, + { "name": "vkCreateBuffer" }, + { "name": "vkCreateBufferView" }, + { "name": "vkCreateCommandPool" }, + { "name": "vkCreateComputePipelines" }, + { "name": "vkCreateDescriptorPool" }, + { "name": "vkCreateDescriptorSetLayout" }, + { "name": "vkCreateDescriptorUpdateTemplate" }, + { "name": "vkCreateDevice" }, + { "name": "vkCreateDisplayModeKHR" }, + { "name": "vkCreateDisplayPlaneSurfaceKHR" }, + { "name": "vkCreateEvent" }, + { "name": "vkCreateFence" }, + { "name": "vkCreateFramebuffer" }, + { "name": "vkCreateGraphicsPipelines" }, + { "name": "vkCreateImage" }, + { "name": "vkCreateImageView" }, + { "name": "vkCreateInstance" }, + { "name": "vkCreatePipelineCache" }, + { "name": "vkCreatePipelineLayout" }, + { "name": "vkCreatePrivateDataSlot" }, + { "name": "vkCreateQueryPool" }, + { "name": "vkCreateRenderPass" }, + { "name": "vkCreateRenderPass2" }, + { "name": "vkCreateSampler" }, + { "name": "vkCreateSamplerYcbcrConversion" }, + { "name": "vkCreateSemaphore" }, + { "name": "vkCreateShaderModule" }, + { "name": "vkCreateSharedSwapchainsKHR" }, + { "name": "vkCreateSwapchainKHR" }, + { "name": "vkDestroyBuffer" }, + { "name": "vkDestroyBufferView" }, + { "name": "vkDestroyCommandPool" }, + { "name": "vkDestroyDescriptorPool" }, + { "name": "vkDestroyDescriptorSetLayout" }, + { "name": "vkDestroyDescriptorUpdateTemplate" }, + { "name": "vkDestroyDevice" }, + { "name": "vkDestroyEvent" }, + { "name": "vkDestroyFence" }, + { "name": "vkDestroyFramebuffer" }, + { "name": "vkDestroyImage" }, + { "name": "vkDestroyImageView" }, + { "name": "vkDestroyInstance" }, + { "name": "vkDestroyPipeline" }, + { "name": "vkDestroyPipelineCache" }, + { "name": "vkDestroyPipelineLayout" }, + { "name": "vkDestroyPrivateDataSlot" }, + { "name": "vkDestroyQueryPool" }, + { "name": "vkDestroyRenderPass" }, + { "name": "vkDestroySampler" }, + { "name": "vkDestroySamplerYcbcrConversion" }, + { "name": "vkDestroySemaphore" }, + { "name": "vkDestroyShaderModule" }, + { "name": "vkDestroySurfaceKHR" }, + { "name": "vkDestroySwapchainKHR" }, + { "name": "vkDeviceWaitIdle" }, + { "name": "vkEndCommandBuffer" }, + { "name": "vkEnumerateDeviceExtensionProperties" }, + { "name": "vkEnumerateDeviceLayerProperties" }, + { "name": "vkEnumerateInstanceExtensionProperties" }, + { "name": "vkEnumerateInstanceLayerProperties" }, + { "name": "vkEnumerateInstanceVersion" }, + { "name": "vkEnumeratePhysicalDeviceGroups" }, + { "name": "vkEnumeratePhysicalDevices" }, + { "name": "vkFlushMappedMemoryRanges" }, + { "name": "vkFreeCommandBuffers" }, + { "name": "vkFreeDescriptorSets" }, + { "name": "vkFreeMemory" }, + { "name": "vkGetBufferDeviceAddress" }, + { "name": "vkGetBufferMemoryRequirements" }, + { "name": "vkGetBufferMemoryRequirements2" }, + { "name": "vkGetBufferOpaqueCaptureAddress" }, + { "name": "vkGetDescriptorSetLayoutSupport" }, + { "name": "vkGetDeviceBufferMemoryRequirements" }, + { "name": "vkGetDeviceGroupPeerMemoryFeatures" }, + { "name": "vkGetDeviceGroupPresentCapabilitiesKHR" }, + { "name": "vkGetDeviceGroupSurfacePresentModesKHR" }, + { "name": "vkGetDeviceImageMemoryRequirements" }, + { "name": "vkGetDeviceImageSparseMemoryRequirements" }, + { "name": "vkGetDeviceMemoryCommitment" }, + { "name": "vkGetDeviceMemoryOpaqueCaptureAddress" }, + { "name": "vkGetDeviceProcAddr" }, + { "name": "vkGetDeviceQueue" }, + { "name": "vkGetDeviceQueue2" }, + { "name": "vkGetDisplayModeProperties2KHR" }, + { "name": "vkGetDisplayModePropertiesKHR" }, + { "name": "vkGetDisplayPlaneCapabilities2KHR" }, + { "name": "vkGetDisplayPlaneCapabilitiesKHR" }, + { "name": "vkGetDisplayPlaneSupportedDisplaysKHR" }, + { "name": "vkGetEventStatus" }, + { "name": "vkGetFenceStatus" }, + { "name": "vkGetImageMemoryRequirements" }, + { "name": "vkGetImageMemoryRequirements2" }, + { "name": "vkGetImageSparseMemoryRequirements" }, + { "name": "vkGetImageSparseMemoryRequirements2" }, + { "name": "vkGetImageSubresourceLayout" }, + { "name": "vkGetInstanceProcAddr" }, + { "name": "vkGetPhysicalDeviceDisplayPlaneProperties2KHR" }, + { "name": "vkGetPhysicalDeviceDisplayPlanePropertiesKHR" }, + { "name": "vkGetPhysicalDeviceDisplayProperties2KHR" }, + { "name": "vkGetPhysicalDeviceDisplayPropertiesKHR" }, + { "name": "vkGetPhysicalDeviceExternalBufferProperties" }, + { "name": "vkGetPhysicalDeviceExternalFenceProperties" }, + { "name": "vkGetPhysicalDeviceExternalSemaphoreProperties" }, + { "name": "vkGetPhysicalDeviceFeatures" }, + { "name": "vkGetPhysicalDeviceFeatures2" }, + { "name": "vkGetPhysicalDeviceFormatProperties" }, + { "name": "vkGetPhysicalDeviceFormatProperties2" }, + { "name": "vkGetPhysicalDeviceImageFormatProperties" }, + { "name": "vkGetPhysicalDeviceImageFormatProperties2" }, + { "name": "vkGetPhysicalDeviceMemoryProperties" }, + { "name": "vkGetPhysicalDeviceMemoryProperties2" }, + { "name": "vkGetPhysicalDevicePresentRectanglesKHR" }, + { "name": "vkGetPhysicalDeviceProperties" }, + { "name": "vkGetPhysicalDeviceProperties2" }, + { "name": "vkGetPhysicalDeviceQueueFamilyProperties" }, + { "name": "vkGetPhysicalDeviceQueueFamilyProperties2" }, + { "name": "vkGetPhysicalDeviceSparseImageFormatProperties" }, + { "name": "vkGetPhysicalDeviceSparseImageFormatProperties2" }, + { "name": "vkGetPhysicalDeviceSurfaceCapabilities2KHR" }, + { "name": "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" }, + { "name": "vkGetPhysicalDeviceSurfaceFormats2KHR" }, + { "name": "vkGetPhysicalDeviceSurfaceFormatsKHR" }, + { "name": "vkGetPhysicalDeviceSurfacePresentModesKHR" }, + { "name": "vkGetPhysicalDeviceSurfaceSupportKHR" }, + { "name": "vkGetPhysicalDeviceToolProperties" }, + { "name": "vkGetPipelineCacheData" }, + { "name": "vkGetPrivateData" }, + { "name": "vkGetQueryPoolResults" }, + { "name": "vkGetRenderAreaGranularity" }, + { "name": "vkGetSemaphoreCounterValue" }, + { "name": "vkGetSwapchainImagesKHR" }, + { "name": "vkInvalidateMappedMemoryRanges" }, + { "name": "vkMapMemory" }, + { "name": "vkMergePipelineCaches" }, + { "name": "vkQueueBindSparse" }, + { "name": "vkQueuePresentKHR" }, + { "name": "vkQueueSubmit" }, + { "name": "vkQueueSubmit2" }, + { "name": "vkQueueWaitIdle" }, + { "name": "vkResetCommandBuffer" }, + { "name": "vkResetCommandPool" }, + { "name": "vkResetDescriptorPool" }, + { "name": "vkResetEvent" }, + { "name": "vkResetFences" }, + { "name": "vkResetQueryPool" }, + { "name": "vkSetEvent" }, + { "name": "vkSetPrivateData" }, + { "name": "vkSignalSemaphore" }, + { "name": "vkTrimCommandPool" }, + { "name": "vkUnmapMemory" }, + { "name": "vkUpdateDescriptorSets" }, + { "name": "vkUpdateDescriptorSetWithTemplate" }, + { "name": "vkWaitForFences" }, + { "name": "vkWaitSemaphores" }, + { "name": "vkCreateSurfaceOHOS" }, + { "name": "vkGetNativeBufferPropertiesOHOS" }, + { "name": "vkGetMemoryNativeBufferOHOS" } +] \ No newline at end of file diff --git a/hiviewdfx/hiappevent/BUILD.gn b/hiviewdfx/hiappevent/BUILD.gn new file mode 100644 index 000000000..9a0c41b0c --- /dev/null +++ b/hiviewdfx/hiappevent/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libhiappevent_ndk") { + output_name = "hiappevent_ndk" + ndk_description_file = "./libhiappevent.ndk.json" + min_compact_version = "1" + system_capability = "SystemCapability.HiviewDFX.HiAppEvent" +} + +ohos_ndk_headers("libhiappevent_header") { + dest_dir = "$ndk_headers_out_dir/hiappevent" + sources = [ + "./include/hiappevent/hiappevent.h", + "./include/hiappevent/hiappevent_cfg.h", + "./include/hiappevent/hiappevent_event.h", + "./include/hiappevent/hiappevent_param.h", + ] +} diff --git a/hiviewdfx/hiappevent/include/hiappevent/hiappevent.h b/hiviewdfx/hiappevent/include/hiappevent/hiappevent.h new file mode 100644 index 000000000..2b3d36311 --- /dev/null +++ b/hiviewdfx/hiappevent/include/hiappevent/hiappevent.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HIVIEWDFX_HIAPPEVENT_H +#define HIVIEWDFX_HIAPPEVENT_H +/** + * @addtogroup HiAppEvent + * @{ + * + * @brief Provides application event logging functions. + * + * Provides the event logging function for applications to log the fault, statistical, security, and user behavior + * events reported during running. Based on event information, you will be able to analyze the running status of + * applications. + * + * @syscap SystemCapability.HiviewDFX.HiAppEvent + * + * @since 8 + * @version 1.0 + */ + +/** + * @file hiappevent.h + * + * @brief Defines the application event logging functions of the HiAppEvent module. + * + * Before performing application event logging, you must construct a ParamList object to store the input + * event parameters and specify the event domain, event name, and event type. + * + *

Event domain: a string used to identify the domain of event logging. + *

Event name: a string used to identify the event name of event logging. + *

Event type: FAULT, STATISTIC, SECURITY, BEHAVIOR. + *

ParamList: a linked list used to store event parameters, each of which is comprised of the parameter name and + * parameter value. + * + * Sample code: + * 00 Including the header file: + *

+ *     #include "hiappevent/hiappevent.h"
+ * 
+ * 01 create a ParamList pointer. + *
+ *     ParamList list = OH_HiAppEvent_CreateParamList();
+ * 
+ * 02 add params to the ParamList. + *
+ *     bool boolean = true;
+ *     OH_HiAppEvent_AddBoolParam(list, "bool_key", boolean);
+ *     int32_t nums[] = {1, 2, 3};
+ *     OH_HiAppEvent_AddInt32ArrayParam(list, "int32_arr_key", nums, sizeof(nums) / sizeof(nums[0]));
+ * 
+ * 03 performing event logging. + *
+ *     int res = OH_HiAppEvent_Write("test_domain", "test_event", BEHAVIOR, list);
+ * 
+ * 04 destroy the ParamList pointer. + *
+ *     OH_HiAppEvent_DestroyParamList(list);
+ * 
+ * + * @since 8 + * @version 1.0 + */ + +#include +#include + +#include "hiappevent_cfg.h" +#include "hiappevent_event.h" +#include "hiappevent_param.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Event types. + * + * You are advised to select event types based on their respective usage scenarios. + * + * @since 8 + * @version 1.0 + */ +enum EventType { + /* Fault event type */ + FAULT = 1, + + /* Statistic event type */ + STATISTIC = 2, + + /* Security event type */ + SECURITY = 3, + + /* Behavior event type */ + BEHAVIOR = 4 +}; + +/** + * @brief Event param list node. + * + * @since 8 + * @version 1.0 + */ +typedef struct ParamListNode* ParamList; + +/** + * @brief Create a pointer to the ParamList. + * + * @return Pointer to the ParamList. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_CreateParamList(void); + +/** + * @brief Destroy a pointer to the ParamList. + * + * @param list Event param list. + * @since 8 + * @version 1.0 + */ +void OH_HiAppEvent_DestroyParamList(ParamList list); + +/** + * @brief Add bool param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param boolean The bool value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddBoolParam(ParamList list, const char* name, bool boolean); + +/** + * @brief Add bool array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param booleans The bool array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddBoolArrayParam(ParamList list, const char* name, const bool* booleans, int arrSize); + +/** + * @brief Add int8_t param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param num The int8_t value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt8Param(ParamList list, const char* name, int8_t num); + +/** + * @brief Add int8_t array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param nums The int8_t array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt8ArrayParam(ParamList list, const char* name, const int8_t* nums, int arrSize); + +/** + * @brief Add int16_t param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param num The int16_t value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt16Param(ParamList list, const char* name, int16_t num); + +/** + * @brief Add int16_t array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param nums The int16_t array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt16ArrayParam(ParamList list, const char* name, const int16_t* nums, int arrSize); + +/** + * @brief Add int32_t param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param num The int32_t value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt32Param(ParamList list, const char* name, int32_t num); + +/** + * @brief Add int32_t array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param nums The int32_t array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt32ArrayParam(ParamList list, const char* name, const int32_t* nums, int arrSize); + +/** + * @brief Add int64_t param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param num The int64_t value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt64Param(ParamList list, const char* name, int64_t num); + +/** + * @brief Add int64_t array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param nums The int64_t array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddInt64ArrayParam(ParamList list, const char* name, const int64_t* nums, int arrSize); + +/** + * @brief Add float param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param num The float value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddFloatParam(ParamList list, const char* name, float num); + +/** + * @brief Add float array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param nums The float array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddFloatArrayParam(ParamList list, const char* name, const float* nums, int arrSize); + +/** + * @brief Add double param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param num The double value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddDoubleParam(ParamList list, const char* name, double num); + +/** + * @brief Add double array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param nums The double array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddDoubleArrayParam(ParamList list, const char* name, const double* nums, int arrSize); + +/** + * @brief Add string param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param str The string value of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddStringParam(ParamList list, const char* name, const char* str); + +/** + * @brief Add string array param to the ParamList. + * + * @param list The ParamList of params to be added. + * @param name The name of the param to be added. + * @param strs The string array value of the param to be added. + * @param arrSize The array size of the param to be added. + * @return ParamList after the param is added. + * @since 8 + * @version 1.0 + */ +ParamList OH_HiAppEvent_AddStringArrayParam(ParamList list, const char* name, const char * const *strs, int arrSize); + +/** + * @brief Implements logging of application events whose parameters are of the list type. + * + * Before logging an application event, this API will first verify parameters of this event. + * If the verification is successful, the API will write the event to the event file. + * + * @param domain Indicates the event domain. You can customize the event domain as needed. + * @param name Indicates the event name. You can customize the event name as needed. + * @param type Indicates the event type, which is defined in {@link EventType}. + * @param list Indicates a linked list of event parameters, each of which is comprised of the parameter name and + * parameter value. + * @return Returns {@code 0} if the event parameter verification is successful, and the event will be written to + * the event file; returns a positive integer if invalid parameters are present in the event, and + * the event will be written to the event file after the invalid parameters are ignored; returns a + * negative integer if the event parameter verification fails, and the event will not be written to the event file. + * @since 8 + * @version 1.0 + */ +int OH_HiAppEvent_Write(const char* domain, const char* name, enum EventType type, const ParamList list); + +/** + * @brief Implements the configuration function of application events logging. + * + * Application event logging configuration interface, which is used to configure event logging switch, + * event file directory storage quota size and other functions. + * + * @param name Configuration item name. + * @param value Configuration item value. + * @return Configuration result. + * @since 8 + * @version 1.0 + */ +bool OH_HiAppEvent_Configure(const char* name, const char* value); + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif // HIVIEWDFX_HIAPPEVENT_H \ No newline at end of file diff --git a/hiviewdfx/hiappevent/include/hiappevent/hiappevent_cfg.h b/hiviewdfx/hiappevent/include/hiappevent/hiappevent_cfg.h new file mode 100644 index 000000000..e2a6fbeaf --- /dev/null +++ b/hiviewdfx/hiappevent/include/hiappevent/hiappevent_cfg.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HIVIEWDFX_HIAPPEVENT_CONFIG_H +#define HIVIEWDFX_HIAPPEVENT_CONFIG_H + +/** + * @addtogroup HiAppEvent + * @{ + * + * @brief Provides application event logging functions. + * + * Provides the event logging function for applications to log the fault, statistical, security, and user behavior + * events reported during running. Based on event information, you will be able to analyze the running status of + * applications. + * + * @syscap SystemCapability.HiviewDFX.HiAppEvent + * + * @since 8 + * @version 1.0 + */ + +/** + * @file hiappevent_cfg.h + * + * @brief Defines the names of all the configuration items of the event logging configuration function. + * + * If you want to configure the event logging function, you can directly use the configuration item constants. + * + * Sample code: + *
+ *     bool res = OH_HiAppEvent_Configure(MAX_STORAGE, "100M");
+ * 
+ * + * @since 8 + * @version 1.0 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Event logging switch. + * + * @since 8 + * @version 1.0 + */ +#define DISABLE "disable" + +/** + * @brief Event file directory storage quota size. + * + * @since 8 + * @version 1.0 + */ +#define MAX_STORAGE "max_storage" + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif // HIVIEWDFX_HIAPPEVENT_CONFIG_H \ No newline at end of file diff --git a/hiviewdfx/hiappevent/include/hiappevent/hiappevent_event.h b/hiviewdfx/hiappevent/include/hiappevent/hiappevent_event.h new file mode 100644 index 000000000..66aa52061 --- /dev/null +++ b/hiviewdfx/hiappevent/include/hiappevent/hiappevent_event.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HIVIEWDFX_HIAPPEVENT_EVENT_H +#define HIVIEWDFX_HIAPPEVENT_EVENT_H + +/** + * @addtogroup HiAppEvent + * @{ + * + * @brief Provides application event logging functions. + * + * Provides the event logging function for applications to log the fault, statistical, security, and user behavior + * events reported during running. Based on event information, you will be able to analyze the running status of + * applications. + * + * @syscap SystemCapability.HiviewDFX.HiAppEvent + * + * @since 8 + * @version 1.0 + */ + +/** + * @file hiappevent_event.h + * + * @brief Defines the event names of all predefined events. + * + * In addition to custom events associated with specific apps, you can also use predefined events for logging. + * + * Sample code: + *
+ *     ParamList list = OH_HiAppEvent_CreateParamList();
+ *     OH_HiAppEvent_AddInt32Param(list, PARAM_USER_ID, 123);
+ *     int res = OH_HiAppEvent_Write("user_domain", EVENT_USER_LOGIN, BEHAVIOR, list);
+ *     OH_HiAppEvent_DestroyParamList(list);
+ * 
+ * + * @since 8 + * @version 1.0 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief user login event. + * + * @since 8 + * @version 1.0 + */ +#define EVENT_USER_LOGIN "hiappevent.user_login" + +/** + * @brief user logout event. + * + * @since 8 + * @version 1.0 + */ +#define EVENT_USER_LOGOUT "hiappevent.user_logout" + +/** + * @brief distributed service event. + * + * @since 8 + * @version 1.0 + */ +#define EVENT_DISTRIBUTED_SERVICE_START "hiappevent.distributed_service_start" + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif // HIVIEWDFX_HIAPPEVENT_EVENT_H \ No newline at end of file diff --git a/hiviewdfx/hiappevent/include/hiappevent/hiappevent_param.h b/hiviewdfx/hiappevent/include/hiappevent/hiappevent_param.h new file mode 100644 index 000000000..f47972e8d --- /dev/null +++ b/hiviewdfx/hiappevent/include/hiappevent/hiappevent_param.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HIVIEWDFX_HIAPPEVENT_PARAM_H +#define HIVIEWDFX_HIAPPEVENT_PARAM_H + +/** + * @addtogroup HiAppEvent + * @{ + * + * @brief Provides application event logging functions. + * + * Provides the event logging function for applications to log the fault, statistical, security, and user behavior + * events reported during running. Based on event information, you will be able to analyze the running status of + * applications. + * + * @syscap SystemCapability.HiviewDFX.HiAppEvent + * + * @since 8 + * @version 1.0 + */ + +/** + * @file hiappevent_param.h + * + * @brief Defines the param names of all predefined events. + * + * In addition to custom events associated with specific apps, you can also use predefined events for logging. + * + * Sample code: + *
+ *     ParamList list = OH_HiAppEvent_CreateParamList();
+ *     OH_HiAppEvent_AddInt32Param(list, PARAM_USER_ID, 123);
+ *     int res = OH_HiAppEvent_Write("user_domain", EVENT_USER_LOGIN, BEHAVIOR, list);
+ *     OH_HiAppEvent_DestroyParamList(list);
+ * 
+ * + * @since 8 + * @version 1.0 + */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Preset param name, user id param. + * + * @since 8 + * @version 1.0 + */ +#define PARAM_USER_ID "user_id" + +/** + * @brief Preset param name, distributed service name param. + * + * @since 8 + * @version 1.0 + */ +#define PARAM_DISTRIBUTED_SERVICE_NAME "ds_name" + +/** + * @brief Preset param name, distributed service instance id param. + * + * @since 8 + * @version 1.0 + */ +#define PARAM_DISTRIBUTED_SERVICE_INSTANCE_ID "ds_instance_id" + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif // HIVIEWDFX_HIAPPEVENT_PARAM_H \ No newline at end of file diff --git a/hiviewdfx/hiappevent/libhiappevent.ndk.json b/hiviewdfx/hiappevent/libhiappevent.ndk.json new file mode 100644 index 000000000..44d3c6a74 --- /dev/null +++ b/hiviewdfx/hiappevent/libhiappevent.ndk.json @@ -0,0 +1,62 @@ +[ + { + "name": "OH_HiAppEvent_Write" + }, + { + "name": "OH_HiAppEvent_Configure" + }, + { + "name": "OH_HiAppEvent_AddBoolParam" + }, + { + "name": "OH_HiAppEvent_AddBoolArrayParam" + }, + { + "name": "OH_HiAppEvent_AddInt8Param" + }, + { + "name": "OH_HiAppEvent_AddInt8ArrayParam" + }, + { + "name": "OH_HiAppEvent_AddInt16Param" + }, + { + "name": "OH_HiAppEvent_AddInt16ArrayParam" + }, + { + "name": "OH_HiAppEvent_AddInt32Param" + }, + { + "name": "OH_HiAppEvent_AddInt32ArrayParam" + }, + { + "name": "OH_HiAppEvent_AddInt64Param" + }, + { + "name": "OH_HiAppEvent_AddInt64ArrayParam" + }, + { + "name": "OH_HiAppEvent_AddFloatParam" + }, + { + "name": "OH_HiAppEvent_AddFloatArrayParam" + }, + { + "name": "OH_HiAppEvent_AddDoubleParam" + }, + { + "name": "OH_HiAppEvent_AddDoubleArrayParam" + }, + { + "name": "OH_HiAppEvent_AddStringParam" + }, + { + "name": "OH_HiAppEvent_AddStringArrayParam" + }, + { + "name": "OH_HiAppEvent_CreateParamList" + }, + { + "name": "OH_HiAppEvent_DestroyParamList" + } +] diff --git a/hiviewdfx/hilog/BUILD.gn b/hiviewdfx/hilog/BUILD.gn new file mode 100644 index 000000000..1d6816c60 --- /dev/null +++ b/hiviewdfx/hilog/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libhilog_ndk") { + output_name = "hilog_ndk" + ndk_description_file = "./libhilog.ndk.json" + min_compact_version = "1" + system_capability = "SystemCapability.HiviewDFX.HiLog" +} + +ohos_ndk_headers("hilog_header") { + dest_dir = "$ndk_headers_out_dir/hilog" + sources = [ "./include/hilog/log.h" ] +} diff --git a/hiviewdfx/hilog/include/hilog/log.h b/hiviewdfx/hilog/include/hilog/log.h new file mode 100644 index 000000000..26049d945 --- /dev/null +++ b/hiviewdfx/hilog/include/hilog/log.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HIVIEWDFX_HILOG_H +#define HIVIEWDFX_HILOG_H +/** + * @addtogroup HiLog + * @{ + * + * @brief Provides logging functions. + * + * For example, you can use these functions to output logs of the specified log type, service domain, log tag, + * and log level. + * + * @syscap SystemCapability.HiviewDFX.HiLog + * + * @since 8 + */ + +/** + * @file log.h + * + * @brief Defines the logging functions of the HiLog module. + * + * Before outputting logs, you must define the service domain, and log tag, use the function with + * the specified log type and level, and specify the privacy identifier.\n + *
  • Service domain: used to identify the subsystem and module of a service. Its value is a hexadecimal + * integer ranging from 0x0 to 0xFFFF. \n + *
  • Log tag: a string used to identify the class, file, or service.
  • \n + *
  • Log level: DEBUG, INFO, WARN, ERROR, and FATAL
  • \n + *
  • Parameter format: a printf format string that starts with a % character, including format specifiers + * and variable parameters.
  • \n + *
  • Privacy identifier: {public} or {private} added between the % character and the format specifier in + * each parameter. Note that each parameter has a privacy identifier. If no privacy identifier is added, + * the parameter is considered to be private.
\n + * + * Sample code:\n + * Defining the service domain and log tag:\n + * #include \n + * #define LOG_DOMAIN 0x0201\n + * #define LOG_TAG "MY_TAG"\n + * Outputting logs:\n + * HILOG_WARN({@link LOG_APP}, "Failed to visit %{private}s, reason:%{public}d.", url, errno);\n + * Output result:\n + * 05-06 15:01:06.870 1051 1051 W 0201/MY_TAG: Failed to visit , reason:503.\n + * + * @since 8 + */ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines the service domain for a log file. + * + * The service domain is used to identify the subsystem and module of a service. Its value is a hexadecimal integer + * ranging from 0x0 to 0xFFFF. If the value is beyond the range, its significant bits are automatically truncated. \n + * + * @since 8 + */ +#ifndef LOG_DOMAIN +#define LOG_DOMAIN 0 +#endif + +/** + * @brief Defines a string constant used to identify the class, file, or service. + * + * @since 8 + */ +#ifndef LOG_TAG +#define LOG_TAG NULL +#endif + +/** + * @brief Enumerates log types. + * + * Currently, LOG_APP is available. \n + * + * @since 8 + */ +typedef enum { + /** Third-party application logs */ + LOG_APP = 0, +} LogType; + +/** + * @brief Enumerates log levels. + * + * You are advised to select log levels based on their respective usage scenarios:\n + *
  • DEBUG: used for debugging and disabled from commercial releases
  • \n + *
  • INFO: used for logging important system running status and steps in key processes
  • \n + *
  • WARN: used for logging unexpected exceptions that have little impact on user experience and can + * automatically recover. Logs at this level are generally output when such exceptions are detected and + * captured.
  • \n + *
  • ERROR: used for logging malfunction that affects user experience and cannot automatically + * recover
  • \n + *
  • FATAL: used for logging major exceptions that have severely affected user experience and should + * not occur.
\n + * + * @since 8 + */ +typedef enum { + /** Debug level to be used by {@link OH_LOG_DEBUG} */ + LOG_DEBUG = 3, + /** Informational level to be used by {@link OH_LOG_INFO} */ + LOG_INFO = 4, + /** Warning level to be used by {@link OH_LOG_WARN} */ + LOG_WARN = 5, + /** Error level to be used by {@link OH_LOG_ERROR} */ + LOG_ERROR = 6, + /** Fatal level to be used by {@link OH_LOG_FATAL} */ + LOG_FATAL = 7, +} LogLevel; + +/** + * @brief Outputs logs. + * + * You can use this function to output logs based on the specified log type, log level, service domain, log tag, + * and variable parameters determined by the format specifier and privacy identifier in the printf format. + * + * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}. + * @param level Indicates the log level, which can be LOG_DEBUG, LOG_INFO, LOG_WARN, + * LOG_ERROR, and LOG_FATAL. + * @param domain Indicates the service domain of logs. Its value is a hexadecimal integer ranging from 0x0 to 0xFFFF. + * @param tag Indicates the log tag, which is a string used to identify the class, file, or service behavior. + * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy + * identifier. Specifically, {public} or {private} is added between the % character and the format specifier + * in each parameter. \n + * @param ... Indicates a list of parameters. The number and type of parameters must map onto the format specifiers + * in the format string. + * @return Returns 0 or a larger value if the operation is successful; returns a value smaller + * than 0 otherwise. + * @since 8 + */ +int OH_LOG_Print(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...) + __attribute__((__format__(os_log, 5, 6))); + +/** + * @brief Checks whether logs of the specified service domain, log tag, and log level can be output. + * + * @param domain Indicates the service domain of logs. + * @param tag Indicates the log tag. + * @param level Indicates the log level. + * @return Returns true if the specified logs can be output; returns false otherwise. + * @since 8 + */ +bool OH_LOG_IsLoggable(unsigned int domain, const char *tag, LogLevel level); + +/** + * @brief Outputs debug logs. This is a function-like macro. + * + * Before calling this function, define the log service domain and log tag. Generally, you need to define them at + * the beginning of the source file. \n + * + * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}. + * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the + * privacy identifier. Specifically, {public} or {private} is added between the % character and the format specifier + * in each parameter. \n + * @param ... Indicates a list of parameters. The number and type of parameters must map onto the format specifiers + * in the format string. + * @see OH_LOG_Print + * @since 8 + */ +#define OH_LOG_DEBUG(type, ...) ((void)OH_LOG_Print((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) + +/** + * @brief Outputs informational logs. This is a function-like macro. + * + * Before calling this function, define the log service domain and log tag. Generally, you need to define them + * at the beginning of the source file. \n + * + * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}. + * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy + * identifier. Specifically, {public} or {private} is added between the % character and the format specifier in + * each parameter. \n + * @param ... Indicates a list of parameters. The number and type of parameters must map onto the format specifiers + * in the format string. + * @see OH_LOG_Print + * @since 8 + */ +#define OH_LOG_INFO(type, ...) ((void)OH_LOG_Print((type), LOG_INFO, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) + +/** + * @brief Outputs warning logs. This is a function-like macro. + * + * Before calling this function, define the log service domain and log tag. Generally, you need to define them + * at the beginning of the source file. \n + * + * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}. + * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the + * privacy identifier. Specifically, {public} or {private} is added between the % character and the format specifier + * in each parameter. \n + * @param ... Indicates a list of parameters. The number and type of parameters must map onto the format specifiers + * in the format string. + * @see OH_LOG_Print + * @since 8 + */ +#define OH_LOG_WARN(type, ...) ((void)OH_LOG_Print((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) + +/** + * @brief Outputs error logs. This is a function-like macro. + * + * Before calling this function, define the log service domain and log tag. Generally, you need to define + * them at the beginning of the source file. \n + * + * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}. + * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy + * identifier. Specifically, {public} or {private} is added between the % character and the format specifier in each + * parameter. \n + * @param ... Indicates a list of parameters. The number and type of parameters must map onto the format specifiers + * in the format string. + * @see OH_LOG_Print + * @since 8 + */ +#define OH_LOG_ERROR(type, ...) ((void)OH_LOG_Print((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) + +/** + * @brief Outputs fatal logs. This is a function-like macro. + * + * Before calling this function, define the log service domain and log tag. Generally, you need to define them at + * the beginning of the source file. \n + * + * @param type Indicates the log type. The type for third-party applications is defined by {@link LOG_APP}. + * @param fmt Indicates the format string, which is an enhancement of a printf format string and supports the privacy + * identifier. Specifically, {public} or {private} is added between the % character and the format specifier in + * each parameter. \n + * @param ... Indicates a list of parameters. The number and type of parameters must map onto the format specifiers + * in the format string. + * @see OH_LOG_Print + * @since 8 + */ +#define OH_LOG_FATAL(type, ...) ((void)OH_LOG_Print((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, __VA_ARGS__)) + +#ifdef __cplusplus +} +#endif +/** @} */ + +#ifdef HILOG_RAWFORMAT +#include "hilog/log_inner.h" +#endif + +#endif // HIVIEWDFX_HILOG_C_H diff --git a/hiviewdfx/hilog/libhilog.ndk.json b/hiviewdfx/hilog/libhilog.ndk.json new file mode 100644 index 000000000..f121a608e --- /dev/null +++ b/hiviewdfx/hilog/libhilog.ndk.json @@ -0,0 +1,8 @@ +[ + { + "name": "OH_LOG_Print" + }, + { + "name": "OH_LOG_IsLoggable" + } +] diff --git a/hiviewdfx/hitrace/BUILD.gn b/hiviewdfx/hitrace/BUILD.gn new file mode 100644 index 000000000..00086c79a --- /dev/null +++ b/hiviewdfx/hitrace/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libhitrace_ndk") { + output_name = "hitrace_ndk" + ndk_description_file = "./libhitrace.ndk.json" + min_compact_version = "1" + system_capability = "SystemCapability.HiviewDFX.HiTrace" +} + +ohos_ndk_headers("hitrace_header") { + dest_dir = "$ndk_headers_out_dir/hitrace" + sources = [ "./include/hitrace/trace.h" ] +} diff --git a/hiviewdfx/hitrace/include/hitrace/trace.h b/hiviewdfx/hitrace/include/hitrace/trace.h new file mode 100644 index 000000000..1940d14b1 --- /dev/null +++ b/hiviewdfx/hitrace/include/hitrace/trace.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef HIVIEWDFX_HITRACE_H +#define HIVIEWDFX_HITRACE_H +/** + * @addtogroup Hitrace + * @{ + * + * @brief hiTraceMeter provides APIs for system performance trace. + * + * You can call the APIs provided by hiTraceMeter in your own service logic to effectively + * track service processes and check the system performance. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * + * @since 10 + */ + +/** + * @file trace.h + * + * @brief Defines APIs of the HiTraceMeter module for performance trace. + * + * Sample code: \n + * Synchronous timeslice trace event: \n + * OH_HiTrace_StartTrace("hitraceTest");\n + * OH_HiTrace_FinishTrace();\n + * Output: \n + * <...>-1668 (-------) [003] .... 135.059377: tracing_mark_write: B|1668|H:hitraceTest \n + * <...>-1668 (-------) [003] .... 135.059415: tracing_mark_write: E|1668| \n + * Asynchronous timeslice trace event:\n + * OH_HiTrace_StartAsyncTrace("hitraceTest", 123); \n + * OH_HiTrace_FinishAsyncTrace("hitraceTest", 123); \n + * Output: \n + * <...>-2477 (-------) [001] .... 396.427165: tracing_mark_write: S|2477|H:hitraceTest 123 \n + * <...>-2477 (-------) [001] .... 396.427196: tracing_mark_write: F|2477|H:hitraceTest 123 \n + * Integer value trace event:\n + * OH_HiTrace_CountTrace("hitraceTest", 500); \n + * Output: \n + * <...>-2638 (-------) [002] .... 458.904382: tracing_mark_write: C|2638|H:hitraceTest 500 \n + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * @since 10 + */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Marks the start of a synchronous trace task. + * + * The OH_HiTrace_StartTrace and OH_HiTrace_FinishTrace APIs must be used in pairs. + * The two APIs can be used in nested mode. The stack data structure is used for matching during trace data parsing. + * + * @param name Name of a trace task. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * @since 10 + */ +void OH_HiTrace_StartTrace(const char *name); + +/** + * @brief Marks the end of a synchronous trace task. + * + * This API must be used with OH_HiTrace_StartTrace in pairs. During trace data parsing, the system matches + * it with the OH_HiTrace_StartTrace API recently invoked in the service process. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * @since 10 + */ +void OH_HiTrace_FinishTrace(void); + +/** + * @brief Marks the start of an asynchronous trace task. + * + * This API is called to implement performance trace in asynchronous manner. The start and end of an asynchronous + * trace task do not occur in sequence. Therefore, a unique taskId is required to ensure proper data parsing. + * It is passed as an input parameter for the asynchronous API. + * This API is used with OH_HiTrace_FinishAsyncTrace in pairs. The two APIs that have the same name and + * task ID together form an asynchronous timeslice trace task. + * If multiple trace tasks with the same name need to be performed at the same time or a trace task needs to be + * performed multiple times concurrently, different task IDs must be specified in OH_HiTrace_StartTrace. + * If the trace tasks with the same name are not performed at the same time, the same taskId can be used. + * + * @param name Name of the asynchronous trace task. + * @param taskId ID of the asynchronous trace task. The start and end of an asynchronous trace task do not occur in + * sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the + * unique task ID together. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * @since 10 + */ +void OH_HiTrace_StartAsyncTrace(const char *name, int32_t taskId); + +/** + * @brief Marks the end of an asynchronous trace task. + * + * This API is called in the callback function after an asynchronous trace is complete. + * It is used with OH_HiTrace_StartAsyncTrace in pairs. Its name and task ID must be the same as those of + * OH_HiTrace_StartAsyncTrace. + * + * @param name Name of the asynchronous trace task. + * @param taskId ID of the asynchronous trace task. The start and end of an asynchronous trace task do not occur in + * sequence. Therefore, the start and end of an asynchronous trace need to be matched based on the task name and the + * unique task ID together. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * @since 10 + */ +void OH_HiTrace_FinishAsyncTrace(const char *name, int32_t taskId); + +/** + * @brief Traces the value change of an integer variable based on its name. + * + * This API can be executed for multiple times to trace the value change of a given integer variable at different + * time points. + * + * @param name Name of the integer variable. It does not need to be the same as the real variable name. + * @param count Integer value. Generally, an integer variable can be passed. + * + * @syscap SystemCapability.HiviewDFX.HiTrace + * @since 10 + */ +void OH_HiTrace_CountTrace(const char *name, int64_t count); + +#ifdef __cplusplus +} +#endif +#endif // HIVIEWDFX_HITRACE_H diff --git a/hiviewdfx/hitrace/libhitrace.ndk.json b/hiviewdfx/hitrace/libhitrace.ndk.json new file mode 100644 index 000000000..accfdcd97 --- /dev/null +++ b/hiviewdfx/hitrace/libhitrace.ndk.json @@ -0,0 +1,17 @@ +[ + { + "name": "OH_HiTrace_StartTrace" + }, + { + "name": "OH_HiTrace_FinishTrace" + }, + { + "name": "OH_HiTrace_StartAsyncTrace" + }, + { + "name": "OH_HiTrace_FinishAsyncTrace" + }, + { + "name": "OH_HiTrace_CountTrace" + } +] \ No newline at end of file diff --git a/multimedia/audio_framework/BUILD.gn b/multimedia/audio_framework/BUILD.gn new file mode 100644 index 000000000..6393654ab --- /dev/null +++ b/multimedia/audio_framework/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/audio_framework/config.gni") + +ohos_ndk_headers("ohaudio_header") { + dest_dir = "$ndk_headers_out_dir/ohaudio" + sources = [ + "audio_capturer/native_audiocapturer.h", + "audio_renderer/native_audiorenderer.h", + "common/native_audiostream_base.h", + "common/native_audiostreambuilder.h", + ] +} + +ohos_ndk_library("libohaudio_ndk") { + output_name = "ohaudio" + output_extension = "so" + ndk_description_file = "./ohaudio.ndk.json" + system_capability = "SystemCapability.Multimedia.Audio.Core" + system_capability_headers = [ + "ohaudio/native_audiostream_base.h", + "ohaudio/native_audiostreambuilder.h", + "ohaudio/native_audiorenderer.h", + "ohaudio/native_audiocapturer.h", + ] +} diff --git a/multimedia/audio_framework/audio_capturer/native_audiocapturer.h b/multimedia/audio_framework/audio_capturer/native_audiocapturer.h new file mode 100644 index 000000000..68d5796ca --- /dev/null +++ b/multimedia/audio_framework/audio_capturer/native_audiocapturer.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup OHAudio + * @{ + * + * @brief Provide the definition of the C interface for the audio module. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * + * @since 10 + * @version 1.0 + */ + +/** + * @file native_audiocapturer.h + * + * @brief Declare audio stream related interfaces for input type. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * @since 10 + * @version 1.0 + */ + +#ifndef NATIVE_AUDIOCAPTURER_H +#define NATIVE_AUDIOCAPTURER_H + +#include +#include "native_audiostream_base.h" +#ifdef __cplusplus +extern "C" { +#endif +/* + * Request to release the capturer stream. + * + * @since 10 + * @permission ohos.permission.MICROPHONE + * + * @param capturer reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_Release(OH_AudioCapturer* capturer); + +/* + * Request to start the capturer stream. + * + * @since 10 + * @permission ohos.permission.MICROPHONE + * + * @param capturer reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_Start(OH_AudioCapturer* capturer); + +/* + * Request to pause the capturer stream. + * + * @since 10 + * @permission ohos.permission.MICROPHONE + * + * @param capturer reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_Pause(OH_AudioCapturer* capturer); + +/* + * Request to stop the capturer stream. + * + * @since 10 + * @permission ohos.permission.MICROPHONE + * + * @param capturer reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_Stop(OH_AudioCapturer* capturer); + +/* + * Request to flush the capturer stream. + * + * @since 10 + * + * @param capturer reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_Flush(OH_AudioCapturer* capturer); + +/* + * Query the current state of the capturer client. + * + * This function will return the capturer state without updating the state. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param state Pointer to a variable that will be set for the state value. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetCurrentState(OH_AudioCapturer* capturer, OH_AudioStream_State* state); + +/* + * Query the latency mode of the capturer client. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param latencyMode Pointer to a variable that will be set for the latency mode. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetLatencyMode(OH_AudioCapturer* capturer, + OH_AudioStream_LatencyMode* latencyMode); + +/* + * Query the stream id of the capturer client. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param stramId Pointer to a variable that will be set for the stream id. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetStreamId(OH_AudioCapturer* capturer, uint32_t* streamId); + +/* + * Query the sample rate value of the capturer client. + * + * This function will return the capturer sample rate value without updating the state. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param rate The state value to be updated + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetSamplingRate(OH_AudioCapturer* capturer, int32_t* rate); + +/* + * Query the channel count of the capturer client. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param channelCount Pointer to a variable that will be set for the channel count. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetChannelCount(OH_AudioCapturer* capturer, int32_t* channelCount); + +/* + * Query the sample format of the capturer client. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param sampleFormat Pointer to a variable that will be set for the sample format. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetSampleFormat(OH_AudioCapturer* capturer, + OH_AudioStream_SampleFormat* sampleFormat); + +/* + * Query the encoding type of the capturer client. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param encodingType Pointer to a variable that will be set for the encoding type. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetEncodingType(OH_AudioCapturer* capturer, + OH_AudioStream_EncodingType* encodingType); + +/* + * Query the capturer info of the capturer client. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param sourceType Pointer to a variable that will be set for the stream sourceType. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetCapturerInfo(OH_AudioCapturer* capturer, + OH_AudioStream_SourceType* sourceType); + +/* + * Query the frame size in callback, it is a fixed length of the buffer returned by each callback. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param frameSize Pointer to a variable that will be set for the frame size. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetFrameSizeInCallback(OH_AudioCapturer* capturer, int32_t* frameSize); + +/* + * Query the the time at which a particular frame was presented + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param clockId {@link #CLOCK_MONOTONIC} + * @param framePosition Pointer to a variable to receive the position + * @param timestamp Pointer to a variable to receive the timestamp + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetTimestamp(OH_AudioCapturer* capturer, + clockid_t clockId, int64_t* framePosition, int64_t* timestamp); + +/* + * Query the the number of frames that have been read since the stream was created. + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder_GenerateCapturer() + * @param frames Pointer to a variable that will be set for the frame count number. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioCapturer_GetFramesRead(OH_AudioCapturer* capturer, int64_t* frames); +#ifdef __cplusplus +} +#endif +#endif // NATIVE_AUDIOCAPTURER_H diff --git a/multimedia/audio_framework/audio_renderer/native_audiorenderer.h b/multimedia/audio_framework/audio_renderer/native_audiorenderer.h new file mode 100644 index 000000000..8b201d978 --- /dev/null +++ b/multimedia/audio_framework/audio_renderer/native_audiorenderer.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup OHAudio + * @{ + * + * @brief Provide the definition of the C interface for the audio module. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * + * @since 10 + * @version 1.0 + */ + +/** + * @file native_audiorenderer.h + * + * @brief Declare audio stream related interfaces for output type. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * @since 10 + * @version 1.0 + */ + +#ifndef NATIVE_AUDIORENDERER_H +#define NATIVE_AUDIORENDERER_H + +#include +#include "native_audiostream_base.h" +#ifdef __cplusplus +extern "C" { +#endif +/* + * Request to release the renderer stream. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_Release(OH_AudioRenderer* renderer); + +/* + * Request to start the renderer stream. + * + * @since 10 + * + * @param renderer reference created by OH_AudioStreamBuilder + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_Start(OH_AudioRenderer* renderer); + +/* + * Request to pause the renderer stream. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_Pause(OH_AudioRenderer* renderer); + +/* + * Request to stop renderer stream. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_Stop(OH_AudioRenderer* renderer); + +/* + * Request to flush the renderer stream. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_Flush(OH_AudioRenderer* renderer); + +/* + * Query the current state of the renderer client. + * + * This function will return the renderer state without updating the state. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param state Pointer to a variable that will be set for the state value. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetCurrentState(OH_AudioRenderer* renderer, + OH_AudioStream_State* state); + +/* + * Query the sample rate value of the renderer client + * + * This function will return the renderer sample rate value without updating the state. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param rate The state value to be updated + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetSamplingRate(OH_AudioRenderer* renderer, int32_t* rate); + +/* + * Query the stream id of the renderer client. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param stramId Pointer to a variable that will be set for the stream id. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetStreamId(OH_AudioRenderer* renderer, uint32_t* streamId); + +/* + * Query the channel count of the renderer client. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param channelCount Pointer to a variable that will be set for the channel count. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetChannelCount(OH_AudioRenderer* renderer, int32_t* channelCount); + +/* + * Query the sample format of the renderer client. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param sampleFormat Pointer to a variable that will be set for the sample format. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetSampleFormat(OH_AudioRenderer* renderer, + OH_AudioStream_SampleFormat* sampleFormat); + +/* + * Query the latency mode of the renderer client. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param latencyMode Pointer to a variable that will be set for the latency mode. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetLatencyMode(OH_AudioRenderer* renderer, + OH_AudioStream_LatencyMode* latencyMode); +/* + * Query the renderer info of the renderer client. + * + * The rendere info includes {@link OH_AudioStream_Usage} value. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param usage Pointer to a variable that will be set for the stream usage. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetRendererInfo(OH_AudioRenderer* renderer, + OH_AudioStream_Usage* usage); + +/* + * Query the encoding type of the renderer client. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param encodingType Pointer to a variable that will be set for the encoding type. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetEncodingType(OH_AudioRenderer* renderer, + OH_AudioStream_EncodingType* encodingType); + +/* + * Query the the number of frames that have been written since the stream was created. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param frames Pointer to a variable that will be set for the frame count number. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetFramesWritten(OH_AudioRenderer* renderer, int64_t* frames); + +/* + * Query the the time at which a particular frame was presented. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param clockId {@link #CLOCK_MONOTONIC} + * @param framePosition Pointer to a variable to receive the position + * @param timestamp Pointer to a variable to receive the timestamp + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetTimestamp(OH_AudioRenderer* renderer, + clockid_t clockId, int64_t* framePosition, int64_t* timestamp); + +/* + * Query the frame size in callback, it is a fixed length that the stream want to be filled for each callback. + * + * @since 10 + * + * @param renderer Reference created by OH_AudioStreamBuilder_GenerateRenderer() + * @param frameSize Pointer to a variable that will be set for the frame size. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioRenderer_GetFrameSizeInCallback(OH_AudioRenderer* renderer, int32_t* frameSize); +#ifdef __cplusplus +} +#endif +#endif // NATIVE_AUDIORENDERER_H diff --git a/multimedia/audio_framework/common/native_audiostream_base.h b/multimedia/audio_framework/common/native_audiostream_base.h new file mode 100644 index 000000000..9270d8437 --- /dev/null +++ b/multimedia/audio_framework/common/native_audiostream_base.h @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup OHAudio + * @{ + * + * @brief Provide the definition of the C interface for the audio module. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * + * @since 10 + * @version 1.0 + */ + +/** + * @file native_audiostream_base.h + * + * @brief Declare the underlying data structure. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * @since 10 + * @version 1.0 + */ + +#ifndef ST_NATIVE_AUDIOSTREAM_BASE_H +#define ST_NATIVE_AUDIOSTREAM_BASE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Define the result of the function execution. + * + * @since 10 + */ +typedef enum { + /** + * The call was successful. + * + * @since 10 + */ + AUDIOSTREAM_SUCCESS = 0, + + /** + * This means that the function was executed with an invalid input parameter. + * + * @since 10 + */ + AUDIOSTREAM_ERROR_INVALID_PARAM = 1, + + /** + * Execution status exception. + * + * @since 10 + */ + AUDIOSTREAM_ERROR_ILLEGAL_STATE = 2, + + /** + * An system error has occurred. + * + * @since 10 + */ + AUDIOSTREAM_ERROR_SYSTEM = 3 +} OH_AudioStream_Result; + +/** + * Define the audio stream type. + * + * @since 10 + */ +typedef enum { + /** + * The type for audio stream is renderer. + * + * @since 10 + */ + AUDIOSTREAM_TYPE_RENDERER = 1, + + /** + * The type for audio stream is capturer. + * + * @since 10 + */ + AUDIOSTREAM_TYPE_CAPTURER = 2 +} OH_AudioStream_Type; + +/** + * Define the audio stream sample format. + * + * @since 10 + */ +typedef enum { + /** + * Unsigned 8 format. + * + * @since 10 + */ + AUDIOSTREAM_SAMPLE_U8 = 0, + /** + * Signed 16 bit integer, little endian. + * + * @since 10 + */ + AUDIOSTREAM_SAMPLE_S16LE = 1, + /** + * Signed 24 bit integer, little endian. + * + * @since 10 + */ + AUDIOSTREAM_SAMPLE_S24LE = 2, + /** + * Signed 32 bit integer, little endian. + * + * @since 10 + */ + AUDIOSTREAM_SAMPLE_S32LE = 3, +} OH_AudioStream_SampleFormat; + +/** + * Define the audio encoding type. + * + * @since 10 + */ +typedef enum { + /** + * PCM encoding type. + * + * @since 10 + */ + AUDIOSTREAM_ENCODING_TYPE_RAW = 0, +} OH_AudioStream_EncodingType; + +/** + * Define the audio stream usage. + * Audio stream usage is used to describe what work scenario + * the current stream is used for. + * + * @since 10 + */ +typedef enum { + /** + * Unknown usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_UNKNOWN = 0, + /** + * Music usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_MUSIC = 1, + /** + * Voice communication usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_VOICE_COMMUNICATION = 2, + /** + * Voice assistant usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_VOICE_ASSISTANT = 3, + /** + * Alarm usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_ALARM = 4, + /** + * Voice message usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_VOICE_MESSAGE = 5, + /** + * Ringtone usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_RINGTONE = 6, + /** + * Notification usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_NOTIFICATION = 7, + /** + * Accessibility usage, such as screen reader. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_ACCESSIBILITY = 8, + /** + * Movie or video usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_MOVIE = 10, + /** + * Game sound effect usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_GAME = 11, + /** + * Audiobook usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_AUDIOBOOK = 12, + /** + * Navigation usage. + * + * @since 10 + */ + AUDIOSTREAM_USAGE_NAVIGATION = 13, +} OH_AudioStream_Usage; + +/** + * Define the audio latency mode. + * + * @since 10 + */ +typedef enum { + /** + * This is a normal audio scene. + * + * @since 10 + */ + AUDIOSTREAM_LATENCY_MODE_NORMAL = 0, + /** + * This is a low latency audio scene. + * + * @since 10 + */ + AUDIOSTREAM_LATENCY_MODE_FAST = 1 +} OH_AudioStream_LatencyMode; + +/** + * Define the audio event. + * + * @since 10 + */ +typedef enum { + /** + * The routing of the audio has changed. + * + * @since 10 + */ + AUDIOSTREAM_EVENT_ROUTING_CHANGED = 0 +} OH_AudioStream_Event; + +/** + * The audio stream states + * + * @since 10 + */ +typedef enum { + /** + * The invalid state. + * + * @since 10 + */ + AUDIOSTREAM_STATE_INVALID = -1, + /** + * Create new instance state. + * + * @since 10 + */ + AUDIOSTREAM_STATE_NEW = 0, + /** + * The prepared state. + * + * @since 10 + */ + AUDIOSTREAM_STATE_PREPARED = 1, + /** + * The stream is running. + * + * @since 10 + */ + AUDIOSTREAM_STATE_RUNNING = 2, + /** + * The stream is stopped. + * + * @since 10 + */ + AUDIOSTREAM_STATE_STOPPED = 3, + /** + * The stream is released. + * + * @since 10 + */ + AUDIOSTREAM_STATE_RELEASED = 4, + /** + * The stream is paused. + * + * @since 10 + */ + AUDIOSTREAM_STATE_PAUSED = 5, +} OH_AudioStream_State; + +/** + * Defines the audio interrupt type. + * + * @since 10 + */ +typedef enum { + /** + * Force type, system change audio state. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_FORCE = 0, + /** + * Share type, application change audio state. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_SHARE = 1 +} OH_AudioInterrupt_ForceType; + +/** + * Defines the audio interrupt hint type. + * + * @since 10 + */ +typedef enum { + /** + * None. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_HINT_NONE = 0, + /** + * Resume the stream. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_HINT_RESUME = 1, + /** + * Pause the stream. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_HINT_PAUSE = 2, + /** + * Stop the stream. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_HINT_STOP = 3, + /** + * Ducked the stream. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_HINT_DUCK = 4, + /** + * Unducked the stream. + * + * @since 10 + */ + AUDIOSTREAM_INTERRUPT_HINT_UNDUCK = 5 +} OH_AudioInterrupt_Hint; + +/** + * Defines the audio source type. + * + * @since 10 + */ +typedef enum { + /** + * Invalid type. + * + * @since 10 + */ + AUDIOSTREAM_SOURCE_TYPE_INVALID = -1, + /** + * Mic source type. + * + * @since 10 + */ + AUDIOSTREAM_SOURCE_TYPE_MIC = 0, + /** + * Voice recognition source type. + * + * @since 10 + */ + AUDIOSTREAM_SOURCE_TYPE_VOICE_RECOGNITION = 1, + /** + * Playback capture source type. + * + * @since 10 + */ + AUDIOSTREAM_SOURCE_TYPE_PLAYBACK_CAPTURE = 2, + /** + * Voice communication source type. + * + * @since 10 + */ + AUDIOSTREAM_SOURCE_TYPE_VOICE_COMMUNICATION = 7 +} OH_AudioStream_SourceType; + +/** + * Declaring the audio stream builder. + * The instance of builder is used for creating audio stream. + * + * @since 10 + */ +typedef struct OH_AudioStreamBuilderStruct OH_AudioStreamBuilder; + +/** + * Declaring the audio renderer stream. + * The instance of renderer stream is used for playing audio data. + * + * @since 10 + */ +typedef struct OH_AudioRendererStruct OH_AudioRenderer; + +/** + * Declaring the audio capturer stream. + * The instance of renderer stream is used for capturing audio data. + * + * @since 10 + */ +typedef struct OH_AudioCapturerStruct OH_AudioCapturer; + +/** + * Declaring the callback struct for renderer stream. + * + * @since 10 + */ +typedef struct OH_AudioRenderer_Callbacks_Struct { + /** + * This function pointer will point to the callback function that + * is used to write audio data + * + * @since 10 + */ + int32_t (*OH_AudioRenderer_OnWriteData)( + OH_AudioRenderer* renderer, + void* userData, + void* buffer, + int32_t lenth); + + /** + * This function pointer will point to the callback function that + * is used to handle audio renderer stream events. + * + * @since 10 + */ + int32_t (*OH_AudioRenderer_OnStreamEvent)( + OH_AudioRenderer* renderer, + void* userData, + OH_AudioStream_Event event); + + /** + * This function pointer will point to the callback function that + * is used to handle audio interrupt events. + * + * @since 10 + */ + int32_t (*OH_AudioRenderer_OnInterrptEvent)( + OH_AudioRenderer* renderer, + void* userData, + OH_AudioInterrupt_ForceType type, + OH_AudioInterrupt_Hint hint); + + /** + * This function pointer will point to the callback function that + * is used to handle audio error result. + * + * @since 10 + */ + int32_t (*OH_AudioRenderer_OnError)( + OH_AudioRenderer* renderer, + void* userData, + OH_AudioStream_Result error); +} OH_AudioRenderer_Callbacks; + +/** + * Declaring the callback struct for capturer stream. + * + * @since 10 + */ +typedef struct OH_AudioCapturer_Callbacks_Struct { + /** + * This function pointer will point to the callback function that + * is used to read audio data. + * + * @since 10 + */ + int32_t (*OH_AudioCapturer_OnReadData)( + OH_AudioCapturer* capturer, + void* userData, + void* buffer, + int32_t lenth); + + /** + * This function pointer will point to the callback function that + * is used to handle audio capturer stream events. + * + * @since 10 + */ + int32_t (*OH_AudioCapturer_OnStreamEvent)( + OH_AudioCapturer* capturer, + void* userData, + OH_AudioStream_Event event); + + /** + * This function pointer will point to the callback function that + * is used to handle audio interrupt events. + * + * @since 10 + */ + int32_t (*OH_AudioCapturer_OnInterrptEvent)( + OH_AudioCapturer* renderer, + void* userData, + OH_AudioInterrupt_ForceType type, + OH_AudioInterrupt_Hint hint); + + /** + * This function pointer will point to the callback function that + * is used to handle audio error result. + * + * @since 10 + */ + int32_t (*OH_AudioCapturer_OnError)( + OH_AudioCapturer* capturer, + void* userData, + OH_AudioStream_Result error); +} OH_AudioCapturer_Callbacks; +#ifdef __cplusplus +} +#endif + +#endif // ST_NATIVE_AUDIOSTREAM_BASE_H diff --git a/multimedia/audio_framework/common/native_audiostreambuilder.h b/multimedia/audio_framework/common/native_audiostreambuilder.h new file mode 100644 index 000000000..99d94288e --- /dev/null +++ b/multimedia/audio_framework/common/native_audiostreambuilder.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup OHAudio + * @{ + * + * @brief Provide the definition of the C interface for the audio module. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * + * @since 10 + * @version 1.0 + */ + +/** + * @file native_audiostreambuilder.h + * + * @brief Declare audio stream builder related interfaces. + * + * @syscap SystemCapability.Multimedia.Audio.Core + * @since 10 + * @version 1.0 + */ + +#ifndef NATIVE_AUDIOSTREAM_BUILDER_H +#define NATIVE_AUDIOSTREAM_BUILDER_H + +#include "native_audiostream_base.h" +#include "native_audiorenderer.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Create a stremBuilder can be used to open a renderer or capturer client. + * + * OH_AudioStreamBuilder_Destroy() must be called when you are done using the builder. + * + * @since 10 + * + * @param builder The builder reference to the created result. + * @param type The stream type to be created. {@link #AUDIOSTREAM_TYPE_RENDERER} or {@link #AUDIOSTREAM_TYPE_CAPTURER} + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_Create(OH_AudioStreamBuilder** builder, OH_AudioStream_Type type); + +/** + * Destroy a streamBulder. + * + * This function must be called when you are done using the builder. + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_Destroy(OH_AudioStreamBuilder* builder); + +/* + * Set the channel count of the capturer client + * + * @since 10 + * + * @param capturer Reference created by OH_AudioStreamBuilder + * @param channelCount Pointer to a variable that will be set for the channel count. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetSamplingRate(OH_AudioStreamBuilder* builder, int32_t rate); + +/* + * Set the channel count of the stream client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param channelCount The channel count. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetChannelCount(OH_AudioStreamBuilder* builder, int32_t channelCount); + +/* + * Set the sample format of the stream client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param format Sample data format. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetSampleFormat(OH_AudioStreamBuilder* builder, + OH_AudioStream_SampleFormat format); + +/* + * Set the encoding type of the stream client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param encodingType Encoding type for the stream client, {@link #AUDIOSTREAM_ENCODING_PCM} + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetEncodingType(OH_AudioStreamBuilder* builder, + OH_AudioStream_EncodingType encodingType); + +/* + * Set the latency mode of the stream client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param latencyMode Latency mode for the stream client. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetLatencyMode(OH_AudioStreamBuilder* builder, + OH_AudioStream_LatencyMode latencyMode); + +/* + * Set the renderer information of the stream client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param usage Set the stream usage for the renderer client. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetRendererInfo(OH_AudioStreamBuilder* builder, + OH_AudioStream_Usage usage); + +/* + * Set the capturer information of the stream client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param sourceType Set the source type for the capturer client. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetCapturerInfo(OH_AudioStreamBuilder* builder, + OH_AudioStream_SourceType sourceType); + +/* + * Set the callbacks for the renderer client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param callbacks Callbacks to the functions that will process renderer stream. + * @param userData Pointer to an application data structure that will be passed to the callback functions. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetRendererCallback(OH_AudioStreamBuilder* builder, + OH_AudioRenderer_Callbacks callbacks, void* userData); + +/* + * Set the callbacks for the capturer client + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param callbacks Callbacks to the functions that will process capturer stream. + * @param userData Pointer to an application data structure that will be passed to the callback functions. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_SetCapturerCallback(OH_AudioStreamBuilder* builder, + OH_AudioCapturer_Callbacks callbacks, void* userData); + +/* + * Create the audio renderer client. + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param audioRenderer Pointer to a viriable to receive the stream client. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_GenerateRenderer(OH_AudioStreamBuilder* builder, + OH_AudioRenderer** audioRenderer); +/* + * Create the audio capturer client. + * + * @since 10 + * + * @param builder Reference provided by OH_AudioStreamBuilder_Create() + * @param audioCapturer Pointer to a viriable to receive the stream client. + * @return {@link #AUDIOSTREAM_SUCCESS} or an undesired error. + */ +OH_AudioStream_Result OH_AudioStreamBuilder_GenerateCapturer(OH_AudioStreamBuilder* builder, + OH_AudioCapturer** audioCapturer); +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AUDIOSTREAM_BUILDER_H diff --git a/multimedia/audio_framework/ohaudio.ndk.json b/multimedia/audio_framework/ohaudio.ndk.json new file mode 100644 index 000000000..1062c40a8 --- /dev/null +++ b/multimedia/audio_framework/ohaudio.ndk.json @@ -0,0 +1,41 @@ +[ + { "name": "OH_AudioStreamBuilder_Create" }, + { "name": "OH_AudioStreamBuilder_Destroy" }, + { "name": "OH_AudioStreamBuilder_SetSamplingRate" }, + { "name": "OH_AudioStreamBuilder_SetChannelCount" }, + { "name": "OH_AudioStreamBuilder_SetSampleFormat" }, + { "name": "OH_AudioStreamBuilder_SetEncodingType" }, + { "name": "OH_AudioStreamBuilder_SetLatencyMode" }, + { "name": "OH_AudioStreamBuilder_SetRendererInfo" }, + { "name": "OH_AudioStreamBuilder_SetCapturerInfo" }, + { "name": "OH_AudioStreamBuilder_SetRendererCallback" }, + { "name": "OH_AudioStreamBuilder_SetCapturerCallback" }, + { "name": "OH_AudioStreamBuilder_GenerateRenderer" }, + { "name": "OH_AudioStreamBuilder_GenerateCapturer" }, + { "name": "OH_AudioRenderer_Release" }, + { "name": "OH_AudioRenderer_Start" }, + { "name": "OH_AudioRenderer_Pause" }, + { "name": "OH_AudioRenderer_Stop" }, + { "name": "OH_AudioRenderer_Flush" }, + { "name": "OH_AudioRenderer_GetCurrentState" }, + { "name": "OH_AudioRenderer_GetSamplingRate" }, + { "name": "OH_AudioRenderer_GetStreamId" }, + { "name": "OH_AudioRenderer_GetChannelCount" }, + { "name": "OH_AudioRenderer_GetSampleFormat" }, + { "name": "OH_AudioRenderer_GetLatencyMode" }, + { "name": "OH_AudioRenderer_GetRendererInfo" }, + { "name": "OH_AudioRenderer_GetEncodingType" }, + { "name": "OH_AudioCapturer_Release" }, + { "name": "OH_AudioCapturer_Start" }, + { "name": "OH_AudioCapturer_Pause" }, + { "name": "OH_AudioCapturer_Stop" }, + { "name": "OH_AudioCapturer_Flush" }, + { "name": "OH_AudioCapturer_GetCurrentState" }, + { "name": "OH_AudioCapturer_GetLatencyMode" }, + { "name": "OH_AudioCapturer_GetStreamId" }, + { "name": "OH_AudioCapturer_GetSamplingRate" }, + { "name": "OH_AudioCapturer_GetChannelCount" }, + { "name": "OH_AudioCapturer_GetSampleFormat" }, + { "name": "OH_AudioCapturer_GetEncodingType" }, + { "name": "OH_AudioCapturer_GetCapturerInfo" } +] \ No newline at end of file diff --git a/multimedia/av_codec/BUILD.gn b/multimedia/av_codec/BUILD.gn new file mode 100644 index 000000000..0f5d4c839 --- /dev/null +++ b/multimedia/av_codec/BUILD.gn @@ -0,0 +1,274 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//foundation/multimedia/av_codec/config.gni") + +group("capi_packages") { + deps = [] + if (av_codec_support_capi) { + deps += [ + "$av_codec_root_dir/interfaces/kits/c:native_media_adec", + "$av_codec_root_dir/interfaces/kits/c:native_media_aenc", + "$av_codec_root_dir/interfaces/kits/c:native_media_avdemuxer", + "$av_codec_root_dir/interfaces/kits/c:native_media_avmuxer", + "$av_codec_root_dir/interfaces/kits/c:native_media_avsource", + "$av_codec_root_dir/interfaces/kits/c:native_media_codecbase", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/interfaces/kits/c:native_media_vdec", + "$av_codec_root_dir/interfaces/kits/c:native_media_venc", + ] + } +} + +config("av_codec_capi_config") { + include_dirs = [ + "$av_codec_root_dir/frameworks/native/capi/common", + "$av_codec_root_dir/interfaces/inner_api/native", + "$av_codec_root_dir/interfaces/kits/c", + "$av_codec_root_dir/services/dfx/include", + "$av_codec_root_dir/services/utils/include", + "//foundation/graphic/graphic_2d/frameworks/surface/include", + ] + + cflags = [ + "-fno-exceptions", + "-Wall", + "-fno-common", + "-fstack-protector-all", + "-Wshadow", + "-FPIC", + "-FS", + "-O2", + "-D_FORTIFY_SOURCE=2", + "-Wformat=2", + "-Wdate-time", + ] + + cflags_cc = [ + "-std=c++17", + "-fno-rtti", + ] +} + +ohos_shared_library("native_media_core") { + install_enable = true + + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + blocklist = "../../../cfi_blocklist.txt" + } + + configs = [ ":av_codec_capi_config" ] + + sources = [ + "$av_codec_root_dir/frameworks/native/capi/common/native_avformat.cpp", + "$av_codec_root_dir/frameworks/native/capi/common/native_avmemory.cpp", + ] + + if (av_codec_support_codeclist) { + sources += [ "$av_codec_root_dir/frameworks/native/capi/common/native_avcapability.cpp" ] + } + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/services/utils:av_codec_format", + ] + + external_deps = [ + "graphic_2d:surface", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_avmuxer") { + install_enable = true + sources = [ + "$av_codec_root_dir/frameworks/native/capi/avcodec/native_avcodec_base.cpp", + "$av_codec_root_dir/frameworks/native/capi/avmuxer/native_avmuxer.cpp", + "$av_codec_root_dir/frameworks/native/capi/common/native_avformat.cpp", + "$av_codec_root_dir/frameworks/native/capi/common/native_avmemory.cpp", + ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/services/utils:av_codec_format", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_avdemuxer") { + install_enable = true + sources = [ + "$av_codec_root_dir/frameworks/native/capi/avdemuxer/native_avdemuxer.cpp", + ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/services/utils:av_codec_format", + ] + + external_deps = [ + "c_utils:utils", + "graphic_2d:surface", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_avsource") { + install_enable = true + sources = [ + "$av_codec_root_dir/frameworks/native/capi/avsource/native_avsource.cpp", + ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/services/utils:av_codec_format", + ] + + external_deps = [ + "c_utils:utils", + "graphic_2d:surface", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_codecbase") { + install_enable = true + sources = [ + "$av_codec_root_dir/frameworks/native/capi/avcodec/native_avcodec_base.cpp", + ] + + public_configs = [ ":av_codec_capi_config" ] + + external_deps = [ "hilog:libhilog" ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_adec") { + install_enable = true + sources = [ "$av_codec_root_dir/frameworks/native/capi/avcodec/native_audio_decoder.cpp" ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/interfaces/kits/c:native_media_codecbase", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/services/dfx:av_codec_service_dfx", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_aenc") { + install_enable = true + sources = [ "$av_codec_root_dir/frameworks/native/capi/avcodec/native_audio_encoder.cpp" ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/interfaces/kits/c:native_media_codecbase", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/services/dfx:av_codec_service_dfx", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_vdec") { + install_enable = true + sources = [ "$av_codec_root_dir/frameworks/native/capi/avcodec/native_video_decoder.cpp" ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/interfaces/kits/c:native_media_codecbase", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/services/dfx:av_codec_service_dfx", + ] + + external_deps = [ + "c_utils:utils", + "graphic_2d:surface", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} + +ohos_shared_library("native_media_venc") { + install_enable = true + sources = [ "$av_codec_root_dir/frameworks/native/capi/avcodec/native_video_encoder.cpp" ] + + public_configs = [ ":av_codec_capi_config" ] + + deps = [ + "$av_codec_root_dir/interfaces/inner_api/native:av_codec_client", + "$av_codec_root_dir/interfaces/kits/c:native_media_codecbase", + "$av_codec_root_dir/interfaces/kits/c:native_media_core", + "$av_codec_root_dir/services/dfx:av_codec_service_dfx", + ] + + external_deps = [ + "c_utils:utils", + "graphic_2d:surface", + "hilog:libhilog", + ] + output_extension = "so" + subsystem_name = "multimedia" + part_name = "av_codec" +} diff --git a/multimedia/av_codec/audio_decoder/BUILD.gn b/multimedia/av_codec/audio_decoder/BUILD.gn new file mode 100644 index 000000000..94b0a7b9f --- /dev/null +++ b/multimedia/av_codec/audio_decoder/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_adec_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = + [ "$av_codec_root_dir/interfaces/kits/c/native_avcodec_audiodecoder.h" ] +} + +ohos_ndk_library("libnative_media_adec") { + ndk_description_file = "./libnative_media_adec.ndk.json" + min_compact_version = "1" + output_name = "native_media_adec" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.AudioDecoder" + system_capability_headers = + [ "multimedia/player_framework/native_avcodec_audiodecoder.h" ] +} diff --git a/multimedia/av_codec/audio_decoder/libnative_media_adec.ndk.json b/multimedia/av_codec/audio_decoder/libnative_media_adec.ndk.json new file mode 100644 index 000000000..1b4472c05 --- /dev/null +++ b/multimedia/av_codec/audio_decoder/libnative_media_adec.ndk.json @@ -0,0 +1,17 @@ +[ + { "name": "OH_AudioDecoder_CreateByMime" }, + { "name": "OH_AudioDecoder_CreateByName" }, + { "name": "OH_AudioDecoder_Destroy" }, + { "name": "OH_AudioDecoder_SetCallback" }, + { "name": "OH_AudioDecoder_Configure" }, + { "name": "OH_AudioDecoder_Prepare" }, + { "name": "OH_AudioDecoder_Start" }, + { "name": "OH_AudioDecoder_Stop" }, + { "name": "OH_AudioDecoder_Flush" }, + { "name": "OH_AudioDecoder_Reset" }, + { "name": "OH_AudioDecoder_GetOutputDescription" }, + { "name": "OH_AudioDecoder_SetParameter" }, + { "name": "OH_AudioDecoder_PushInputData" }, + { "name": "OH_AudioDecoder_FreeOutputData" }, + { "name": "OH_AudioDecoder_IsValid" } +] diff --git a/multimedia/av_codec/audio_encoder/BUILD.gn b/multimedia/av_codec/audio_encoder/BUILD.gn new file mode 100644 index 000000000..5700e2e6a --- /dev/null +++ b/multimedia/av_codec/audio_encoder/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_aenc_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = + [ "$av_codec_root_dir/interfaces/kits/c/native_avcodec_audioencoder.h" ] +} + +ohos_ndk_library("libnative_media_aenc") { + ndk_description_file = "./libnative_media_aenc.ndk.json" + min_compact_version = "1" + output_name = "native_media_aenc" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.AudioEncoder" + system_capability_headers = + [ "multimedia/player_framework/native_avcodec_audioencoder.h" ] +} diff --git a/multimedia/av_codec/audio_encoder/libnative_media_aenc.ndk.json b/multimedia/av_codec/audio_encoder/libnative_media_aenc.ndk.json new file mode 100644 index 000000000..830a103a7 --- /dev/null +++ b/multimedia/av_codec/audio_encoder/libnative_media_aenc.ndk.json @@ -0,0 +1,17 @@ +[ + { "name": "OH_AudioEncoder_CreateByMime" }, + { "name": "OH_AudioEncoder_CreateByName" }, + { "name": "OH_AudioEncoder_Destroy" }, + { "name": "OH_AudioEncoder_SetCallback" }, + { "name": "OH_AudioEncoder_Configure" }, + { "name": "OH_AudioEncoder_Prepare" }, + { "name": "OH_AudioEncoder_Start" }, + { "name": "OH_AudioEncoder_Stop" }, + { "name": "OH_AudioEncoder_Flush" }, + { "name": "OH_AudioEncoder_Reset" }, + { "name": "OH_AudioEncoder_GetOutputDescription" }, + { "name": "OH_AudioEncoder_SetParameter" }, + { "name": "OH_AudioEncoder_PushInputData" }, + { "name": "OH_AudioEncoder_FreeOutputData" }, + { "name": "OH_AudioEncoder_IsValid" } +] diff --git a/multimedia/av_codec/avcodec_audio_channel_layout.h b/multimedia/av_codec/avcodec_audio_channel_layout.h new file mode 100644 index 000000000..364bd6a12 --- /dev/null +++ b/multimedia/av_codec/avcodec_audio_channel_layout.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef AVCODEC_AUDIO_CHANNEL_LAYOUT_H +#define AVCODEC_AUDIO_CHANNEL_LAYOUT_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Audio Channel Set + * A 64-bit integer with bits set for each channel. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +enum AudioChannelSet : uint64_t { + FRONT_LEFT = 1ULL << 0U, + FRONT_RIGHT = 1ULL << 1U, + FRONT_CENTER = 1ULL << 2U, + LOW_FREQUENCY = 1ULL << 3U, + BACK_LEFT = 1ULL << 4U, + BACK_RIGHT = 1ULL << 5U, + FRONT_LEFT_OF_CENTER = 1ULL << 6U, + FRONT_RIGHT_OF_CENTER = 1ULL << 7U, + BACK_CENTER = 1ULL << 8U, + SIDE_LEFT = 1ULL << 9U, + SIDE_RIGHT = 1ULL << 10U, + TOP_CENTER = 1ULL << 11U, + TOP_FRONT_LEFT = 1ULL << 12U, + TOP_FRONT_CENTER = 1ULL << 13U, + TOP_FRONT_RIGHT = 1ULL << 14U, + TOP_BACK_LEFT = 1ULL << 15U, + TOP_BACK_CENTER = 1ULL << 16U, + TOP_BACK_RIGHT = 1ULL << 17U, + STEREO_LEFT = 1ULL << 29U, + STEREO_RIGHT = 1ULL << 30U, + WIDE_LEFT = 1ULL << 31U, + WIDE_RIGHT = 1ULL << 32U, + SURROUND_DIRECT_LEFT = 1ULL << 33U, + SURROUND_DIRECT_RIGHT = 1ULL << 34U, + LOW_FREQUENCY_2 = 1ULL << 35U, + TOP_SIDE_LEFT = 1ULL << 36U, + TOP_SIDE_RIGHT = 1ULL << 37U, + BOTTOM_FRONT_CENTER = 1ULL << 38U, + BOTTOM_FRONT_LEFT = 1ULL << 39U, + BOTTOM_FRONT_RIGHT = 1ULL << 40U, + + // Ambisonics ACN formats + // 0th and first order ambisonics ACN + AMBISONICS_ACN0 = 1ULL << 41U, /** 0th ambisonics channel number 0. */ + AMBISONICS_ACN1 = 1ULL << 42U, /** first-order ambisonics channel number 1. */ + AMBISONICS_ACN2 = 1ULL << 43U, /** first-order ambisonics channel number 2. */ + AMBISONICS_ACN3 = 1ULL << 44U, /** first-order ambisonics channel number 3. */ + AMBISONICS_W = AMBISONICS_ACN0, /** same as 0th ambisonics channel number 0. */ + AMBISONICS_Y = AMBISONICS_ACN1, /** same as first-order ambisonics channel number 1. */ + AMBISONICS_Z = AMBISONICS_ACN2, /** same as first-order ambisonics channel number 2. */ + AMBISONICS_X = AMBISONICS_ACN3, /** same as first-order ambisonics channel number 3. */ + + // second order ambisonics ACN + AMBISONICS_ACN4 = 1ULL << 45U, /** second-order ambisonics channel number 4. */ + AMBISONICS_ACN5 = 1ULL << 46U, /** second-order ambisonics channel number 5. */ + AMBISONICS_ACN6 = 1ULL << 47U, /** second-order ambisonics channel number 6. */ + AMBISONICS_ACN7 = 1ULL << 48U, /** second-order ambisonics channel number 7. */ + AMBISONICS_ACN8 = 1ULL << 49U, /** second-order ambisonics channel number 8. */ + + // third order ambisonics ACN + AMBISONICS_ACN9 = 1ULL << 50U, /** third-order ambisonics channel number 9. */ + AMBISONICS_ACN10 = 1ULL << 51U, /** third-order ambisonics channel number 10. */ + AMBISONICS_ACN11 = 1ULL << 52U, /** third-order ambisonics channel number 11. */ + AMBISONICS_ACN12 = 1ULL << 53U, /** third-order ambisonics channel number 12. */ + AMBISONICS_ACN13 = 1ULL << 54U, /** third-order ambisonics channel number 13. */ + AMBISONICS_ACN14 = 1ULL << 55U, /** third-order ambisonics channel number 14. */ + AMBISONICS_ACN15 = 1ULL << 56U, /** third-order ambisonics channel number 15. */ +}; + +/** + * @brief Audio AudioChannel Layout + * Indicates that the channel order in which the user requests decoder output + * is the native codec channel order. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +enum AudioChannelLayout : uint64_t { + UNKNOWN_CHANNEL_LAYOUT = 0, + MONO = (AudioChannelSet::FRONT_CENTER), + STEREO = (AudioChannelSet::FRONT_LEFT | AudioChannelSet::FRONT_RIGHT), + CH_2POINT1 = (STEREO | AudioChannelSet::LOW_FREQUENCY), + CH_2_1 = (STEREO | AudioChannelSet::BACK_CENTER), + SURROUND = (STEREO | AudioChannelSet::FRONT_CENTER), + CH_3POINT1 = (SURROUND | AudioChannelSet::LOW_FREQUENCY), + CH_4POINT0 = (SURROUND | AudioChannelSet::BACK_CENTER), + CH_4POINT1 = (CH_4POINT0 | AudioChannelSet::LOW_FREQUENCY), + CH_2_2 = (STEREO | AudioChannelSet::SIDE_LEFT | AudioChannelSet::SIDE_RIGHT), + QUAD = (STEREO | AudioChannelSet::BACK_LEFT | AudioChannelSet::BACK_RIGHT), + CH_5POINT0 = (SURROUND | AudioChannelSet::SIDE_LEFT | AudioChannelSet::SIDE_RIGHT), + CH_5POINT1 = (CH_5POINT0 | AudioChannelSet::LOW_FREQUENCY), + CH_5POINT0_BACK = (SURROUND | AudioChannelSet::BACK_LEFT | AudioChannelSet::BACK_RIGHT), + CH_5POINT1_BACK = (CH_5POINT0_BACK | AudioChannelSet::LOW_FREQUENCY), + CH_6POINT0 = (CH_5POINT0 | AudioChannelSet::BACK_CENTER), + CH_6POINT0_FRONT = (CH_2_2 | AudioChannelSet::FRONT_LEFT_OF_CENTER | AudioChannelSet::FRONT_RIGHT_OF_CENTER), + HEXAGONAL = (CH_5POINT0_BACK | AudioChannelSet::BACK_CENTER), + CH_6POINT1 = (CH_5POINT1 | AudioChannelSet::BACK_CENTER), + CH_6POINT1_BACK = (CH_5POINT1_BACK | AudioChannelSet::BACK_CENTER), + CH_6POINT1_FRONT = (CH_6POINT0_FRONT | AudioChannelSet::LOW_FREQUENCY), + CH_7POINT0 = (CH_5POINT0 | AudioChannelSet::BACK_LEFT | AudioChannelSet::BACK_RIGHT), + CH_7POINT0_FRONT = (CH_5POINT0 | AudioChannelSet::FRONT_LEFT_OF_CENTER | AudioChannelSet::FRONT_RIGHT_OF_CENTER), + CH_7POINT1 = (CH_5POINT1 | AudioChannelSet::BACK_LEFT | AudioChannelSet::BACK_RIGHT), + CH_7POINT1_WIDE = (CH_5POINT1 | AudioChannelSet::FRONT_LEFT_OF_CENTER | AudioChannelSet::FRONT_RIGHT_OF_CENTER), + CH_7POINT1_WIDE_BACK = + (CH_5POINT1_BACK | AudioChannelSet::FRONT_LEFT_OF_CENTER | AudioChannelSet::FRONT_RIGHT_OF_CENTER), + CH_3POINT1POINT2 = (CH_3POINT1 | AudioChannelSet::TOP_FRONT_LEFT | AudioChannelSet::TOP_FRONT_RIGHT), + CH_5POINT1POINT2 = (CH_5POINT1 | AudioChannelSet::TOP_SIDE_LEFT | AudioChannelSet::TOP_SIDE_RIGHT), + CH_5POINT1POINT4 = (CH_5POINT1 | AudioChannelSet::TOP_FRONT_LEFT | AudioChannelSet::TOP_FRONT_RIGHT | + AudioChannelSet::TOP_BACK_LEFT | AudioChannelSet::TOP_BACK_RIGHT), + CH_7POINT1POINT2 = (CH_7POINT1 | AudioChannelSet::TOP_SIDE_LEFT | AudioChannelSet::TOP_SIDE_RIGHT), + CH_7POINT1POINT4 = (CH_7POINT1 | AudioChannelSet::TOP_FRONT_LEFT | AudioChannelSet::TOP_FRONT_RIGHT | + AudioChannelSet::TOP_BACK_LEFT | AudioChannelSet::TOP_BACK_RIGHT), + CH_9POINT1POINT4 = (CH_7POINT1POINT4 | AudioChannelSet::WIDE_LEFT | AudioChannelSet::WIDE_RIGHT), + CH_9POINT1POINT6 = (CH_9POINT1POINT4 | AudioChannelSet::TOP_SIDE_LEFT | AudioChannelSet::TOP_SIDE_RIGHT), + CH_10POINT2 = (AudioChannelSet::FRONT_LEFT | AudioChannelSet::FRONT_RIGHT | AudioChannelSet::FRONT_CENTER | + AudioChannelSet::TOP_FRONT_LEFT | AudioChannelSet::TOP_FRONT_RIGHT | AudioChannelSet::BACK_LEFT | + AudioChannelSet::BACK_RIGHT | AudioChannelSet::BACK_CENTER | AudioChannelSet::SIDE_LEFT | + AudioChannelSet::SIDE_RIGHT | AudioChannelSet::WIDE_LEFT | AudioChannelSet::WIDE_RIGHT), + CH_22POINT2 = (CH_7POINT1POINT4 | AudioChannelSet::FRONT_LEFT_OF_CENTER | AudioChannelSet::FRONT_RIGHT_OF_CENTER | + AudioChannelSet::BACK_CENTER | AudioChannelSet::TOP_CENTER | AudioChannelSet::TOP_FRONT_CENTER | + AudioChannelSet::TOP_BACK_CENTER | AudioChannelSet::TOP_SIDE_LEFT | AudioChannelSet::TOP_SIDE_RIGHT | + AudioChannelSet::BOTTOM_FRONT_LEFT | AudioChannelSet::BOTTOM_FRONT_RIGHT | + AudioChannelSet::BOTTOM_FRONT_CENTER | AudioChannelSet::LOW_FREQUENCY_2), + OCTAGONAL = (CH_5POINT0 | AudioChannelSet::BACK_LEFT | AudioChannelSet::BACK_CENTER | AudioChannelSet::BACK_RIGHT), + HEXADECAGONAL = + (OCTAGONAL | AudioChannelSet::WIDE_LEFT | AudioChannelSet::WIDE_RIGHT | AudioChannelSet::TOP_BACK_LEFT | + AudioChannelSet::TOP_BACK_RIGHT | AudioChannelSet::TOP_BACK_CENTER | AudioChannelSet::TOP_FRONT_CENTER | + AudioChannelSet::TOP_FRONT_LEFT | AudioChannelSet::TOP_FRONT_RIGHT), + STEREO_DOWNMIX = (AudioChannelSet::STEREO_LEFT | AudioChannelSet::STEREO_RIGHT), + + HOA_FIRST = AudioChannelSet::AMBISONICS_ACN0 | AudioChannelSet::AMBISONICS_ACN1 | AudioChannelSet::AMBISONICS_ACN2 | + AudioChannelSet::AMBISONICS_ACN3, + HOA_SECOND = HOA_FIRST | AudioChannelSet::AMBISONICS_ACN4 | AudioChannelSet::AMBISONICS_ACN5 | + AudioChannelSet::AMBISONICS_ACN6 | AudioChannelSet::AMBISONICS_ACN7 | AudioChannelSet::AMBISONICS_ACN8, + HOA_THIRD = HOA_SECOND | AudioChannelSet::AMBISONICS_ACN9 | AudioChannelSet::AMBISONICS_ACN10 | + AudioChannelSet::AMBISONICS_ACN11 | AudioChannelSet::AMBISONICS_ACN12 | + AudioChannelSet::AMBISONICS_ACN13 | AudioChannelSet::AMBISONICS_ACN14 | + AudioChannelSet::AMBISONICS_ACN15, +}; +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/multimedia/av_codec/avdemuxer/BUILD.gn b/multimedia/av_codec/avdemuxer/BUILD.gn new file mode 100644 index 000000000..2106cb10a --- /dev/null +++ b/multimedia/av_codec/avdemuxer/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_avdemuxer_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ "$av_codec_root_dir/interfaces/kits/c/native_avdemuxer.h" ] +} + +ohos_ndk_library("libnative_media_avdemuxer") { + ndk_description_file = "./libnative_media_avdemuxer.ndk.json" + min_compact_version = "1" + output_name = "native_media_avdemuxer" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.Spliter" + system_capability_headers = + [ "multimedia/player_framework/native_avdemuxer.h" ] +} diff --git a/multimedia/av_codec/avdemuxer/libnative_media_avdemuxer.ndk.json b/multimedia/av_codec/avdemuxer/libnative_media_avdemuxer.ndk.json new file mode 100644 index 000000000..bf9ca16b8 --- /dev/null +++ b/multimedia/av_codec/avdemuxer/libnative_media_avdemuxer.ndk.json @@ -0,0 +1,8 @@ +[ + { "name": "OH_AVDemuxer_CreateWithSource" }, + { "name": "OH_AVDemuxer_Destroy" }, + { "name": "OH_AVDemuxer_SelectTrackByID" }, + { "name": "OH_AVDemuxer_UnselectTrackByID" }, + { "name": "OH_AVDemuxer_ReadSample" }, + { "name": "OH_AVDemuxer_SeekToTime" } +] diff --git a/multimedia/av_codec/avmuxer/BUILD.gn b/multimedia/av_codec/avmuxer/BUILD.gn new file mode 100644 index 000000000..e70f98cf2 --- /dev/null +++ b/multimedia/av_codec/avmuxer/BUILD.gn @@ -0,0 +1,30 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_avmuxer_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ "$av_codec_root_dir/interfaces/kits/c/native_avmuxer.h" ] +} + +ohos_ndk_library("libnative_media_avmuxer") { + ndk_description_file = "./libnative_media_avmuxer.ndk.json" + min_compact_version = "1" + output_name = "native_media_avmuxer" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.Muxer" + system_capability_headers = [ "multimedia/player_framework/native_avmuxer.h" ] +} diff --git a/multimedia/av_codec/avmuxer/libnative_media_avmuxer.ndk.json b/multimedia/av_codec/avmuxer/libnative_media_avmuxer.ndk.json new file mode 100644 index 000000000..b831c325d --- /dev/null +++ b/multimedia/av_codec/avmuxer/libnative_media_avmuxer.ndk.json @@ -0,0 +1,9 @@ +[ + { "name": "OH_AVMuxer_Create" }, + { "name": "OH_AVMuxer_SetRotation" }, + { "name": "OH_AVMuxer_AddTrack" }, + { "name": "OH_AVMuxer_Start" }, + { "name": "OH_AVMuxer_WriteSample" }, + { "name": "OH_AVMuxer_Stop" }, + { "name": "OH_AVMuxer_Destroy" } +] diff --git a/multimedia/av_codec/avsource/BUILD.gn b/multimedia/av_codec/avsource/BUILD.gn new file mode 100644 index 000000000..651ade03e --- /dev/null +++ b/multimedia/av_codec/avsource/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_avsource_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ "$av_codec_root_dir/interfaces/kits/c/native_avsource.h" ] +} + +ohos_ndk_library("libnative_media_avsource") { + ndk_description_file = "./libnative_media_avsource.ndk.json" + min_compact_version = "1" + output_name = "native_media_avsource" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.Spliter" + system_capability_headers = + [ "multimedia/player_framework/native_avsource.h" ] +} diff --git a/multimedia/av_codec/avsource/libnative_media_avsource.ndk.json b/multimedia/av_codec/avsource/libnative_media_avsource.ndk.json new file mode 100644 index 000000000..3232f28e2 --- /dev/null +++ b/multimedia/av_codec/avsource/libnative_media_avsource.ndk.json @@ -0,0 +1,7 @@ +[ + { "name": "OH_AVSource_CreateWithURI" }, + { "name": "OH_AVSource_CreateWithFD" }, + { "name": "OH_AVSource_Destroy" }, + { "name": "OH_AVSource_GetSourceFormat" }, + { "name": "OH_AVSource_GetTrackFormat" } +] diff --git a/multimedia/av_codec/codec_base/BUILD.gn b/multimedia/av_codec/codec_base/BUILD.gn new file mode 100644 index 000000000..affea0acc --- /dev/null +++ b/multimedia/av_codec/codec_base/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_codecbase_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ + "$av_codec_root_dir/interfaces/kits/c/avcodec_audio_channel_layout.h", + "$av_codec_root_dir/interfaces/kits/c/native_avcapability.h", + "$av_codec_root_dir/interfaces/kits/c/native_avcodec_base.h", + ] +} + +ohos_ndk_library("libnative_media_codecbase") { + ndk_description_file = "./libnative_media_codecbase.ndk.json" + min_compact_version = "1" + output_name = "native_media_codecbase" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.CodecBase" + system_capability_headers = [ + "multimedia/player_framework/native_avcodec_base.h", + "multimedia/player_framework/native_avcapability.h", + "multimedia/player_framework/avcodec_audio_channel_layout.h", + ] +} diff --git a/multimedia/av_codec/codec_base/libnative_media_codecbase.ndk.json b/multimedia/av_codec/codec_base/libnative_media_codecbase.ndk.json new file mode 100644 index 000000000..3e19fb31d --- /dev/null +++ b/multimedia/av_codec/codec_base/libnative_media_codecbase.ndk.json @@ -0,0 +1,83 @@ +[ + { "name": "OH_AVCODEC_MIMETYPE_VIDEO_AVC" }, + { "name": "OH_AVCODEC_MIMETYPE_AUDIO_AAC" }, + { "name": "OH_AVCODEC_MIMETYPE_VIDEO_MPEG4" }, + { "name": "OH_AVCODEC_MIMETYPE_VIDEO_HEVC" }, + { "name": "OH_AVCODEC_MIMETYPE_AUDIO_MPEG" }, + { "name": "OH_AVCODEC_MIMETYPE_IMAGE_JPG" }, + { "name": "OH_AVCODEC_MIMETYPE_IMAGE_PNG" }, + { "name": "OH_AVCODEC_MIMETYPE_IMAGE_BMP" }, + { "name": "OH_AVCODEC_MIMETYPE_AUDIO_FLAC" }, + { "name": "OH_AVCODEC_MIMETYPE_AUDIO_VORBIS" }, + { "name": "OH_ED_KEY_TIME_STAMP" }, + { "name": "OH_ED_KEY_EOS" }, + { "name": "OH_MD_KEY_TRACK_TYPE" }, + { "name": "OH_MD_KEY_CODEC_MIME" }, + { "name": "OH_MD_KEY_DURATION" }, + { "name": "OH_MD_KEY_BITRATE" }, + { "name": "OH_MD_KEY_MAX_INPUT_SIZE" }, + { "name": "OH_MD_KEY_WIDTH" }, + { "name": "OH_MD_KEY_HEIGHT" }, + { "name": "OH_MD_KEY_PIXEL_FORMAT" }, + { "name": "OH_MD_KEY_RANGE_FLAG" }, + { "name": "OH_MD_KEY_COLOR_PRIMARIES" }, + { "name": "OH_MD_KEY_TRANSFER_CHARACTERISTICS" }, + { "name": "OH_MD_KEY_MATRIX_COEFFICIENTS" }, + { "name": "OH_MD_KEY_AUDIO_SAMPLE_FORMAT" }, + { "name": "OH_MD_KEY_FRAME_RATE" }, + { "name": "OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE" }, + { "name": "OH_MD_KEY_PROFILE" }, + { "name": "OH_MD_KEY_AUD_CHANNEL_COUNT" }, + { "name": "OH_MD_KEY_AUD_SAMPLE_RATE" }, + { "name": "OH_MD_KEY_I_FRAME_INTERVAL" }, + { "name": "OH_MD_KEY_ROTATION" }, + { "name": "OH_MD_KEY_CODEC_CONFIG" }, + { "name": "OH_MD_KEY_REQUEST_I_FRAME" }, + { "name": "OH_MD_KEY_QUALITY" }, + { "name": "OH_MD_KEY_CHANNEL_LAYOUT" }, + { "name": "OH_MD_KEY_BITS_PER_CODED_SAMPLE" }, + { "name": "OH_MD_KEY_AAC_IS_ADTS" }, + { "name": "OH_MD_KEY_SBR" }, + { "name": "OH_MD_KEY_COMPLIANCE_LEVEL" }, + { "name": "OH_MD_KEY_IDENTIFICATION_HEADER" }, + { "name": "OH_MD_KEY_SETUP_HEADER" }, + { "name": "OH_MD_KEY_SCALING_MODE" }, + { "name": "OH_MD_MAX_INPUT_BUFFER_COUNT" }, + { "name": "OH_MD_MAX_OUTPUT_BUFFER_COUNT" }, + { "name": "OH_MD_KEY_TITLE" }, + { "name": "OH_MD_KEY_ARTIST" }, + { "name": "OH_MD_KEY_ALBUM" }, + { "name": "OH_MD_KEY_ALBUM_ARTIST" }, + { "name": "OH_MD_KEY_DATE" }, + { "name": "OH_MD_KEY_COMMENT" }, + { "name": "OH_MD_KEY_GENRE" }, + { "name": "OH_MD_KEY_COPYRIGHT" }, + { "name": "OH_MD_KEY_LANGUAGE" }, + { "name": "OH_MD_KEY_DESCRIPTION" }, + { "name": "OH_MD_KEY_LYRICS" }, + { "name": "OH_MD_KEY_TRACK_COUNT" }, + { "name": "OH_AVCapability_IsHardware" }, + { "name": "OH_AVCapability_GetName" }, + { "name": "OH_AVCapability_GetMaxSupportedInstances" }, + { "name": "OH_AVCapability_GetEncoderBitrateRange" }, + { "name": "OH_AVCapability_IsEncoderBitrateModeSupported" }, + { "name": "OH_AVCapability_GetEncoderQualityRange" }, + { "name": "OH_AVCapability_GetEncoderComplexityRange" }, + { "name": "OH_AVCapability_GetAudioSupportedSampleRates" }, + { "name": "OH_AVCapability_GetAudioChannelCountRange" }, + { "name": "OH_AVCapability_GetVideoWidthAlignment" }, + { "name": "OH_AVCapability_GetVideoHeightAlignment" }, + { "name": "OH_AVCapability_GetVideoWidthRangeForHeight" }, + { "name": "OH_AVCapability_GetVideoHeightRangeForWidth" }, + { "name": "OH_AVCapability_GetVideoWidthRange" }, + { "name": "OH_AVCapability_GetVideoHeightRange" }, + { "name": "OH_AVCapability_IsVideoSizeSupported" }, + { "name": "OH_AVCapability_GetVideoFrameRateRange" }, + { "name": "OH_AVCapability_GetVideoFrameRateRangeForSize" }, + { "name": "OH_AVCapability_AreVideoSizeAndFrameRateSupported" }, + { "name": "OH_AVCapability_GetVideoSupportedPixelFormats" }, + { "name": "OH_AVCapability_GetSupportedProfiles" }, + { "name": "OH_AVCapability_GetSupportedLevelsForProfile" }, + { "name": "OH_AVCapability_AreProfileAndLevelSupported" } +] + diff --git a/multimedia/av_codec/core/BUILD.gn b/multimedia/av_codec/core/BUILD.gn new file mode 100644 index 000000000..80cbc267a --- /dev/null +++ b/multimedia/av_codec/core/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_core_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ + "$av_codec_root_dir/interfaces/kits/c/native_averrors.h", + "$av_codec_root_dir/interfaces/kits/c/native_avformat.h", + "$av_codec_root_dir/interfaces/kits/c/native_avmemory.h", + ] +} + +ohos_ndk_library("libnative_media_core") { + ndk_description_file = "./libnative_media_core.ndk.json" + min_compact_version = "1" + output_name = "native_media_core" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.Core" + system_capability_headers = [ + "multimedia/player_framework/native_averrors.h", + "multimedia/player_framework/native_avformat.h", + "multimedia/player_framework/native_avmemory.h", + ] +} diff --git a/multimedia/av_codec/core/libnative_media_core.ndk.json b/multimedia/av_codec/core/libnative_media_core.ndk.json new file mode 100644 index 000000000..f7ceabdb5 --- /dev/null +++ b/multimedia/av_codec/core/libnative_media_core.ndk.json @@ -0,0 +1,26 @@ +[ + { "name": "OH_AVFormat_Create" }, + { "name": "OH_AVFormat_CreateAudioFormat" }, + { "name": "OH_AVFormat_CreateVideoFormat" }, + { "name": "OH_AVFormat_Destroy" }, + { "name": "OH_AVFormat_Copy" }, + { "name": "OH_AVFormat_SetIntValue" }, + { "name": "OH_AVFormat_SetLongValue" }, + { "name": "OH_AVFormat_SetFloatValue" }, + { "name": "OH_AVFormat_SetDoubleValue" }, + { "name": "OH_AVFormat_SetStringValue" }, + { "name": "OH_AVFormat_SetBuffer" }, + { "name": "OH_AVFormat_GetIntValue" }, + { "name": "OH_AVFormat_GetLongValue" }, + { "name": "OH_AVFormat_GetFloatValue" }, + { "name": "OH_AVFormat_GetDoubleValue" }, + { "name": "OH_AVFormat_GetStringValue" }, + { "name": "OH_AVFormat_GetBuffer" }, + { "name": "OH_AVFormat_DumpInfo" }, + { "name": "OH_AVMemory_Create" }, + { "name": "OH_AVMemory_GetAddr" }, + { "name": "OH_AVMemory_GetSize" }, + { "name": "OH_AVMemory_Destroy" }, + { "name": "OH_AVCodec_GetCapability" }, + { "name": "OH_AVCodec_GetCapabilityByCategory" } +] diff --git a/multimedia/av_codec/native_avcapability.h b/multimedia/av_codec/native_avcapability.h new file mode 100644 index 000000000..043678aab --- /dev/null +++ b/multimedia/av_codec/native_avcapability.h @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVCAPABILITY_H +#define NATIVE_AVCAPABILITY_H + +#include +#include "native_averrors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_AVCapability OH_AVCapability; + +/** + * @brief The bitrate mode of encoder. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_BitrateMode { + /* Constant Bit rate mode. */ + BITRATE_MODE_CBR = 0, + /* Variable Bit rate mode. */ + BITRATE_MODE_VBR = 1, + /* Constant Quality mode. */ + BITRATE_MODE_CQ = 2 +} OH_BitrateMode; + +/** + * @brief Range contain min and max value + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef struct OH_AVRange { + int32_t minVal; + int32_t maxVal; +} OH_AVRange; + +/** + * @brief The codec category + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_AVCodecCategory { + HARDWARE = 0, + SOFTWARE +} OH_AVCodecCategory; + +/** + * @brief Get a system-recommended codec's capability. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param mime Mime type + * @param isEncoder True for encoder, false for decoder + * @return Returns a capability instance if an existing codec matches, + * if the specified mime type doesn't match any existing codec, returns NULL. + * @since 10 + */ +OH_AVCapability *OH_AVCodec_GetCapability(const char *mime, bool isEncoder); + +/** + * @brief Get a codec's capability within the specified category. By specifying the category, + * the matched codec is limited to either hardware codecs or software codecs. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param mime Mime type + * @param isEncoder True for encoder, false for decoder + * @param category The codec category + * @return Returns a capability instance if an existing codec matches, + * if the specified mime type doesn't match any existing codec, returns NULL + * @since 10 + */ +OH_AVCapability *OH_AVCodec_GetCapabilityByCategory(const char *mime, bool isEncoder, OH_AVCodecCategory category); + +/** + * @brief Check if the capability instance is describing a hardware codec. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Codec capability pointer + * @return Returns true if the capability instance is describing a hardware codec, + * false if the capability instance is describing a software codec + * @since 10 + */ +bool OH_AVCapability_IsHardware(OH_AVCapability *capability); + +/** + * @brief Get the codec name. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Codec capability pointer + * @return Returns codec name string + * @since 10 + */ +const char *OH_AVCapability_GetName(OH_AVCapability *capability); + +/** + * @brief Get the supported max instance number of the codec. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Codec capability pointer + * @return Returns the max supported codec instance number + * @since 10 + */ +int32_t OH_AVCapability_GetMaxSupportedInstances(OH_AVCapability *capability); + +/** + * @brief Get the encoder's supported bitrate range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Encoder capability pointer. Do not give a decoder capability pointer + * @param bitrateRange Output parameter. Encoder bitrate range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetEncoderBitrateRange(OH_AVCapability *capability, OH_AVRange *bitrateRange); + +/** + * @brief Check if the encoder supports the specific bitrate mode. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Encoder capability pointer. Do not give a decoder capability pointer + * @param bitrateMode Bitrate mode + * @return Returns true if the bitrate mode is supported, false if the bitrate mode is not supported + * @since 10 + */ +bool OH_AVCapability_IsEncoderBitrateModeSupported(OH_AVCapability *capability, OH_BitrateMode bitrateMode); + +/** + * @brief Get the encoder's supported quality range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Encoder capability pointer. Do not give a decoder capability pointer + * @param qualityRange Output parameter. Encoder quality range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetEncoderQualityRange(OH_AVCapability *capability, OH_AVRange *qualityRange); + +/** + * @brief Get the encoder's supported encoder complexity range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Encoder capability pointer. Do not give a decoder capability pointer + * @param complexityRange Output parameter. Encoder complexity range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetEncoderComplexityRange(OH_AVCapability *capability, OH_AVRange *complexityRange); + +/** + * @brief Get the audio codec's supported sample rates. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Audio codec capability pointer. Do not give a video codec capability pointer + * @param sampleRates Output parameter. A pointer to the sample rates array + * @param sampleRateNum Output parameter. The element number of the sample rates array + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetAudioSupportedSampleRates(OH_AVCapability *capability, const int32_t **sampleRates, + uint32_t *sampleRateNum); + +/** + * @brief Get the audio codec's supported audio channel count range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Audio codec capability pointer. Do not give a video codec capability pointer + * @param channelCountRange Output parameter. Audio channel count range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetAudioChannelCountRange(OH_AVCapability *capability, OH_AVRange *channelCountRange); + +/** + * @brief Get the video codec's supported video width alignment. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param widthAlignment Output parameter. Video width alignment + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoWidthAlignment(OH_AVCapability *capability, int32_t *widthAlignment); + +/** + * @brief Get the video codec's supported video height alignment. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param heightAlignment Output parameter. Video height alignment + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoHeightAlignment(OH_AVCapability *capability, int32_t *heightAlignment); + +/** + * @brief Get the video codec's supported video width range for a specific height. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability video codec capability pointer. Do not give an audio codec capability pointer + * @param height Vertical pixel number of the video + * @param widthRange Output parameter. Video width range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoWidthRangeForHeight(OH_AVCapability *capability, int32_t height, + OH_AVRange *widthRange); + +/** + * @brief Get the video codec's supported video height range for a specific width. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param width Horizontal pixel number of the video + * @param heightRange Output parameter. Video height range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoHeightRangeForWidth(OH_AVCapability *capability, int32_t width, + OH_AVRange *heightRange); + +/** + * @brief Get the video codec's supported video width range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. DO not give an audio codec capability pointer + * @param widthRange Output parameter. Video width range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoWidthRange(OH_AVCapability *capability, OH_AVRange *widthRange); + +/** + * @brief Get the video codec's supported video height range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param heightRange Output parameter. Video height range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoHeightRange(OH_AVCapability *capability, OH_AVRange *heightRange); + +/** + * @brief Check if the video codec supports the specific video size. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param width Horizontal pixel number of the video + * @param height Vertical pixel number of the video + * @return Returns true if the video size is supported, false if the video size is not supported + * @since 10 + */ +bool OH_AVCapability_IsVideoSizeSupported(OH_AVCapability *capability, int32_t width, int32_t height); + +/** + * @brief Get the video codec's supported video frame rate range. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param frameRateRange Output parameter. Video frame rate range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoFrameRateRange(OH_AVCapability *capability, OH_AVRange *frameRateRange); + +/** + * @brief Get the Video codec's supported video frame rate range for a specified video size. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param width Horizontal pixel number of the video + * @param height Vertical pixel number of the video + * @param frameRateRange Output parameter. Frame rate range + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoFrameRateRangeForSize(OH_AVCapability *capability, int32_t width, int32_t height, + OH_AVRange *frameRateRange); + +/** + * @brief Check if the video codec supports the specific combination of video size and frame rate. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param width Horizontal pixel number of the video + * @param height Vertical pixel number of the video + * @param frameRate Frame number per second + * @return Returns true if the combination of video size and frame rate is supported, + * false if it is not supported + * @since 10 + */ +bool OH_AVCapability_AreVideoSizeAndFrameRateSupported(OH_AVCapability *capability, int32_t width, int32_t height, + int32_t frameRate); + +/** + * @brief Get the video codec's supported video pixel format. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Video codec capability pointer. Do not give an audio codec capability pointer + * @param pixelFormats Output parameter. A pointer to the video pixel format array + * @param pixelFormatNum Output parameter. The element number of the pixel format array + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetVideoSupportedPixelFormats(OH_AVCapability *capability, const int32_t **pixelFormats, + uint32_t *pixelFormatNum); + +/** + * @brief Get the codec's supported profiles. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Codec capability pointer + * @param profiles Output parameter. A pointer to the profile array + * @param profileNum Output parameter. The element number of the profile array + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetSupportedProfiles(OH_AVCapability *capability, const int32_t **profiles, + uint32_t *profileNum); + +/** + * @brief Get codec's supported levels for a specific profile. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Codec capability pointer + * @param profile Codec profile + * @param levels Output parameter. A pointer to the level array + * @param levelNum Output parameter. The element number of the level array + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVCapability_GetSupportedLevelsForProfile(OH_AVCapability *capability, int32_t profile, + const int32_t **levels, uint32_t *levelNum); + +/** + * @brief Check if the codec supports the specific combination of the profile and level. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param capability Codec capability pointer + * @param profile Codec profile + * @param level Codec level + * @return Returns true if the combination of profile and level is supported, + * false if it is not supported + * @since 10 + */ +bool OH_AVCapability_AreProfileAndLevelSupported(OH_AVCapability *capability, int32_t profile, int32_t level); + +#ifdef __cplusplus +} +#endif +#endif // NATIVE_AVCAPABILITY_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avcodec_audiodecoder.h b/multimedia/av_codec/native_avcodec_audiodecoder.h new file mode 100644 index 000000000..bb62e8a8c --- /dev/null +++ b/multimedia/av_codec/native_avcodec_audiodecoder.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVCODEC_AUDIODECODER_H +#define NATIVE_AVCODEC_AUDIODECODER_H + +#include +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "native_avmemory.h" +#include "native_avcodec_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates an audio decoder instance from the mime type, which is recommended in most cases. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param mime mime type description string, refer to {@link AVCODEC_MIME_TYPE} + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_AudioDecoder_CreateByMime(const char *mime); + +/** + * @brief Create an audio decoder instance through the audio decoder name. + * The premise of using this interface is to know the exact name of the decoder. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param name Audio codec name + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_AudioDecoder_CreateByName(const char *name); + +/** + * @brief Clear the internal resources of the decoder and destroy the decoder instance + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_Destroy(OH_AVCodec *codec); + +/** + * @brief Set the asynchronous callback function so that your application + * can respond to the events generated by the audio decoder. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param callback A collection of all callback functions, see {@link OH_AVCodecAsyncCallback} + * @param userData User specific data + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData); + +/** + * @brief To configure the audio decoder, typically, you need to configure the description information of the decoded + * audio track, which can be extracted from the container. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param format A pointer to an OH_AVFormat giving a description of the audio track to be decoded + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_Configure(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief To prepare the internal resources of the decoder, the Configure interface must be called + * before calling this interface. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_Prepare(OH_AVCodec *codec); + +/** + * @brief Start the decoder, this interface must be called after the Prepare is successful. + * After being successfully started, the decoder will start reporting NeedInputData events. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_Start(OH_AVCodec *codec); + +/** + * @brief Stop the decoder. After stopping, you can re-enter the Started state through Start, + * but it should be noted that need to re-enter if the decoder has been input before + * Codec-Specific-Data. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_Stop(OH_AVCodec *codec); + +/** + * @brief Clear the input and output data buffered in the decoder. After this interface is called, all the Buffer + * indexes previously reported through the asynchronous callback will be invalidated, make sure not to access + * the Buffers corresponding to these indexes. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_Flush(OH_AVCodec *codec); + +/** + * @brief Reset the decoder. To continue decoding, you need to call the Configure interface again to + * configure the decoder instance. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ + +OH_AVErrCode OH_AudioDecoder_Reset(OH_AVCodec *codec); + +/** + * @brief Get the description information of the output data of the decoder, refer to {@link OH_AVFormat} for details. + * It should be noted that the life cycle of the OH_AVFormat instance pointed to by the return value * needs to + * be manually released by the caller + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns the OH_AVFormat handle pointer, the life cycle is refreshed with the next GetOutputMediaDescription, + * or destroyed with OH_AVCodec; + * @since 9 + * @version 1.0 + */ +OH_AVFormat *OH_AudioDecoder_GetOutputDescription(OH_AVCodec *codec); + +/** + * @brief Set dynamic parameters to the decoder. Note: This interface can only be called after the decoder is started. + * At the same time, incorrect parameter settings may cause decoding failure. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param format OH_AVFormat handle pointer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief Submit the input buffer filled with data to the audio decoder. The {@link OH_AVCodecOnNeedInputData} callback + * will report the available input buffer and the corresponding index value. Once the buffer with the specified index + * is submitted to the audio decoder, the buffer cannot be accessed again until the {@link OH_AVCodecOnNeedInputData} + * callback is received again reporting that the buffer with the same index is available. In addition, for some + * decoders, it is required to input Codec-Specific-Data to the decoder at the beginning to initialize the decoding + * process of the decoder. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param index Enter the index value corresponding to the Buffer + * @param attr Information describing the data contained in the Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr); + +/** + * @brief Return the processed output Buffer to the decoder. + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param index The index value corresponding to the output Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioDecoder_FreeOutputData(OH_AVCodec *codec, uint32_t index); + +/** + * @brief Check whether the current codec instance is valid. It can be used fault recovery or app + * switchback from the background + * @syscap SystemCapability.Multimedia.Media.AudioDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param isValid Output Parameter. A pointer to a boolean instance, it is true if the codec instance is valid, + * false if the codec instance is invalid + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AudioDecoder_IsValid(OH_AVCodec *codec, bool *isValid); + +#ifdef __cplusplus +} +#endif +#endif // NATIVE_AVCODEC_AUDIODECODER_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avcodec_audioencoder.h b/multimedia/av_codec/native_avcodec_audioencoder.h new file mode 100644 index 000000000..7493f69e0 --- /dev/null +++ b/multimedia/av_codec/native_avcodec_audioencoder.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVCODEC_AUDIOENCODER_H +#define NATIVE_AVCODEC_AUDIOENCODER_H + +#include +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "native_avmemory.h" +#include "native_avcodec_base.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates an audio encoder instance from the mime type, this interface is recommended in most cases. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param mime mime type description string, refer to {@link AVCODEC_MIME_TYPE} + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_AudioEncoder_CreateByMime(const char *mime); + +/** + * @brief Create an audio encoder instance through the audio encoder name. + * The premise of using this interface is to know the exact name of the encoder. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param name Audio encoder name + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_AudioEncoder_CreateByName(const char *name); + +/** + * @brief Clear the internal resources of the encoder and destroy the encoder instance + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Destroy(OH_AVCodec *codec); + +/** + * @brief Set the asynchronous callback function so that your application can respond to + * the events generated by the audio encoder. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param callback A collection of all callback functions, see {@link OH_AVCodecAsyncCallback} + * @param userData User specific data + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData); + +/** + * @brief To configure the audio encoder, typically, you need to configure the description information of + * the encoded audio track. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param format OH_AVFormat handle pointer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Configure(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief To prepare the internal resources of the encoder, + * the Configure interface must be called before calling this interface. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Prepare(OH_AVCodec *codec); + +/** + * @brief Start the encoder, this interface must be called after the Prepare is successful. + * After being successfully started, the encoder will start reporting NeedInputData events. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Start(OH_AVCodec *codec); + +/** + * @brief Stop the encoder. After stopping, you can re-enter the Started state through Start. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Stop(OH_AVCodec *codec); + +/** + * @brief Clear the input and output data buffered in the encoder. After this interface is called, + * all the Buffer indexes previously reported through the asynchronous callback will be invalidated, + * make sure not to access the Buffers corresponding to these indexes. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Flush(OH_AVCodec *codec); + +/** + * @brief Reset the encoder. To continue coding, you need to call the Configure interface + * again to configure the encoder instance. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_Reset(OH_AVCodec *codec); + +/** + * @brief Get the description information of the output data of the encoder, refer to {@link OH_AVFormat} for details. + * It should be noted that the life cycle of the OH_AVFormat instance pointed to by the return value * needs to + * be manually released by the caller. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns the OH_AVFormat handle pointer, the life cycle is refreshed with the next GetOutputMediaDescription, + * or destroyed with OH_AVCodec; + * @since 9 + * @version 1.0 + */ +OH_AVFormat *OH_AudioEncoder_GetOutputDescription(OH_AVCodec *codec); + +/** + * @brief Set dynamic parameters to the encoder. Note: This interface can only be called after the encoder is started. + * At the same time, incorrect parameter settings may cause the encoding to fail. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param format OH_AVFormat handle pointer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief Submit the input buffer filled with data to the audio encoder. The {@link OH_AVCodecOnNeedInputData} + * callback will report the available input buffer and the corresponding index value. Once the buffer with the + * specified index is submitted to the audio encoder, the buffer cannot be accessed again until the + * callback is received again reporting that the buffer with the same index is available + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param index Enter the index value corresponding to the Buffer + * @param attr Information describing the data contained in the Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr); + +/** + * @brief Return the processed output Buffer to the encoder. + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param index The index value corresponding to the output Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_AudioEncoder_FreeOutputData(OH_AVCodec *codec, uint32_t index); + +/** + * @brief Check whether the current codec instance is valid. It can be used fault recovery or app + * switchback from the background + * @syscap SystemCapability.Multimedia.Media.AudioEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param isValid Output Parameter. A pointer to a boolean instance, it is true if the codec instance is valid, + * false if the codec instance is invalid + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AudioEncoder_IsValid(OH_AVCodec *codec, bool *isValid); + +#ifdef __cplusplus +} +#endif +#endif // NATIVE_AVCODEC_AUDIOENCODER_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avcodec_base.h b/multimedia/av_codec/native_avcodec_base.h new file mode 100644 index 000000000..bedee4004 --- /dev/null +++ b/multimedia/av_codec/native_avcodec_base.h @@ -0,0 +1,450 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVCODEC_BASE_H +#define NATIVE_AVCODEC_BASE_H + +#include +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "native_avmemory.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct NativeWindow OHNativeWindow; +typedef struct OH_AVCodec OH_AVCodec; + +/** + * @brief Enumerate the categories of OH_AVCodec's Buffer tags + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +typedef enum OH_AVCodecBufferFlags { + AVCODEC_BUFFER_FLAGS_NONE = 0, + /* Indicates that the Buffer is an End-of-Stream frame */ + AVCODEC_BUFFER_FLAGS_EOS = 1 << 0, + /* Indicates that the Buffer contains keyframes */ + AVCODEC_BUFFER_FLAGS_SYNC_FRAME = 1 << 1, + /* Indicates that the data contained in the Buffer is only part of a frame */ + AVCODEC_BUFFER_FLAGS_INCOMPLETE_FRAME = 1 << 2, + /* Indicates that the Buffer contains Codec-Specific-Data */ + AVCODEC_BUFFER_FLAGS_CODEC_DATA = 1 << 3, +} OH_AVCodecBufferFlags; + +/** + * @brief Define the Buffer description information of OH_AVCodec + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +typedef struct OH_AVCodecBufferAttr { + /* Presentation timestamp of this Buffer in microseconds */ + int64_t pts; + /* The size of the data contained in the Buffer in bytes */ + int32_t size; + /* The starting offset of valid data in this Buffer */ + int32_t offset; + /* The flags this Buffer has, which is also a combination of multiple {@link OH_AVCodecBufferFlags}. */ + uint32_t flags; +} OH_AVCodecBufferAttr; + +/** + * @brief When an error occurs in the running of the OH_AVCodec instance, the function pointer will be called + * to report specific error information. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param codec OH_AVCodec instance + * @param errorCode specific error code + * @param userData User specific data + * @since 9 + * @version 1.0 + */ +typedef void (*OH_AVCodecOnError)(OH_AVCodec *codec, int32_t errorCode, void *userData); + +/** + * @brief When the output stream changes, the function pointer will be called to report the new stream description + * information. It should be noted that the life cycle of the OH_AVFormat pointer + * is only valid when the function pointer is called, and it is forbidden to continue to access after the call ends. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param codec OH_AVCodec instance + * @param format New output stream description information + * @param userData User specific data + * @since 9 + * @version 1.0 + */ +typedef void (*OH_AVCodecOnStreamChanged)(OH_AVCodec *codec, OH_AVFormat *format, void *userData); + +/** + * @brief When OH_AVCodec needs new input data during the running process, + * the function pointer will be called and carry an available Buffer to fill in the new input data. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param codec OH_AVCodec instance + * @param index The index corresponding to the newly available input buffer. + * @param data New available input buffer. + * @param userData User specific data + * @since 9 + * @version 1.0 + */ +typedef void (*OH_AVCodecOnNeedInputData)(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, void *userData); + +/** + * @brief When new output data is generated during the operation of OH_AVCodec, the function pointer will be + * called and carry a Buffer containing the new output data. It should be noted that the life cycle of the + * OH_AVCodecBufferAttr pointer is only valid when the function pointer is called. , which prohibits continued + * access after the call ends. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param codec OH_AVCodec instance + * @param index The index corresponding to the new output Buffer. + * @param data Buffer containing the new output data + * @param attr The description of the new output Buffer, please refer to {@link OH_AVCodecBufferAttr} + * @param userData specified data + * @since 9 + * @version 1.0 + */ +typedef void (*OH_AVCodecOnNewOutputData)(OH_AVCodec *codec, uint32_t index, OH_AVMemory *data, + OH_AVCodecBufferAttr *attr, void *userData); + +/** + * @brief A collection of all asynchronous callback function pointers in OH_AVCodec. Register an instance of this + * structure to the OH_AVCodec instance, and process the information reported through the callback to ensure the + * normal operation of OH_AVCodec. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @param onError Monitor OH_AVCodec operation errors, refer to {@link OH_AVCodecOnError} + * @param onStreamChanged Monitor codec stream information, refer to {@link OH_AVCodecOnStreamChanged} + * @param onNeedInputData Monitoring codec requires input data, refer to {@link OH_AVCodecOnNeedInputData} + * @param onNeedInputData Monitor codec to generate output data, refer to {@link onNeedInputData} + * @since 9 + * @version 1.0 + */ +typedef struct OH_AVCodecAsyncCallback { + OH_AVCodecOnError onError; + OH_AVCodecOnStreamChanged onStreamChanged; + OH_AVCodecOnNeedInputData onNeedInputData; + OH_AVCodecOnNewOutputData onNeedOutputData; +} OH_AVCodecAsyncCallback; + +/** + * @brief Enumerates the MIME types of audio and video codecs + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +extern const char *OH_AVCODEC_MIMETYPE_VIDEO_AVC; +extern const char *OH_AVCODEC_MIMETYPE_AUDIO_AAC; + +/** + * @brief Enumerates the MIME types of audio and video codecs + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +extern const char *OH_AVCODEC_MIMETYPE_AUDIO_FLAC; +extern const char *OH_AVCODEC_MIMETYPE_AUDIO_VORBIS; +extern const char *OH_AVCODEC_MIMETYPE_AUDIO_MPEG; +extern const char *OH_AVCODEC_MIMETYPE_VIDEO_HEVC; +extern const char *OH_AVCODEC_MIMETYPE_VIDEO_MPEG4; +extern const char *OH_AVCODEC_MIMETYPE_IMAGE_JPG; +extern const char *OH_AVCODEC_MIMETYPE_IMAGE_PNG; +extern const char *OH_AVCODEC_MIMETYPE_IMAGE_BMP; + +/** + * @brief The extra data's key of surface Buffer + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +/* Key for timeStamp in surface's extraData, value type is int64 */ +extern const char *OH_ED_KEY_TIME_STAMP; +/* Key for endOfStream in surface's extraData, value type is bool */ +extern const char *OH_ED_KEY_EOS; + +/** + * @brief Provides the uniform container for storing the media description. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +/* Key for track type, value type is uint8_t, see @OH_MediaType. */ +extern const char *OH_MD_KEY_TRACK_TYPE; +/* Key for codec mime type, value type is string. */ +extern const char *OH_MD_KEY_CODEC_MIME; +/* Key for duration, value type is int64_t. */ +extern const char *OH_MD_KEY_DURATION; +/* Key for bitrate, value type is uint32_t. */ +extern const char *OH_MD_KEY_BITRATE; +/* Key for max input size, value type is uint32_t */ +extern const char *OH_MD_KEY_MAX_INPUT_SIZE; +/* Key for video width, value type is uint32_t */ +extern const char *OH_MD_KEY_WIDTH; +/* Key for video height, value type is uint32_t */ +extern const char *OH_MD_KEY_HEIGHT; +/* Key for video pixel format, value type is int32_t, see @OH_AVPixelFormat */ +extern const char *OH_MD_KEY_PIXEL_FORMAT; +/* key for audio raw format, value type is uint32_t , see @AudioSampleFormat */ +extern const char *OH_MD_KEY_AUDIO_SAMPLE_FORMAT; +/* Key for video frame rate, value type is double. */ +extern const char *OH_MD_KEY_FRAME_RATE; +/* video encode bitrate mode, the value type is int32_t, see @OH_VideoEncodeBitrateMode */ +extern const char *OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE; +/* encode profile, the value type is number. see @OH_AVCProfile, OH_HEVCProfile, OH_AACProfile. */ +extern const char *OH_MD_KEY_PROFILE; +/* Key for audio channel count, value type is uint32_t */ +extern const char *OH_MD_KEY_AUD_CHANNEL_COUNT; +/* Key for audio sample rate, value type is uint32_t */ +extern const char *OH_MD_KEY_AUD_SAMPLE_RATE; +/* Key for the interval of key frame. value type is int32_t, the unit is milliseconds. */ +extern const char *OH_MD_KEY_I_FRAME_INTERVAL; +/* Key of the surface rotation angle. value type is int32_t: should be {0, 90, 180, 270}, default is 0. */ +extern const char *OH_MD_KEY_ROTATION; + +/** + * @brief Provides the uniform container for storing the media description. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +/* Key for video YUV value range flag, value type is boolean */ +extern const char *OH_MD_KEY_RANGE_FLAG; +/* Key for video color primaries, value type is int32_t, see @OH_ColorPrimary */ +extern const char *OH_MD_KEY_COLOR_PRIMARIES; +/* Key for video transfer characteristics, value type is int32_t, see @OH_TransferCharacteristic */ +extern const char *OH_MD_KEY_TRANSFER_CHARACTERISTICS; +/* Key for video matrix coefficients, value type is int32_t, see @OH_MatrixCoefficient */ +extern const char *OH_MD_KEY_MATRIX_COEFFICIENTS; +/* Key for the request an I-Frame immediately, value type is boolean */ +extern const char *OH_MD_KEY_REQUEST_I_FRAME; +/* Key for the desired encoding quality, value type is uint32_t, this key is only + * supported for encoders that are configured in constant quality mode */ +extern const char *OH_MD_KEY_QUALITY; +/* Key of the codec specific data. value type is a uint8_t pointer */ +extern const char *OH_MD_KEY_CODEC_CONFIG; +/* source format Key for title, value type is string */ +extern const char *OH_MD_KEY_TITLE; +/* source format Key for artist, value type is string */ +extern const char *OH_MD_KEY_ARTIST; +/* source format Key for album, value type is string */ +extern const char *OH_MD_KEY_ALBUM; +/* source format Key for album artist, value type is string */ +extern const char *OH_MD_KEY_ALBUM_ARTIST; +/* source format Key for date, value type is string */ +extern const char *OH_MD_KEY_DATE; +/* source format Key for comment, value type is string */ +extern const char *OH_MD_KEY_COMMENT; +/* source format Key for genre, value type is string */ +extern const char *OH_MD_KEY_GENRE; +/* source format Key for copyright, value type is string */ +extern const char *OH_MD_KEY_COPYRIGHT; +/* source format Key for language, value type is string */ +extern const char *OH_MD_KEY_LANGUAGE; +/* source format Key for description, value type is string */ +extern const char *OH_MD_KEY_DESCRIPTION; +/* source format Key for lyrics, value type is string */ +extern const char *OH_MD_KEY_LYRICS; +/* source format Key for track count, value type is uint32_t */ +extern const char *OH_MD_KEY_TRACK_COUNT; +/* Key for the desired encoding channel layout, value type is int64_t, this key is only supported for encoders */ +extern const char *OH_MD_KEY_CHANNEL_LAYOUT; +/* Key for bits per coded sample, value type is uint32_t, supported for flac encoder, see @OH_BitsPerSample */ +extern const char *OH_MD_KEY_BITS_PER_CODED_SAMPLE; +/* Key for the aac format, value type is uint32_t, supported for aac decoder */ +extern const char *OH_MD_KEY_AAC_IS_ADTS; +/* Key for aac sbr mode, value type is uint32_t, supported for aac encoder */ +extern const char *OH_MD_KEY_SBR; +/* Key for flac compliance level, value type is int32_t */ +extern const char *OH_MD_KEY_COMPLIANCE_LEVEL; +/* Key for vorbis identification header, value type is a uint8_t pointer, supported only for vorbis decoder */ +extern const char *OH_MD_KEY_IDENTIFICATION_HEADER; +/* Key for vorbis setup header, value type is a uint8_t pointer, supported only for vorbis decoder */ +extern const char *OH_MD_KEY_SETUP_HEADER; +/* Key for video scale type, value type is int32_t, see @OH_ScalingMode */ +extern const char *OH_MD_KEY_SCALING_MODE; +/* Key for max input buffer count, value type is int32_t */ +extern const char *OH_MD_MAX_INPUT_BUFFER_COUNT; +/* Key for max output buffer count, value type is int32_t */ +extern const char *OH_MD_MAX_OUTPUT_BUFFER_COUNT; + +/** + * @brief Media type. + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +typedef enum OH_MediaType { + /* track is audio. */ + MEDIA_TYPE_AUD = 0, + /* track is video. */ + MEDIA_TYPE_VID = 1, +} OH_MediaType; + +/** + * @brief AAC Profile + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +typedef enum OH_AACProfile { + AAC_PROFILE_LC = 0, +} OH_AACProfile; + +/** + * @brief AVC Profile + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 9 + * @version 1.0 + */ +typedef enum OH_AVCProfile { + AVC_PROFILE_BASELINE = 0, + AVC_PROFILE_HIGH = 4, + AVC_PROFILE_MAIN = 8, +} OH_AVCProfile; + +/** + * @brief Enumerates the muxer output file format + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_AVOutputFormat { + AV_OUTPUT_FORMAT_DEFAULT = 0, + AV_OUTPUT_FORMAT_MPEG_4 = 2, + AV_OUTPUT_FORMAT_M4A = 6, +} OH_AVOutputFormat; + +/** + * @brief Seek Mode + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_AVSeekMode { + /* seek to sync sample after the time */ + SEEK_MODE_NEXT_SYNC = 0, + /* seek to sync sample before the time */ + SEEK_MODE_PREVIOUS_SYNC, + /* seek to sync sample closest to time */ + SEEK_MODE_CLOSEST_SYNC, +} OH_AVSeekMode; + +/** + * @brief HEVC Profile + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_HEVCProfile { + HEVC_PROFILE_MAIN = 0, + HEVC_PROFILE_MAIN_10 = 1, + HEVC_PROFILE_MAIN_STILL = 2, + HEVC_PROFILE_MAIN_10_HDR10 = 3, + HEVC_PROFILE_MAIN_10_HDR10_PLUS = 4, +} OH_HEVCProfile; + +/** + * @brief Color Primary + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_ColorPrimary { + COLOR_PRIMARY_BT709 = 1, + COLOR_PRIMARY_UNSPECIFIED = 2, + COLOR_PRIMARY_BT470_M = 4, + COLOR_PRIMARY_BT601_625 = 5, + COLOR_PRIMARY_BT601_525 = 6, + COLOR_PRIMARY_SMPTE_ST240 = 7, + COLOR_PRIMARY_GENERIC_FILM = 8, + COLOR_PRIMARY_BT2020 = 9, + COLOR_PRIMARY_SMPTE_ST428 = 10, + COLOR_PRIMARY_P3DCI = 11, + COLOR_PRIMARY_P3D65 = 12, +} OH_ColorPrimary; + +/** + * @brief Transfer Characteristic + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_TransferCharacteristic { + TRANSFER_CHARACTERISTIC_BT709 = 1, + TRANSFER_CHARACTERISTIC_UNSPECIFIED = 2, + TRANSFER_CHARACTERISTIC_GAMMA_2_2 = 4, + TRANSFER_CHARACTERISTIC_GAMMA_2_8 = 5, + TRANSFER_CHARACTERISTIC_BT601 = 6, + TRANSFER_CHARACTERISTIC_SMPTE_ST240 = 7, + TRANSFER_CHARACTERISTIC_LINEAR = 8, + TRANSFER_CHARACTERISTIC_LOG = 9, + TRANSFER_CHARACTERISTIC_LOG_SQRT = 10, + TRANSFER_CHARACTERISTIC_IEC_61966_2_4 = 11, + TRANSFER_CHARACTERISTIC_BT1361 = 12, + TRANSFER_CHARACTERISTIC_IEC_61966_2_1 = 13, + TRANSFER_CHARACTERISTIC_BT2020_10BIT = 14, + TRANSFER_CHARACTERISTIC_BT2020_12BIT = 15, + TRANSFER_CHARACTERISTIC_PQ = 16, + TRANSFER_CHARACTERISTIC_SMPTE_ST428 = 17, + TRANSFER_CHARACTERISTIC_HLG = 18, +} OH_TransferCharacteristic; + +/** + * @brief Matrix Coefficient + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_MatrixCoefficient { + MATRIX_COEFFICIENT_IDENTITY = 0, + MATRIX_COEFFICIENT_BT709 = 1, + MATRIX_COEFFICIENT_UNSPECIFIED = 2, + MATRIX_COEFFICIENT_FCC = 4, + MATRIX_COEFFICIENT_BT601_625 = 5, + MATRIX_COEFFICIENT_BT601_525 = 6, + MATRIX_COEFFICIENT_SMPTE_ST240 = 7, + MATRIX_COEFFICIENT_YCGCO = 8, + MATRIX_COEFFICIENT_BT2020_NCL = 9, + MATRIX_COEFFICIENT_BT2020_CL = 10, + MATRIX_COEFFICIENT_SMPTE_ST2085 = 11, + MATRIX_COEFFICIENT_CHROMATICITY_NCL = 12, + MATRIX_COEFFICIENT_CHROMATICITY_CL = 13, + MATRIX_COEFFICIENT_ICTCP = 14, +} OH_MatrixCoefficient; + +/** + * @brief Scaling Mode + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_ScalingMode { + SCALING_MODE_SCALE_TO_WINDOW = 1, + SCALING_MODE_SCALE_CROP = 2, +} OH_ScalingMode; + +/** + * @brief enum Audio Bits Per Coded Sample + * @syscap SystemCapability.Multimedia.Media.CodecBase + * @since 10 + */ +typedef enum OH_BitsPerSample { + SAMPLE_U8 = 0, + SAMPLE_S16LE = 1, + SAMPLE_S24LE = 2, + SAMPLE_S32LE = 3, + SAMPLE_F32LE = 4, + SAMPLE_U8P = 5, + SAMPLE_S16P = 6, + SAMPLE_S24P = 7, + SAMPLE_S32P = 8, + SAMPLE_F32P = 9, + INVALID_WIDTH = -1 +} OH_BitsPerSample; +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVCODEC_BASE_H diff --git a/multimedia/av_codec/native_avcodec_videodecoder.h b/multimedia/av_codec/native_avcodec_videodecoder.h new file mode 100644 index 000000000..3bc557751 --- /dev/null +++ b/multimedia/av_codec/native_avcodec_videodecoder.h @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVCODEC_VIDEODECODER_H +#define NATIVE_AVCODEC_VIDEODECODER_H + +#include +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "native_avmemory.h" +#include "native_avcodec_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates a video decoder instance from the mime type, which is recommended in most cases. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param mime mime type description string, refer to {@link AVCODEC_MIME_TYPE} + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_VideoDecoder_CreateByMime(const char *mime); + +/** + * @brief Create a video decoder instance through the video decoder name. + * The premise of using this interface is to know the exact name of the decoder. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param name video codec name + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_VideoDecoder_CreateByName(const char *name); + +/** + * @brief Clear the internal resources of the decoder and destroy the decoder instance + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Destroy(OH_AVCodec *codec); + +/** + * @brief Set the asynchronous callback function so that your application can respond to the events + * generated by the video decoder. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param callback A collection of all callback functions, see {@link OH_AVCodecAsyncCallback} + * @param userData User specific data + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData); + +/** + * @brief Specify the output Surface to provide video decoding output, + * this interface must be called before Prepare is called + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param window A pointer to a OHNativeWindow instance, see {@link OHNativeWindow} + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_SetSurface(OH_AVCodec *codec, OHNativeWindow *window); + +/** + * @brief To configure the video decoder, typically, you need to configure the description information of the decoded + * video track, which can be extracted from the container. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param format A pointer to an OH_AVFormat to give the description of the video track to be decoded + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Configure(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief To prepare the internal resources of the decoder, the Configure interface must be called before + * calling this interface. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Prepare(OH_AVCodec *codec); + +/** + * @brief Start the decoder, this interface must be called after the Prepare is successful. + * After being successfully started, the decoder will start reporting NeedInputData events. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Start(OH_AVCodec *codec); + +/** + * @brief Stop the decoder. After stopping, you can re-enter the Started state through Start, + * but it should be noted that if Codec-Specific-Data has been input to the decoder before, it needs to be input again. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Stop(OH_AVCodec *codec); + +/** + * @brief Clear the input and output data buffered in the decoder. After this interface is called, all the Buffer + * indexes previously reported through the asynchronous callback will be invalidated, make sure not to access + * the Buffers corresponding to these indexes. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Flush(OH_AVCodec *codec); + +/** + * @brief Reset the decoder. To continue decoding, you need to call the Configure interface again + * to configure the decoder instance. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_Reset(OH_AVCodec *codec); + +/** + * @brief Get the description information of the output data of the decoder, refer to {@link OH_AVFormat} + * It should be noted that the life cycle of the OH_AVFormat instance pointed to by the return value * needs + * to be manually released by the caller. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns a pointer to an OH_AVFormat instance + * @since 9 + * @version 1.0 + */ +OH_AVFormat *OH_VideoDecoder_GetOutputDescription(OH_AVCodec *codec); + +/** + * @brief Set dynamic parameters to the decoder. Note: This interface can only be called after the decoder is started. + * At the same time, incorrect parameter settings may cause decoding failure. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param format pointer to an OH_AVFormat instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief Submit the input buffer filled with data to the video decoder. The {@link OH_AVCodecOnNeedInputData} callback + * will report the available input buffer and the corresponding index value. Once the buffer with the specified index + * is submitted to the video decoder, the buffer cannot be accessed again until the {@link OH_AVCodecOnNeedInputData} + * callback is received again reporting that the buffer with the same index is available. In addition, for some + * decoders, it is required to input Codec-Specific-Data to the decoder at the beginning to initialize the decoding + * process of the decoder, such as PPS/SPS data in H264 format. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param index Enter the index value corresponding to the Buffer + * @param attr Information describing the data contained in the Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr); + +/** + * @brief Return the processed output Buffer to the decoder, and notify the decoder to finish rendering the + * decoded data contained in the Buffer on the output Surface. If the output surface is not configured before, + * calling this interface only returns the output buffer corresponding to the specified index to the decoder. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param index The index value corresponding to the output Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_RenderOutputData(OH_AVCodec *codec, uint32_t index); + +/** + * @brief Return the processed output Buffer to the decoder. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param index The index value corresponding to the output Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoDecoder_FreeOutputData(OH_AVCodec *codec, uint32_t index); + +/** + * @brief Check whether the current codec instance is valid. It can be used fault recovery or app + * switchback from the background. + * @syscap SystemCapability.Multimedia.Media.VideoDecoder + * @param codec Pointer to an OH_AVCodec instance + * @param isValid Output parameter. A pointer to a boolean instance, it is true if the codec instance is valid, + * false if the codec instance is invalid + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_VideoDecoder_IsValid(OH_AVCodec *codec, bool *isValid); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVCODEC_VIDEODECODER_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avcodec_videoencoder.h b/multimedia/av_codec/native_avcodec_videoencoder.h new file mode 100644 index 000000000..86b8750d6 --- /dev/null +++ b/multimedia/av_codec/native_avcodec_videoencoder.h @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVCODEC_VIDEOENCODER_H +#define NATIVE_AVCODEC_VIDEOENCODER_H + +#include +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "native_avmemory.h" +#include "native_avcodec_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates a video encoder instance from the mime type, which is recommended in most cases. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param mime mime type description string, refer to {@link AVCODEC_MIME_TYPE} + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_VideoEncoder_CreateByMime(const char *mime); + +/** + * @brief Create a video encoder instance through the video encoder name. The premise of using this interface is to + * know the exact name of the encoder. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param name Video encoder name + * @return Returns a Pointer to an OH_AVCodec instance + * @since 9 + * @version 1.0 + */ +OH_AVCodec *OH_VideoEncoder_CreateByName(const char *name); + +/** + * @brief Clear the internal resources of the encoder and destroy the encoder instance + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Destroy(OH_AVCodec *codec); + +/** + * @brief Set the asynchronous callback function so that your application can respond to the events generated by the + * video encoder. This interface must be called before Prepare is called + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param callback A collection of all callback functions, see {@link OH_AVCodecAsyncCallback} + * @param userData User specific data + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData); + +/** + * @brief To configure the video encoder, typically, you need to configure the description information of the + * encoded video track. This interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param format A pointer to an OH_AVFormat that gives the description of the video track to be encoded + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Configure(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief To prepare the internal resources of the encoder, the Configure interface must be called before + * calling this interface. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Prepare(OH_AVCodec *codec); + +/** + * @brief Start the encoder, this interface must be called after the Prepare is successful. After being + * successfully started, the encoder will start reporting NeedInputData events. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Start(OH_AVCodec *codec); + +/** + * @brief Stop the encoder. After stopping, you can re-enter the Started state through Start. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Stop(OH_AVCodec *codec); + +/** + * @brief Clear the input and output data buffered in the encoder. After this interface is called, all the Buffer + * indexes previously reported through the asynchronous callback will be invalidated, make sure not to access the + * Buffers corresponding to these indexes. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Flush(OH_AVCodec *codec); + +/** + * @brief Reset the encoder. To continue coding, you need to call the Configure interface again to + * configure the encoder instance. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_Reset(OH_AVCodec *codec); + +/** + * @brief Get the description information of the output data of the encoder, refer to {@link OH_AVFormat} for details. + * It should be noted that the life cycle of the OH_AVFormat instance pointed to by the return value * needs to + * be manually released by the caller. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns a pointer to an OH_AVFormat instance + * @since 9 + * @version 1.0 + */ +OH_AVFormat *OH_VideoEncoder_GetOutputDescription(OH_AVCodec *codec); + +/** + * @brief Set dynamic parameters to the encoder. Note: This interface can only be called after the encoder is started. + * At the same time, incorrect parameter settings may cause the encoding to fail. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param format OH_AVFormat handle pointer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format); + +/** + * @brief Get the input Surface from the video encoder, this interface must be called before Prepare is called. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param window A pointer to a OHNativeWindow instance, see {@link OHNativeWindow} + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_GetSurface(OH_AVCodec *codec, OHNativeWindow **window); + +/** + * @brief Return the processed output Buffer to the encoder. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param index The index value corresponding to the output Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_FreeOutputData(OH_AVCodec *codec, uint32_t index); + +/** + * @brief Notifies the video encoder that the input stream has ended. It is recommended to use this interface to notify + * the encoder of the end of the stream in surface mode + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 9 + * @version 1.0 + */ +OH_AVErrCode OH_VideoEncoder_NotifyEndOfStream(OH_AVCodec *codec); + +/** + * @brief Submit the input buffer filled with data to the video encoder. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param index Enter the index value corresponding to the Buffer + * @param attr Information describing the data contained in the Buffer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_VideoEncoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr); + +/** + * @brief Get the input data description of the encoder after call {@OH_VideoEncoder_Configure}, + * refer to {@link OH_AVFormat} for details. It should be noted that the life cycle of the OH_AVFormat + * instance pointed to by the return value needs to be manually released by the caller. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @return Returns a pointer to an OH_AVFormat instance + * @since 10 + */ +OH_AVFormat *OH_VideoEncoder_GetInputDescription(OH_AVCodec *codec); + +/** + * @brief Check whether the current codec instance is valid. It can be used fault recovery or app + * switchback from the background + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @param codec Pointer to an OH_AVCodec instance + * @param isValid Output Parameter. A pointer to a boolean instance, it is true if the codec instance is valid, + * false if the codec instance is invalid + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_VideoEncoder_IsValid(OH_AVCodec *codec, bool *isValid); + +/** + * @brief The bitrate mode of video encoder. + * @syscap SystemCapability.Multimedia.Media.VideoEncoder + * @since 9 + * @version 1.0 + */ +typedef enum OH_VideoEncodeBitrateMode { + /* constant bit rate mode. */ + CBR = 0, + /* variable bit rate mode. */ + VBR = 1, + /* constant quality mode. */ + CQ = 2, +} OH_VideoEncodeBitrateMode; + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVCODEC_VIDEOENCODER_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avdemuxer.h b/multimedia/av_codec/native_avdemuxer.h new file mode 100644 index 000000000..cdcff0914 --- /dev/null +++ b/multimedia/av_codec/native_avdemuxer.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVDEMUXER_H +#define NATIVE_AVDEMUXER_H + +#include +#include "native_avcodec_base.h" +#include "native_averrors.h" +#include "native_avmemory.h" +#include "native_avsource.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_AVDemuxer OH_AVDemuxer; + +/** + * @brief Creates an OH_AVDemuxer instance for getting samples from source. + * Free the resources of the instance by calling OH_AVDemuxer_Destroy. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param source Pointer to an OH_AVSource instance. + * @return Returns a pointer to an OH_AVDemuxer instance + * @since 10 +*/ +OH_AVDemuxer *OH_AVDemuxer_CreateWithSource(OH_AVSource *source); + +/** + * @brief Destroy the OH_AVDemuxer instance and free the internal resources. + * The same instance can only be destroyed once. The destroyed instance + * should not be used before it is created again. It is recommended setting + * the instance pointer to NULL right after the instance is destroyed successfully. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param demuxer Pointer to an OH_AVDemuxer instance. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVErrCode OH_AVDemuxer_Destroy(OH_AVDemuxer *demuxer); + +/** + * @brief The specified track is selected and the demuxer will read samples from + * this track. Multiple tracks are selected by calling this interface multiple times + * with different track indexes. Only the selected tracks are valid when calling + * OH_AVDemuxer_ReadSample to read samples. The interface returns AV_ERR_OK and the + * track is selected only once if the same track is selected multiple times. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param demuxer Pointer to an OH_AVDemuxer instance. + * @param trackIndex The index of the selected track. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVErrCode OH_AVDemuxer_SelectTrackByID(OH_AVDemuxer *demuxer, uint32_t trackIndex); + +/** + * @brief The specified selected track is unselected. The unselected track's sample + * can not be read from demuxer. Multiple selected tracks are unselected by calling + * this interface multiple times with different track indexes. The interface returns + * AV_ERR_OK and the track is unselected only once if the same track is unselected + * multiple times. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param demuxer Pointer to an OH_AVDemuxer instance. + * @param trackIndex The index of the unselected track. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVErrCode OH_AVDemuxer_UnselectTrackByID(OH_AVDemuxer *demuxer, uint32_t trackIndex); + +/** + * @brief Get the current encoded sample and sample-related information from the specified + * track. The track index must be selected before reading sample. The demuxer will advance + * automatically after calling this interface. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param demuxer Pointer to an OH_AVDemuxer instance. + * @param trackIndex The index of the track from which read an encoded sample. + * @param sample The OH_AVMemory handle pointer to the buffer storing the sample data. + * @param info The OH_AVCodecBufferAttr handle pointer to the buffer storing sample information. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVErrCode OH_AVDemuxer_ReadSample(OH_AVDemuxer *demuxer, uint32_t trackIndex, + OH_AVMemory *sample, OH_AVCodecBufferAttr *info); + +/** + * @brief All selected tracks seek near to the requested time according to the seek mode. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param demuxer Pointer to an OH_AVDemuxer instance. + * @param millisecond The millisecond for seeking, the timestamp is the position of + * the file relative to the start of the file. + * @param mode The mode for seeking. See {@link OH_AVSeekMode}. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVErrCode OH_AVDemuxer_SeekToTime(OH_AVDemuxer *demuxer, int64_t millisecond, OH_AVSeekMode mode); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVDEMUXER_H diff --git a/multimedia/av_codec/native_averrors.h b/multimedia/av_codec/native_averrors.h new file mode 100644 index 000000000..fe02f4aee --- /dev/null +++ b/multimedia/av_codec/native_averrors.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ +#ifndef NATIVE_AVERRORS_H +#define NATIVE_AVERRORS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief AV error code + * @syscap SystemCapability.Multimedia.Media.Core + * @since 9 + * @version 1.0 + */ +typedef enum OH_AVErrCode { + /** + * the operation completed successfully. + */ + AV_ERR_OK = 0, + /** + * no memory. + */ + AV_ERR_NO_MEMORY = 1, + /** + * opertation not be permitted. + */ + AV_ERR_OPERATE_NOT_PERMIT = 2, + /** + * invalid argument. + */ + AV_ERR_INVALID_VAL = 3, + /** + * IO error. + */ + AV_ERR_IO = 4, + /** + * network timeout. + */ + AV_ERR_TIMEOUT = 5, + /** + * unknown error. + */ + AV_ERR_UNKNOWN = 6, + /** + * media service died. + */ + AV_ERR_SERVICE_DIED = 7, + /** + * the state is not support this operation. + */ + AV_ERR_INVALID_STATE = 8, + /** + * unsupport interface. + */ + AV_ERR_UNSUPPORT = 9, + /** + * extend err start. + */ + AV_ERR_EXTEND_START = 100, +} OH_AVErrCode; + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVERRORS_H diff --git a/multimedia/av_codec/native_avformat.h b/multimedia/av_codec/native_avformat.h new file mode 100644 index 000000000..4335cee33 --- /dev/null +++ b/multimedia/av_codec/native_avformat.h @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVFORMAT_H +#define NATIVE_AVFORMAT_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_AVFormat OH_AVFormat; + +/** + * @brief Enumerates AVPixel Format. + * @syscap SystemCapability.Multimedia.Media.Core + * @since 9 + * @version 1.0 + */ +typedef enum OH_AVPixelFormat { + /** + * yuv 420 planar. + */ + AV_PIXEL_FORMAT_YUVI420 = 1, + /** + * NV12. yuv 420 semiplanar. + */ + AV_PIXEL_FORMAT_NV12 = 2, + /** + * NV21. yvu 420 semiplanar. + */ + AV_PIXEL_FORMAT_NV21 = 3, + /** + * format from surface. + */ + AV_PIXEL_FORMAT_SURFACE_FORMAT = 4, + /** + * RGBA8888 + */ + AV_PIXEL_FORMAT_RGBA = 5, +} OH_AVPixelFormat; + +/** + * @briefCreate an OH_AVFormat handle pointer to read and write data + * @syscap SystemCapability.Multimedia.Media.Core + * @return Returns a pointer to an OH_AVFormat instance + * @since 9 + * @version 1.0 + */ +struct OH_AVFormat *OH_AVFormat_Create(void); + +/** + * @briefCreate an audio OH_AVFormat handle pointer to read and write data + * @syscap SystemCapability.Multimedia.Media.Core + * @param mimeType mime type + * @param sampleRate sample rate + * @param channelCount channel count + * @return Returns a pointer to an OH_AVFormat instance + * @since 10 + * @version 1.0 + */ +struct OH_AVFormat *OH_AVFormat_CreateAudioFormat(const char *mimeType, + int32_t sampleRate, + int32_t channelCount); + +/** + * @briefCreate an video OH_AVFormat handle pointer to read and write data + * @syscap SystemCapability.Multimedia.Media.Core + * @param mimeType mime type + * @param width width + * @param height height + * @return Returns a pointer to an OH_AVFormat instance + * @since 10 + * @version 1.0 + */ +struct OH_AVFormat *OH_AVFormat_CreateVideoFormat(const char *mimeType, + int32_t width, + int32_t height); + +/** + * @brief Destroy the specified OH_AVFormat handle resource + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @return void + * @since 9 + * @version 1.0 + */ +void OH_AVFormat_Destroy(struct OH_AVFormat *format); + +/** + * @brief Copy OH_AVFormat handle resource + * @syscap SystemCapability.Multimedia.Media.Core + * @param to OH_AVFormat handle pointer to receive data + * @param from pointer to the OH_AVFormat handle of the copied data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_Copy(struct OH_AVFormat *to, struct OH_AVFormat *from); + +/** + * @brief Write Int data to OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key key to write data + * @param value written data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_SetIntValue(struct OH_AVFormat *format, const char *key, int32_t value); + +/** + * @brief Write Long data to OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key key to write data + * @param value written data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_SetLongValue(struct OH_AVFormat *format, const char *key, int64_t value); + +/** + * @brief Write Float data to OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key key to write data + * @param value written data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_SetFloatValue(struct OH_AVFormat *format, const char *key, float value); + +/** + * @brief Write Double data to OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key key to write data + * @param value written data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_SetDoubleValue(struct OH_AVFormat *format, const char *key, double value); + +/** + * @brief Write String data to OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key key to write data + * @param value written data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_SetStringValue(struct OH_AVFormat *format, const char *key, const char *value); + +/** + * @brief Write a block of data of a specified length to OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key key to write data + * @param addr written data addr + * @param size written data length + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_SetBuffer(struct OH_AVFormat *format, const char *key, const uint8_t *addr, size_t size); + +/** + * @brief Read Int data from OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key read key value + * @param out read data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_GetIntValue(struct OH_AVFormat *format, const char *key, int32_t *out); + +/** + * @brief Read Long data from OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key read key value + * @param out read data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_GetLongValue(struct OH_AVFormat *format, const char *key, int64_t *out); + +/** + * @brief Read Float data from OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key read key value + * @param out read data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_GetFloatValue(struct OH_AVFormat *format, const char *key, float *out); + +/** + * @brief Read Double data from OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key read key value + * @param out read data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_GetDoubleValue(struct OH_AVFormat *format, const char *key, double *out); + +/** + * @brief Read String data from OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key read key value + * @param out The read string pointer, the data life cycle pointed to is updated with GetString, + * and Format is destroyed. If the caller needs to hold it for a long time, it must copy the memory + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_GetStringValue(struct OH_AVFormat *format, const char *key, const char **out); + +/** + * @brief Read a block of data of specified length from OH_AVFormat + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @param key Key value for reading and writing data + * @param addr The life cycle is held by the format, with the destruction of the format, + * if the caller needs to hold it for a long time, it must copy the memory + * @param size Length of read and write data + * @return The return value is TRUE for success, FALSE for failure + * @since 9 + * @version 1.0 + */ +bool OH_AVFormat_GetBuffer(struct OH_AVFormat *format, const char *key, uint8_t **addr, size_t *size); + +/** + * @brief Output the information contained in OH_AVFormat as a string. + * @syscap SystemCapability.Multimedia.Media.Core + * @param format pointer to an OH_AVFormat instance + * @return Returns a string consisting of key and data + * @since 9 + * @version 1.0 + */ +const char *OH_AVFormat_DumpInfo(struct OH_AVFormat *format); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVFORMAT_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avmemory.h b/multimedia/av_codec/native_avmemory.h new file mode 100644 index 000000000..a165d290a --- /dev/null +++ b/multimedia/av_codec/native_avmemory.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVMEMORY_H +#define NATIVE_AVMEMORY_H + +#include +#include "native_averrors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_AVMemory OH_AVMemory; + +/** + * @brief Create an OH_AVMemory instance + * @syscap SystemCapability.Multimedia.Media.Core + * @param size the memory's size, bytes. + * @return Returns a pointer to an OH_AVMemory instance, needs to be freed by OH_AVMemory_Destroy. + * @since 10 + */ +OH_AVMemory *OH_AVMemory_Create(int32_t size); + +/** + * @brief Get the memory's virtual address + * @syscap SystemCapability.Multimedia.Media.Core + * @param mem Encapsulate OH_AVMemory structure instance pointer + * @return the memory's virtual address if the memory is valid, otherwise nullptr. + * @since 9 + * @version 1.0 + */ +uint8_t *OH_AVMemory_GetAddr(struct OH_AVMemory *mem); + +/** + * @brief Get the memory's size + * @syscap SystemCapability.Multimedia.Media.Core + * @param mem Encapsulate OH_AVMemory structure instance pointer + * @return the memory's size if the memory is valid, otherwise -1. + * @since 9 + * @version 1.0 + */ +int32_t OH_AVMemory_GetSize(struct OH_AVMemory *mem); + +/** + * @brief Clear the internal resources of the memory and destroy the memory instance + * @syscap SystemCapability.Multimedia.Media.Core + * @param mem Encapsulate OH_AVMemory structure instance pointer + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMemory_Destroy(struct OH_AVMemory *mem); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVMEMORY_H diff --git a/multimedia/av_codec/native_avmuxer.h b/multimedia/av_codec/native_avmuxer.h new file mode 100644 index 000000000..ec7e647dc --- /dev/null +++ b/multimedia/av_codec/native_avmuxer.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVMUXER_H +#define NATIVE_AVMUXER_H + +#include +#include +#include "native_avcodec_base.h" +#include "native_averrors.h" +#include "native_avformat.h" +#include "native_avmemory.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_AVMuxer OH_AVMuxer; + +/** + * @brief Create an OH_AVMuxer instance by output file description and format. + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param fd Must be opened with read and write permission. Caller is responsible for closing fd. + * @param format The output format is {@link OH_AVOutputFormat} . + * @return Returns a pointer to an OH_AVMuxer instance, needs to be freed by OH_AVMuxer_Destroy. + * @since 10 + */ +OH_AVMuxer *OH_AVMuxer_Create(int32_t fd, OH_AVOutputFormat format); + +/** + * @brief Set the rotation for output video playback. + * Note: This interface can only be called before OH_AVMuxer_Start. + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param muxer Pointer to an OH_AVMuxer instance. + * @param rotation The supported angles are 0, 90, 180, and 270 degrees. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMuxer_SetRotation(OH_AVMuxer *muxer, int32_t rotation); + +/** + * @brief Add track format to the muxer. + * Note: This interface can only be called before OH_AVMuxer_Start. + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param muxer Pointer to an OH_AVMuxer instance + * @param trackIndex The int32_t handle pointer used to get the track index for this newly added track, + * and it should be used in the OH_AVMuxer_WriteSample. The track index is greater than or equal to 0, + * others is error index. + * @param trackFormat OH_AVFormat handle pointer contain track format + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMuxer_AddTrack(OH_AVMuxer *muxer, int32_t *trackIndex, OH_AVFormat *trackFormat); + +/** + * @brief Start the muxer. + * Note: This interface is called after OH_AVMuxer_AddTrack and before OH_AVMuxer_WriteSample. + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param muxer Pointer to an OH_AVMuxer instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMuxer_Start(OH_AVMuxer *muxer); + +/** + * @brief Write an encoded sample to the muxer. + * Note: This interface can only be called after OH_AVMuxer_Start and before OH_AVMuxer_Stop. The application needs to + * make sure that the samples are written to the right tacks. Also, it needs to make sure the samples for each track are + * written in chronological order. + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param muxer Pointer to an OH_AVMuxer instance + * @param trackIndex The track index for this sample + * @param sample The encoded or demuxer sample + * @param info The buffer information related to this sample {@link OH_AVCodecBufferAttr} + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMuxer_WriteSample(OH_AVMuxer *muxer, + uint32_t trackIndex, + OH_AVMemory *sample, + OH_AVCodecBufferAttr info); + +/** + * @brief Stop the muxer. + * Note: Once the muxer stops, it can not be restarted. + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param muxer Pointer to an OH_AVMuxer instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMuxer_Stop(OH_AVMuxer *muxer); + +/** + * @brief Clear the internal resources of the muxer and destroy the muxer instance + * @syscap SystemCapability.Multimedia.Media.Muxer + * @param muxer Pointer to an OH_AVMuxer instance + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 + */ +OH_AVErrCode OH_AVMuxer_Destroy(OH_AVMuxer *muxer); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVMUXER_H \ No newline at end of file diff --git a/multimedia/av_codec/native_avsource.h b/multimedia/av_codec/native_avsource.h new file mode 100644 index 000000000..fe6ab38dc --- /dev/null +++ b/multimedia/av_codec/native_avsource.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVSOURCE_H +#define NATIVE_AVSOURCE_H + +#include +#include "native_avcodec_base.h" +#include "native_averrors.h" +#include "native_avformat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OH_AVSource OH_AVSource; + +/** + * @brief Creates an OH_AVSource instance that models the media at the URI. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param uri An URI for a remote media resource. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVSource *OH_AVSource_CreateWithURI(char *uri); + +/** + * @brief Creates an OH_AVSource instance that models the media at the FileDescriptor. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param fd The fileDescriptor of data source. + * @param offset The offset into the file to start reading. + * @param size The file size in bytes. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVSource *OH_AVSource_CreateWithFD(int32_t fd, int64_t offset, int64_t size); + +/** + * @brief Destroy the OH_AVSource instance and free the internal resources. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param source Pointer to an OH_AVSource instance. + * @return Returns AV_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVErrCode} + * @since 10 +*/ +OH_AVErrCode OH_AVSource_Destroy(OH_AVSource *source); + +/** + * @brief Get the format info of source. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param source Pointer to an OH_AVSource instance. + * @return Returns the source's format info. + * @since 10 +*/ +OH_AVFormat *OH_AVSource_GetSourceFormat(OH_AVSource *source); + +/** + * @brief Get the format info of track. + * @syscap SystemCapability.Multimedia.Media.Spliter + * @param source Pointer to an OH_AVSource instance. + * @param trackIndex The track index to get format. + * @return Returns the track's format info. + * @since 10 +*/ +OH_AVFormat *OH_AVSource_GetTrackFormat(OH_AVSource *source, uint32_t trackIndex); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVSOURCE_H \ No newline at end of file diff --git a/multimedia/av_codec/video_decoder/BUILD.gn b/multimedia/av_codec/video_decoder/BUILD.gn new file mode 100644 index 000000000..155f161c3 --- /dev/null +++ b/multimedia/av_codec/video_decoder/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_vdec_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = + [ "$av_codec_root_dir/interfaces/kits/c/native_avcodec_videodecoder.h" ] +} + +ohos_ndk_library("libnative_media_vdec") { + ndk_description_file = "./libnative_media_vdec.ndk.json" + min_compact_version = "1" + output_name = "native_media_vdec" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.VideoDecoder" + system_capability_headers = + [ "multimedia/player_framework/native_avcodec_videodecoder.h" ] +} diff --git a/multimedia/av_codec/video_decoder/libnative_media_vdec.ndk.json b/multimedia/av_codec/video_decoder/libnative_media_vdec.ndk.json new file mode 100644 index 000000000..7e6fd7d7a --- /dev/null +++ b/multimedia/av_codec/video_decoder/libnative_media_vdec.ndk.json @@ -0,0 +1,19 @@ +[ + { "name": "OH_VideoDecoder_CreateByMime" }, + { "name": "OH_VideoDecoder_CreateByName" }, + { "name": "OH_VideoDecoder_Destroy" }, + { "name": "OH_VideoDecoder_SetCallback" }, + { "name": "OH_VideoDecoder_SetSurface" }, + { "name": "OH_VideoDecoder_Configure" }, + { "name": "OH_VideoDecoder_Prepare" }, + { "name": "OH_VideoDecoder_Start" }, + { "name": "OH_VideoDecoder_Stop" }, + { "name": "OH_VideoDecoder_Flush" }, + { "name": "OH_VideoDecoder_Reset" }, + { "name": "OH_VideoDecoder_GetOutputDescription" }, + { "name": "OH_VideoDecoder_SetParameter" }, + { "name": "OH_VideoDecoder_PushInputData" }, + { "name": "OH_VideoDecoder_RenderOutputData" }, + { "name": "OH_VideoDecoder_FreeOutputData" }, + { "name": "OH_VideoDecoder_IsValid" } +] diff --git a/multimedia/av_codec/video_encoder/BUILD.gn b/multimedia/av_codec/video_encoder/BUILD.gn new file mode 100644 index 000000000..9e38f860f --- /dev/null +++ b/multimedia/av_codec/video_encoder/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/av_codec/config.gni") +ohos_ndk_headers("native_media_venc_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = + [ "$av_codec_root_dir/interfaces/kits/c/native_avcodec_videoencoder.h" ] +} + +ohos_ndk_library("libnative_media_venc") { + ndk_description_file = "./libnative_media_venc.ndk.json" + min_compact_version = "1" + output_name = "native_media_venc" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.VideoEncoder" + system_capability_headers = + [ "multimedia/player_framework/native_avcodec_videoencoder.h" ] +} diff --git a/multimedia/av_codec/video_encoder/libnative_media_venc.ndk.json b/multimedia/av_codec/video_encoder/libnative_media_venc.ndk.json new file mode 100644 index 000000000..28febaa45 --- /dev/null +++ b/multimedia/av_codec/video_encoder/libnative_media_venc.ndk.json @@ -0,0 +1,20 @@ +[ + { "name": "OH_VideoEncoder_CreateByMime" }, + { "name": "OH_VideoEncoder_CreateByName" }, + { "name": "OH_VideoEncoder_Destroy" }, + { "name": "OH_VideoEncoder_SetCallback" }, + { "name": "OH_VideoEncoder_Configure" }, + { "name": "OH_VideoEncoder_Prepare" }, + { "name": "OH_VideoEncoder_Start" }, + { "name": "OH_VideoEncoder_Stop" }, + { "name": "OH_VideoEncoder_Flush" }, + { "name": "OH_VideoEncoder_Reset" }, + { "name": "OH_VideoEncoder_GetOutputDescription" }, + { "name": "OH_VideoEncoder_SetParameter" }, + { "name": "OH_VideoEncoder_GetSurface" }, + { "name": "OH_VideoEncoder_FreeOutputData" }, + { "name": "OH_VideoEncoder_NotifyEndOfStream" }, + { "name": "OH_VideoEncoder_PushInputData" }, + { "name": "OH_VideoEncoder_GetInputDescription" }, + { "name": "OH_VideoEncoder_IsValid" } +] diff --git a/multimedia/image_framework/BUILD.gn b/multimedia/image_framework/BUILD.gn new file mode 100644 index 000000000..833b5fb73 --- /dev/null +++ b/multimedia/image_framework/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libpixelmap_ndk") { + ndk_description_file = "./libimage_pixelmap_napi.ndk.json" + min_compact_version = "1" + output_name = "pixelmap_ndk" +} + +ohos_ndk_headers("image_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" + sources = [ + "./include/image_pixel_map_mdk.h", + "./include/image_pixel_map_napi.h", + ] +} + +ohos_ndk_library("libimage_ndk") { + ndk_description_file = "./libimage_ndk.ndk.json" + min_compact_version = "1" + output_name = "image_ndk" +} + +ohos_ndk_headers("image_ndk_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" + sources = [ + "./include/image_mdk.h", + "./include/image_mdk_common.h", + ] +} + +ohos_ndk_library("libimage_receiver_ndk") { + ndk_description_file = "./libimage_receiver_ndk.ndk.json" + min_compact_version = "1" + output_name = "image_receiver_ndk" +} + +ohos_ndk_headers("image_receiver_ndk_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" + sources = [ "./include/image_receiver_mdk.h" ] +} + +ohos_ndk_library("libimage_source_ndk") { + ndk_description_file = "./libimage_source_ndk.ndk.json" + min_compact_version = "1" + output_name = "image_source_ndk" +} + +ohos_ndk_headers("image_source_ndk_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" + sources = [ "./include/image_source_mdk.h" ] +} diff --git a/multimedia/image_framework/include/image_mdk.h b/multimedia/image_framework/include/image_mdk.h new file mode 100644 index 000000000..cb1aa629a --- /dev/null +++ b/multimedia/image_framework/include/image_mdk.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup image + * @{ + * + * @brief Provides APIs for access to the image interface. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 2.0 + */ + +/** + * @file image_mdk.h + * + * @brief Declares functions that access the image rectangle, size, format, and component data. + * Need link libimagendk.z.so + * + * @since 10 + * @version 2.0 + */ + +#ifndef INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_MDK_H_ +#define INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_MDK_H_ +#include "napi/native_api.h" +#include "image_mdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ImageNative_; + +/** + * @brief Defines an image object at the native layer for the image interface. + * + * @since 10 + * @version 2.0 + */ +typedef struct ImageNative_ ImageNative; + +/** + * @brief Enumerates the image formats. + * + * @since 10 + * @version 2.0 + */ +enum { + /** YCbCr422 semi-planar format. */ + OHOS_IMAGE_FORMAT_YCBCR_422_SP = 1000, + /** JPEG encoding format. */ + OHOS_IMAGE_FORMAT_JPEG = 2000 +}; + +/** + * @brief Enumerates the image components. + * + * @since 10 + * @version 2.0 + */ +enum { + /** Luminance component. */ + OHOS_IMAGE_COMPONENT_FORMAT_YUV_Y = 1, + /** Chrominance component - blue projection. */ + OHOS_IMAGE_COMPONENT_FORMAT_YUV_U = 2, + /** Chrominance component - red projection. */ + OHOS_IMAGE_COMPONENT_FORMAT_YUV_V = 3, + /** JPEG format. */ + OHOS_IMAGE_COMPONENT_FORMAT_JPEG = 4, +}; + +/** + * @brief Defines the information about an image rectangle. + * + * @since 10 + * @version 2.0 + */ +struct OhosImageRect { + /** X coordinate of the rectangle. */ + int32_t x; + /** Y coordinate of the rectangle. */ + int32_t y; + /** Width of the rectangle, in pixels. */ + int32_t width; + /** Height of the rectangle, in pixels. */ + int32_t height; +}; + +/** + * @brief Defines the image composition information. + * + * @since 10 + * @version 2.0 + */ +struct OhosImageComponent { + /** Buffer that stores the pixel data. */ + uint8_t* byteBuffer; + /** Size of the pixel data in the memory. */ + size_t size; + /** Type of the pixel data. */ + int32_t componentType; + /** Row stride of the pixel data. */ + int32_t rowStride; + /** Pixel stride of the pixel data */ + int32_t pixelStride; +}; + +/** + * @brief Parses an {@link ImageNative} object at the native layer from a JavaScript native API image object. + * + * @param env Indicates the pointer to the Java Native Interface (JNI) environment. + * @param source Indicates a JavaScript native API image object. + * @return Returns an {@link ImageNative} pointer object if the operation is successful + * returns a null pointer otherwise. + * @see ImageNative, OH_Image_Release + * @since 10 + * @version 2.0 + */ +ImageNative* OH_Image_InitImageNative(napi_env env, napi_value source); + +/** + * @brief Obtains {@link OhosImageRect} of an {@link ImageNative} at the native layer. + * + * @param native Indicates the pointer to an {@link ImageNative} object at the native layer. + * @param rect Indicates the pointer to the {@link OhosImageRect} object obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * @see ImageNative, OhosImageRect + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_ClipRect(const ImageNative* native, struct OhosImageRect* rect); + +/** + * @brief Obtains {@link OhosImageSize} of an {@link ImageNative} object at the native layer. + * + * @param native Indicates the pointer to an {@link ImageNative} object at the native layer. + * @param size Indicates the pointer to the {@link OhosImageSize} object obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * @see ImageNative, OhosImageSize + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Size(const ImageNative* native, struct OhosImageSize* size); + +/** + * @brief Obtains the image format of an {@link ImageNative} object at the native layer. + * + * @param native Indicates the pointer to an {@link ImageNative} object at the native layer. + * @param format Indicates the pointer to the image format obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * @see ImageNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Format(const ImageNative* native, int32_t* format); + +/** + * @brief Obtains {@link OhosImageComponent} of an {@link ImageNative} object at the native layer. + * + * @param native Indicates the pointer to an {@link ImageNative} object at the native layer. + * @param componentType Indicates the type of the required component. + * @param componentNative Indicates the pointer to the {@link OhosImageComponent} object obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * @see ImageNative, OhosImageComponent + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_GetComponent(const ImageNative* native, + int32_t componentType, struct OhosImageComponent* componentNative); + +/** + * @brief Releases an {@link ImageNative} object at the native layer. + * Note: This API is not used to release a JavaScript native API Image object. + * It is used to release the object {@link ImageNative} at the native layer + * parsed by calling {@link OH_Image_InitImageNative}. + * + * @param native Indicates the pointer to an {@link ImageNative} object at the native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * @see ImageNative, OH_Image_InitImageNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Release(ImageNative* native); +#ifdef __cplusplus +}; +#endif +/** @} */ +#endif // INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_MDK_H_ diff --git a/multimedia/image_framework/include/image_mdk_common.h b/multimedia/image_framework/include/image_mdk_common.h new file mode 100644 index 000000000..65fe60885 --- /dev/null +++ b/multimedia/image_framework/include/image_mdk_common.h @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup image + * @{ + * + * @brief Provides APIs for access to the image interface. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 2.0 + */ + +/** + * @file image_mdk_common.h + * + * @brief Declares the common enums and structs used by the image interface. + * + * @since 10 + * @version 2.0 + */ + +#ifndef INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_COMMON_H_ +#define INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_COMMON_H_ +#include + +#ifdef __cplusplus +extern "C" { +#endif +#define IMAGE_RESULT_BASE 62980096 +/** + * @brief Enumerates the return values that may be used by the interface. + * + * @since 10 + * @version 2.0 + */ +typedef enum { + IMAGE_RESULT_SUCCESS = 0, // Operation success + IMAGE_RESULT_BAD_PARAMETER = -1, // Invalid parameter + IMAGE_RESULT_IMAGE_RESULT_BASE = IMAGE_RESULT_BASE, // Operation failed + IMAGE_RESULT_ERR_IPC = IMAGE_RESULT_BASE + 1, // ipc error + IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST = IMAGE_RESULT_BASE + 2, // sharememory error + IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL = IMAGE_RESULT_BASE + 3, // sharememory data abnormal + IMAGE_RESULT_DECODE_ABNORMAL = IMAGE_RESULT_BASE + 4, // image decode error + IMAGE_RESULT_DATA_ABNORMAL = IMAGE_RESULT_BASE + 5, // image input data error + IMAGE_RESULT_MALLOC_ABNORMAL = IMAGE_RESULT_BASE + 6, // image malloc error + IMAGE_RESULT_DATA_UNSUPPORT = IMAGE_RESULT_BASE + 7, // image type unsupported + IMAGE_RESULT_INIT_ABNORMAL = IMAGE_RESULT_BASE + 8, // image init error + IMAGE_RESULT_GET_DATA_ABNORMAL = IMAGE_RESULT_BASE + 9, // image get data error + IMAGE_RESULT_TOO_LARGE = IMAGE_RESULT_BASE + 10, // image data too large + IMAGE_RESULT_TRANSFORM = IMAGE_RESULT_BASE + 11, // image transform error + IMAGE_RESULT_COLOR_CONVERT = IMAGE_RESULT_BASE + 12, // image color convert error + IMAGE_RESULT_CROP = IMAGE_RESULT_BASE + 13, // crop error + IMAGE_RESULT_SOURCE_DATA = IMAGE_RESULT_BASE + 14, // image source data error + IMAGE_RESULT_SOURCE_DATA_INCOMPLETE = IMAGE_RESULT_BASE + 15, // image source data incomplete + IMAGE_RESULT_MISMATCHED_FORMAT = IMAGE_RESULT_BASE + 16, // image mismatched format + IMAGE_RESULT_UNKNOWN_FORMAT = IMAGE_RESULT_BASE + 17, // image unknown format + IMAGE_RESULT_SOURCE_UNRESOLVED = IMAGE_RESULT_BASE + 18, // image source unresolved + IMAGE_RESULT_INVALID_PARAMETER = IMAGE_RESULT_BASE + 19, // image invalid parameter + IMAGE_RESULT_DECODE_FAILED = IMAGE_RESULT_BASE + 20, // decode fail + IMAGE_RESULT_PLUGIN_REGISTER_FAILED = IMAGE_RESULT_BASE + 21, // register plugin fail + IMAGE_RESULT_PLUGIN_CREATE_FAILED = IMAGE_RESULT_BASE + 22, // create plugin fail + IMAGE_RESULT_ENCODE_FAILED = IMAGE_RESULT_BASE + 23, // image encode fail + IMAGE_RESULT_ADD_PIXEL_MAP_FAILED = IMAGE_RESULT_BASE + 24, // image add pixel map fail + IMAGE_RESULT_HW_DECODE_UNSUPPORT = IMAGE_RESULT_BASE + 25, // image hardware decode unsupported + IMAGE_RESULT_DECODE_HEAD_ABNORMAL = IMAGE_RESULT_BASE + 26, // image decode head error + IMAGE_RESULT_DECODE_EXIF_UNSUPPORT = IMAGE_RESULT_BASE + 27, // image decode exif unsupport + IMAGE_RESULT_PROPERTY_NOT_EXIST = IMAGE_RESULT_BASE + 28, // image property not exist + + IMAGE_RESULT_MEDIA_DATA_UNSUPPORT = IMAGE_RESULT_BASE + 30, // media type unsupported + IMAGE_RESULT_MEDIA_TOO_LARGE = IMAGE_RESULT_BASE + 31, // media data too large + IMAGE_RESULT_MEDIA_MALLOC_FAILED = IMAGE_RESULT_BASE + 32, // media malloc memory failed + IMAGE_RESULT_MEDIA_END_OF_STREAM = IMAGE_RESULT_BASE + 33, // media end of stream error + IMAGE_RESULT_MEDIA_IO_ABNORMAL = IMAGE_RESULT_BASE + 34, // media io error + IMAGE_RESULT_MEDIA_MALFORMED = IMAGE_RESULT_BASE + 35, // media malformed error + IMAGE_RESULT_MEDIA_BUFFER_TOO_SMALL = IMAGE_RESULT_BASE + 36, // media buffer too small error + IMAGE_RESULT_MEDIA_OUT_OF_RANGE = IMAGE_RESULT_BASE + 37, // media out of range error + IMAGE_RESULT_MEDIA_STATUS_ABNORMAL = IMAGE_RESULT_BASE + 38, // media status abnormal error + IMAGE_RESULT_MEDIA_VALUE_INVALID = IMAGE_RESULT_BASE + 39, // media value invalid + IMAGE_RESULT_MEDIA_NULL_POINTER = IMAGE_RESULT_BASE + 40, // media error operation + IMAGE_RESULT_MEDIA_INVALID_OPERATION = IMAGE_RESULT_BASE + 41, // media invalid operation + IMAGE_RESULT_MEDIA_ERR_PLAYER_NOT_INIT = IMAGE_RESULT_BASE + 42, // media init error + IMAGE_RESULT_MEDIA_EARLY_PREPARE = IMAGE_RESULT_BASE + 43, // media early prepare + IMAGE_RESULT_MEDIA_SEEK_ERR = IMAGE_RESULT_BASE + 44, // media rewind error + IMAGE_RESULT_MEDIA_PERMISSION_DENIED = IMAGE_RESULT_BASE + 45, // media permission denied + IMAGE_RESULT_MEDIA_DEAD_OBJECT = IMAGE_RESULT_BASE + 46, // media dead object + IMAGE_RESULT_MEDIA_TIMED_OUT = IMAGE_RESULT_BASE + 47, // media time out + IMAGE_RESULT_MEDIA_TRACK_NOT_ALL_SUPPORTED = IMAGE_RESULT_BASE + 48, // media track subset support + IMAGE_RESULT_MEDIA_ADAPTER_INIT_FAILED = IMAGE_RESULT_BASE + 49, // media recorder adapter init failed + IMAGE_RESULT_MEDIA_WRITE_PARCEL_FAIL = IMAGE_RESULT_BASE + 50, // write parcel failed + IMAGE_RESULT_MEDIA_READ_PARCEL_FAIL = IMAGE_RESULT_BASE + 51, // read parcel failed + IMAGE_RESULT_MEDIA_NO_AVAIL_BUFFER = IMAGE_RESULT_BASE + 52, // read parcel failed + IMAGE_RESULT_MEDIA_INVALID_PARAM = IMAGE_RESULT_BASE + 53, // media function found invalid param + IMAGE_RESULT_MEDIA_CODEC_ADAPTER_NOT_EXIST = IMAGE_RESULT_BASE + 54, // media zcodec adapter not init + IMAGE_RESULT_MEDIA_CREATE_CODEC_ADAPTER_FAILED = IMAGE_RESULT_BASE + 55, // media create zcodec adapter failed + IMAGE_RESULT_MEDIA_CODEC_ADAPTER_NOT_INIT = IMAGE_RESULT_BASE + 56, // media adapter inner not init + IMAGE_RESULT_MEDIA_ZCODEC_CREATE_FAILED = IMAGE_RESULT_BASE + 57, // media adapter inner not init + IMAGE_RESULT_MEDIA_ZCODEC_NOT_EXIST = IMAGE_RESULT_BASE + 58, // media zcodec not exist + IMAGE_RESULT_MEDIA_JNI_CLASS_NOT_EXIST = IMAGE_RESULT_BASE + 59, // media jni class not found + IMAGE_RESULT_MEDIA_JNI_METHOD_NOT_EXIST = IMAGE_RESULT_BASE + 60, // media jni method not found + IMAGE_RESULT_MEDIA_JNI_NEW_OBJ_FAILED = IMAGE_RESULT_BASE + 61, // media jni obj new failed + IMAGE_RESULT_MEDIA_JNI_COMMON_ERROR = IMAGE_RESULT_BASE + 62, // media jni normal error + IMAGE_RESULT_MEDIA_DISTRIBUTE_NOT_SUPPORT = IMAGE_RESULT_BASE + 63, // media distribute not support + IMAGE_RESULT_MEDIA_SOURCE_NOT_SET = IMAGE_RESULT_BASE + 64, // media source not set + IMAGE_RESULT_MEDIA_RTSP_ADAPTER_NOT_INIT = IMAGE_RESULT_BASE + 65, // media rtsp adapter not init + IMAGE_RESULT_MEDIA_RTSP_ADAPTER_NOT_EXIST = IMAGE_RESULT_BASE + 66, // media rtsp adapter not exist + IMAGE_RESULT_MEDIA_RTSP_SURFACE_UNSUPPORT = IMAGE_RESULT_BASE + 67, // media rtsp surface not support + IMAGE_RESULT_MEDIA_RTSP_CAPTURE_NOT_INIT = IMAGE_RESULT_BASE + 68, // media rtsp capture init error + IMAGE_RESULT_MEDIA_RTSP_SOURCE_URL_INVALID = IMAGE_RESULT_BASE + 69, // media rtsp source url invalid + IMAGE_RESULT_MEDIA_RTSP_VIDEO_TRACK_NOT_FOUND = IMAGE_RESULT_BASE + 70, // media rtsp can't find video track + IMAGE_RESULT_MEDIA_RTSP_CAMERA_NUM_REACH_MAX = IMAGE_RESULT_BASE + 71, // rtsp camera num reach to max num + IMAGE_RESULT_MEDIA_SET_VOLUME = IMAGE_RESULT_BASE + 72, // media set volume error + IMAGE_RESULT_MEDIA_NUMBER_OVERFLOW = IMAGE_RESULT_BASE + 73, // media number operation overflow + IMAGE_RESULT_MEDIA_DIS_PLAYER_UNSUPPORTED = IMAGE_RESULT_BASE + 74, // media distribute player unsupporteded + IMAGE_RESULT_MEDIA_DENCODE_ICC_FAILED = IMAGE_RESULT_BASE + 75, // image dencode ICC fail + IMAGE_RESULT_MEDIA_ENCODE_ICC_FAILED = IMAGE_RESULT_BASE + 76, // image encode ICC fail + + IMAGE_RESULT_MEDIA_READ_PIXELMAP_FAILED = IMAGE_RESULT_BASE + 150, // read pixelmap failed + IMAGE_RESULT_MEDIA_WRITE_PIXELMAP_FAILED = IMAGE_RESULT_BASE + 151, // write pixelmap failed + IMAGE_RESULT_MEDIA_PIXELMAP_NOT_ALLOW_MODIFY = IMAGE_RESULT_BASE + 152, // pixelmap not allow modify + IMAGE_RESULT_MEDIA_CONFIG_FAILED = IMAGE_RESULT_BASE + 153, // config error + IMAGE_RESULT_JNI_ENV_ABNORMAL = IMAGE_RESULT_BASE + 154, // Abnormal JNI environment + IMAGE_RESULT_SURFACE_GRALLOC_BUFFER_FAILED = IMAGE_RESULT_BASE + 155, // surface gralloc buffer failed + IMAGE_RESULT_CREATE_SURFACE_FAILED = IMAGE_RESULT_BASE + 156, // create surface failed + IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED = IMAGE_RESULT_BASE + 157, // Failed to obtain parameters for surface + IMAGE_RESULT_GET_SURFACE_FAILED = IMAGE_RESULT_BASE + 158, // get sufrace failed + IMAGE_RESULT_SURFACE_ACQUIRE_BUFFER_FAILED = IMAGE_RESULT_BASE + 159, // Acquire Buffer failed + IMAGE_RESULT_SURFACE_REQUEST_BUFFER_FAILED = IMAGE_RESULT_BASE + 160, // request Buffer failed + IMAGE_RESULT_REGISTER_LISTENER_FAILED = IMAGE_RESULT_BASE + 161, // Failed to register listener + IMAGE_RESULT_REGISTER_BUFFER_FAILED = IMAGE_RESULT_BASE + 162, // Failed to register buffer + IMAGE_RESULT_FREAD_FAILED = IMAGE_RESULT_BASE + 163, // read file failed + IMAGE_RESULT_PEEK_FAILED = IMAGE_RESULT_BASE + 164, // peek file failed + IMAGE_RESULT_SEEK_FAILED = IMAGE_RESULT_BASE + 165, // seek file failed + IMAGE_RESULT_STREAM_SIZE_ERROR = IMAGE_RESULT_BASE + 166, // stream bad + IMAGE_RESULT_FILE_FD_ERROR = IMAGE_RESULT_BASE + 167, // file fd is bad + IMAGE_RESULT_FILE_DAMAGED = IMAGE_RESULT_BASE + 168, // file damaged + IMAGE_RESULT_CREATE_DECODER_FAILED = IMAGE_RESULT_BASE + 169, // create decoder failed + IMAGE_RESULT_CREATE_ENCODER_FAILED = IMAGE_RESULT_BASE + 170, // create encoder failed + IMAGE_RESULT_CHECK_FORMAT_ERROR = IMAGE_RESULT_BASE + 171, // check format failed + IMAGE_RESULT_THIRDPART_SKIA_ERROR = IMAGE_RESULT_BASE + 172, // skia error + IMAGE_RESULT_HW_DECODE_FAILED = IMAGE_RESULT_BASE + 173, // hard decode failed + IMAGE_RESULT_ALLOCATER_TYPE_ERROR = IMAGE_RESULT_BASE + 174, // hard decode failed + IMAGE_RESULT_ALPHA_TYPE_ERROR = IMAGE_RESULT_BASE + 175, // hard decode failed + IMAGE_RESULT_INDEX_INVALID = IMAGE_RESULT_BASE + 176, // invalid index + + IMAGE_RESULT_MEDIA_UNKNOWN = IMAGE_RESULT_BASE + 200, // media unknown error +} IRNdkErrCode; + +/** + * @brief Defines the image size. + * + * @since 10 + * @version 2.0 + */ +struct OhosImageSize { + /** Image width, in pixels. */ + int32_t width; + /** Image height, in pixels. */ + int32_t height; +}; + +#ifdef __cplusplus +}; +#endif +/** @} */ + +#endif // INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_COMMON_H_ \ No newline at end of file diff --git a/multimedia/image_framework/include/image_pixel_map_mdk.h b/multimedia/image_framework/include/image_pixel_map_mdk.h new file mode 100644 index 000000000..cd511ca30 --- /dev/null +++ b/multimedia/image_framework/include/image_pixel_map_mdk.h @@ -0,0 +1,615 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup image + * @{ + * + * @brief Provides APIs for obtaining pixel map data and information. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 1.0 + */ + +/** + * @file image_pixel_map_mdk.h + * + * @brief Declares the APIs that can lock, access, and unlock a pixel map. + * Need link libpixelmapndk.z.so + * + * @since 10 + * @version 1.0 + */ + +#ifndef INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_PIXEL_MAP_MDK_H_ +#define INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_PIXEL_MAP_MDK_H_ +#include +#include "napi/native_api.h" +#include "image_mdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines the native pixel map information. + * @since 10 + * @version 1.0 + */ +struct NativePixelMap_; + +/** + * @brief Defines the data type name of the native pixel map. + * @since 10 + * @version 1.0 + */ +typedef struct NativePixelMap_ NativePixelMap; + +/** + * @brief Defines the pixel map information. + * + * @since 10 + * @version 1.0 + */ +typedef struct OhosPixelMapInfos { + /** Image width, in pixels. */ + uint32_t width; + /** Image height, in pixels. */ + uint32_t height; + /** Number of bytes per row. */ + uint32_t rowSize; + /** Pixel format. */ + int32_t pixelFormat; +} OhosPixelMapInfos; + +/** + * @brief Enumerates the pixel map alpha types. + * + * @since 10 + * @version 1.0 + */ +enum { + /** + * Unknown format. + */ + OHOS_PIXEL_MAP_ALPHA_TYPE_UNKNOWN = 0, + /** + * Opaque format. + */ + OHOS_PIXEL_MAP_ALPHA_TYPE_OPAQUE = 1, + /** + * Premultiplied format. + */ + OHOS_PIXEL_MAP_ALPHA_TYPE_PREMUL = 2, + /** + * Unpremultiplied format. + */ + OHOS_PIXEL_MAP_ALPHA_TYPE_UNPREMUL = 3 +}; + +/** + * @brief Enumerates the pixel map editing types. + * + * @since 10 + * @version 1.0 + */ +enum { + /** + * Read-only. + */ + OHOS_PIXEL_MAP_READ_ONLY = 0, + /** + * Editable. + */ + OHOS_PIXEL_MAP_EDITABLE = 1, +}; + +/** + * @brief Defines the options used for creating a pixel map. + * + * @since 10 + * @version 1.0 + */ +struct OhosPixelMapCreateOps { + /** Image width, in pixels. */ + uint32_t width; + /** Image height, in pixels. */ + uint32_t height; + /** Image format. */ + int32_t pixelFormat; + /** Editing type of the image. */ + uint32_t editable; + /** Alpha type of the image. */ + uint32_t alphaType; + /** Scale mode of the image. */ + uint32_t scaleMode; +}; + +/** + * @brief Creates a PixelMap object. + * + * @param env Indicates the NAPI environment pointer. + * @param info Indicates the options for setting the PixelMap object. + * @param buf Indicates the pointer to the buffer of the image. + * @param len Indicates the image size. + * @param res Indicates the pointer to the PixelMap object at the application layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_ENCODER_FAILED - if create encoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INIT_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ENCODE_FAILED - if image add pixel map fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_UNSUPPORT - if image hardware decode unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_FAILED - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_IPC - if ipc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see CreatePixelMap + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_CreatePixelMap(napi_env env, OhosPixelMapCreateOps info, + void* buf, size_t len, napi_value* res); + +/** + * @brief Creates a PixelMap object that contains only alpha channel information. + * + * @param env Indicates the NAPI environment pointer. + * @param source Indicates the options for setting the PixelMap object. + * @param alpha Indicates the pointer to the alpha channel. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_ENCODER_FAILED - if create encoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INIT_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ENCODE_FAILED - if image add pixel map fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_UNSUPPORT - if image hardware decode unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_FAILED - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_IPC - if ipc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see CreateAlphaPixelMap + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_CreateAlphaPixelMap(napi_env env, napi_value source, napi_value* alpha); + +/** + * @brief Initializes a PixelMap object. + * + * @param env Indicates the NAPI environment pointer. + * @param source Indicates the options for setting the PixelMap object. + * @return Returns a pointer to the NativePixelMap object + * if the operation is successful; returns nullptr otherwise. + * @see InitNativePixelMap + * @since 10 + * @version 1.0 + */ +NativePixelMap* OH_PixelMap_InitNativePixelMap(napi_env env, napi_value source); + +/** + * @brief Obtains the number of bytes per row of a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param num Indicates the pointer to the number of bytes per row of the PixelMap object. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see GetBytesNumberPerRow + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_GetBytesNumberPerRow(const NativePixelMap* native, int32_t* num); + +/** + * @brief Checks whether a PixelMap object is editable. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param editable Indicates the pointer to the editing type of the PixelMap object. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see GetIsEditable + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_GetIsEditable(const NativePixelMap* native, int32_t* editable); + +/** + * @brief Checks whether a PixelMap object supports alpha channels. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param alpha Indicates the pointer to the support for alpha channels. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see IsSupportAlpha + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_IsSupportAlpha(const NativePixelMap* native, int32_t* alpha); + +/** + * @brief Sets an alpha channel for a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param alpha Indicates the alpha channel to set. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see SetAlphaAble + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_SetAlphaAble(const NativePixelMap* native, int32_t alpha); + +/** + * @brief Obtains the pixel density of a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param density Indicates the pointer to the pixel density. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see GetDensity + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_GetDensity(const NativePixelMap* native, int32_t* density); + +/** + * @brief Sets the pixel density for a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param density Indicates the pixel density to set. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see GetDensity + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_SetDensity(const NativePixelMap* native, int32_t density); + +/** + * @brief Sets the opacity for a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param opacity Indicates the opacity to set. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * @see SetOpacity + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_SetOpacity(const NativePixelMap* native, float opacity); + +/** + * @brief Scales a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param x Indicates the scaling ratio of the width. + * @param y Indicates the scaling ratio of the height. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see Scale + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_Scale(const NativePixelMap* native, float x, float y); + +/** + * @brief Translates a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param x Indicates the horizontal distance to translate. + * @param y Indicates the vertical distance to translate. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see Translate + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_Translate(const NativePixelMap* native, float x, float y); + +/** + * @brief Rotates a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param angle Indicates the angle to rotate. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see Rotate + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_Rotate(const NativePixelMap* native, float angle); + +/** + * @brief Flips a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param x Specifies whether to flip around the x axis. + * @param y Specifies whether to flip around the y axis. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see Flip + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_Flip(const NativePixelMap* native, int32_t x, int32_t y); + +/** + * @brief Crops a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param x Indicates the x-coordinate of the upper left corner of the target image. + * @param y Indicates the y-coordinate of the upper left corner of the target image. + * @param width Indicates the width of the cropped region. + * @param height Indicates the height of the cropped region. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see Crop + * @since 10 + * @version 1.0 + */ +int32_t OH_PixelMap_Crop(const NativePixelMap* native, int32_t x, int32_t y, int32_t width, int32_t height); + +/** + * @brief Obtains the image information of a PixelMap object. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param info Indicates the pointer to the image information. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see OhosPixelMapInfos + * @since 10 + * @version 2.0 + */ +int32_t OH_PixelMap_GetImageInfo(const NativePixelMap* native, OhosPixelMapInfos *info); + +/** + * @brief Obtains the memory address of a NativePixelMap object and locks the memory. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @param addr Indicates the double pointer to the memory address. + * @see UnAccessPixels + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. * @since 10 + * @version 2.0 + */ +int32_t OH_PixelMap_AccessPixels(const NativePixelMap* native, void** addr); + +/** + * @brief Unlocks the memory of the NativePixelMap object data. + * This function is used with {@link OH_PixelMap_AccessPixels} in pairs. + * + * @param native Indicates the pointer to a NativePixelMap object. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. * @see AccessPixels + * @since 10 + * @version 2.0 + */ +int32_t OH_PixelMap_UnAccessPixels(const NativePixelMap* native); + +#ifdef __cplusplus +}; +#endif +/** @} */ + +#endif // INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_PIXEL_MAP_NAPI_H_ diff --git a/multimedia/image_framework/include/image_pixel_map_napi.h b/multimedia/image_framework/include/image_pixel_map_napi.h new file mode 100644 index 000000000..4ce97331e --- /dev/null +++ b/multimedia/image_framework/include/image_pixel_map_napi.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup image + * @{ + * + * @brief Provides APIs for obtaining pixel map data and information. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 8 + * @version 1.0 + */ + +/** + * @file image_pixel_map_napi.h + * + * @brief Declares the APIs that can lock, access, and unlock a pixel map. + * + * @since 8 + * @version 1.0 + */ + +#ifndef INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_PIXEL_MAP_NAPI_H_ +#define INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_PIXEL_MAP_NAPI_H_ +#include +#include "napi/native_api.h" +namespace OHOS { +namespace Media { +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumerates the error codes returned by the functions. + * + * @deprecated since 10 + * @since 8 + * @version 1.0 + */ +enum { + /** Operation success. */ + OHOS_IMAGE_RESULT_SUCCESS = 0, + /** Invalid value. */ + OHOS_IMAGE_RESULT_BAD_PARAMETER = -1, +}; + +/** + * @brief Enumerates the pixel formats. + * + * @deprecated since 10 + * @since 8 + * @version 1.0 + */ +enum { + /** + * Unknown format. + */ + OHOS_PIXEL_MAP_FORMAT_NONE = 0, + /** + * 32-bit RGBA, with 8 bits each for R (red), G (green), B (blue), and A (alpha). + * The data is stored from the most significant bit to the least significant bit. + */ + OHOS_PIXEL_MAP_FORMAT_RGBA_8888 = 3, + /** + * 16-bit RGB, with 5, 6, and 5 bits for R, G, and B, respectively. + * The data is stored from the most significant bit to the least significant bit. + */ + OHOS_PIXEL_MAP_FORMAT_RGB_565 = 2, +}; + +/** + * @brief Defines the pixel map information. + * + * @deprecated since 10 + * @since 8 + * @version 1.0 + */ +struct OhosPixelMapInfo { + /** Image width, in pixels. */ + uint32_t width; + /** Image height, in pixels. */ + uint32_t height; + /** Number of bytes per row. */ + uint32_t rowSize; + /** Pixel format. */ + int32_t pixelFormat; +}; + +/** + * @brief Enumerates the pixel map scale modes. + * + * @since 10 + * @version 2.0 + */ +enum { + /** + * Adaptation to the target image size. + */ + OHOS_PIXEL_MAP_SCALE_MODE_FIT_TARGET_SIZE = 0, + /** + * Cropping the center portion of an image to the target size. + */ + OHOS_PIXEL_MAP_SCALE_MODE_CENTER_CROP = 1, +}; + +/** + * @brief Obtains the information about a PixelMap object + * and stores the information to the {@link OhosPixelMapInfo} struct. + * + * @deprecated since 10 + * @param env Indicates the NAPI environment pointer. + * @param value Indicates the PixelMap object at the application layer. + * @param info Indicates the pointer to the object that stores the information obtained. + * For details, see {@link OhosPixelMapInfo}. + * @return Returns 0 if the information is obtained and stored successfully; returns an error code otherwise. + * @see OhosPixelMapInfo + * @since 8 + * @version 1.0 + */ +int32_t OH_GetImageInfo(napi_env env, napi_value value, OhosPixelMapInfo *info); + +/** + * @brief Obtains the memory address of a PixelMap object and locks the memory. + * + * After the function is executed successfully, *addrPtr is the memory address to be accessed. + * After the access operation is complete, you must use {@link OH_UnAccessPixels} to unlock the memory. + * Otherwise, the resources in the memory cannot be released. + * After the memory is unlocked, its address cannot be accessed or operated. + * + * @deprecated since 10 + * @param env Indicates the NAPI environment pointer. + * @param value Indicates the PixelMap object at the application layer. + * @param addrPtr Indicates the double pointer to the memory address. + * @see UnAccessPixels + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; returns an error code otherwise. + * @since 8 + * @version 1.0 + */ +int32_t OH_AccessPixels(napi_env env, napi_value value, void** addrPtr); + +/** + * @brief Unlocks the memory of a PixelMap object. This function is used with {@link OH_AccessPixels} in pairs. + * + * @deprecated since 10 + * @param env Indicates the NAPI environment pointer. + * @param value Indicates the PixelMap object at the application layer. + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; returns an error code otherwise. + * @see AccessPixels + * @since 8 + * @version 1.0 + */ +int32_t OH_UnAccessPixels(napi_env env, napi_value value); + +#ifdef __cplusplus +}; +#endif +/** @} */ +} // namespace Media +} // namespace OHOS +#endif // INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_PIXEL_MAP_NAPI_H_ diff --git a/multimedia/image_framework/include/image_receiver_mdk.h b/multimedia/image_framework/include/image_receiver_mdk.h new file mode 100644 index 000000000..2ca87438f --- /dev/null +++ b/multimedia/image_framework/include/image_receiver_mdk.h @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup image + * @{ + * + * @brief Provides APIs for obtaining image data from the native layer. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 2.0 + */ + +/** + * @file image_receiver_mdk.h + * + * @brief Declares the APIs for obtaining image data from the native layer. + * Need link libimagendk.z.so and libimage_receiverndk.z.so + * @since 10 + * @version 2.0 + */ + +#ifndef INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_RECEIVER_MDK_H_ +#define INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_RECEIVER_MDK_H_ +#include "napi/native_api.h" +#include "image_mdk_common.h" +#include "image_mdk.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines an ImageReceiver object at the native layer. + * + * @since 10 + * @version 2.0 + */ +struct ImageReceiverNative_; + +/** + * @brief Defines the data type name of a native image receiver. + * + * @since 10 + * @version 2.0 + */ +typedef struct ImageReceiverNative_ ImageReceiverNative; + +/** + * @brief Defines the callbacks for images at the native layer. + * + * @since 10 + * @version 2.0 + */ +typedef void (*OH_Image_Receiver_On_Callback)(void); + +/** + * @brief Defines the information about an image receiver. + * + * @since 10 + * @version 2.0 + */ +struct OhosImageReceiverInfo { + /* Default width of the image received by the consumer, in pixels. */ + int32_t width; + /* Default height of the image received by the consumer, in pixels. */ + int32_t height; + /* Image format {@link OHOS_IMAGE_FORMAT_JPEG} created by using the receiver. */ + int32_t format; + /* Maximum number of images that can be cached. */ + int32_t capicity; +}; + +/** + * @brief Creates an ImageReceiver object at the application layer. + * + * @param env Indicates the NAPI environment pointer. + * @param info Indicates the options for setting the ImageReceiver object. + * @param res Indicates the pointer to the ImageReceiver object obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_SURFACE_FAILED - if create surface failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GRALLOC_BUFFER_FAILED - if surface gralloc buffer failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_SURFACE_FAILED - if get sufrace failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MEDIA_RTSP_SURFACE_UNSUPPORT - if media rtsp surface not support. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MEDIA_DATA_UNSUPPORT - if media type unsupported. + * @see OhosImageReceiverInfo + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_CreateImageReceiver(napi_env env, struct OhosImageReceiverInfo info, napi_value* res); + +/** + * @brief Initializes an {@link ImageReceiverNative} object at the native layer + * through an ImageReceiver object at the application layer. + * + * @param env Indicates the NAPI environment pointer. + * @param source Indicates an ImageReceiver object. + * @return Returns the pointer to the {@link ImageReceiverNative} object obtained if the operation is successful; + * returns a null pointer otherwise. + * @see ImageReceiverNative, OH_Image_Receiver_Release + * @since 10 + * @version 2.0 + */ +ImageReceiverNative* OH_Image_Receiver_InitImageReceiverNative(napi_env env, napi_value source); + +/** + * @brief Obtains the receiver ID through an {@link ImageReceiverNative} object. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param id Indicates the pointer to the buffer that stores the ID string obtained. + * @param len Indicates the size of the buffer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_SURFACE_FAILED - if get sufrace failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MEDIA_DATA_UNSUPPORT - if media type unsupported. + * @see ImageReceiverNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_GetReceivingSurfaceId(const ImageReceiverNative* native, char* id, size_t len); + +/** + * @brief Obtains the latest image through an {@link ImageReceiverNative} object. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param image Indicates the pointer to an Image object at the application layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_SURFACE_FAILED - if create surface failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GRALLOC_BUFFER_FAILED - if surface gralloc buffer failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_SURFACE_FAILED - if get sufrace failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MEDIA_RTSP_SURFACE_UNSUPPORT - if media rtsp surface not support. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_REQUEST_BUFFER_FAILED - if request Buffer failed. + * @see ImageReceiverNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_ReadLatestImage(const ImageReceiverNative* native, napi_value* image); + +/** + * @brief Obtains the next image through an {@link ImageReceiverNative} object. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param image Indicates the pointer to an Image object at the application layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GET_PARAMETER_FAILED - if Failed to obtain parameters for surface. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_SURFACE_FAILED - if create surface failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_GRALLOC_BUFFER_FAILED - if surface gralloc buffer failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_SURFACE_FAILED - if get sufrace failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MEDIA_RTSP_SURFACE_UNSUPPORT - if media rtsp surface not support. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SURFACE_REQUEST_BUFFER_FAILED - if request Buffer failed. + * @see ImageReceiverNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_ReadNextImage(const ImageReceiverNative* native, napi_value* image); + +/** + * @brief Registers an {@link OH_Image_Receiver_On_Callback} callback event. + * + * This callback event is triggered whenever a new image is received. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param callback Indicates the {@link OH_Image_Receiver_On_Callback} callback event to register. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_SURFACE_FAILED - if get sufrace failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_REGISTER_LISTENER_FAILED - if Failed to register listener. + * returns {@link IRNdkErrCode} IMAGE_RESULT_REGISTER_BUFFER_FAILED - if Failed to register buffer. + * @see ImageReceiverNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_On(const ImageReceiverNative* native, OH_Image_Receiver_On_Callback callback); + +/** + * @brief Obtains the size of the image receiver through an {@link ImageReceiverNative} object. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param size Indicates the pointer to the {@link OhosImageSize} object obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * @see ImageReceiverNative, OH_Image_Receiver_On_Callback + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_GetSize(const ImageReceiverNative* native, struct OhosImageSize* size); + +/** + * @brief Obtains the capacity of the image receiver through an {@link ImageReceiverNative} object. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param capacity Indicates the pointer to the capacity obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * @see ImageReceiverNative, OhosImageSize + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_GetCapacity(const ImageReceiverNative* native, int32_t* capacity); + +/** + * @brief Obtains the format of the image receiver through an {@link ImageReceiverNative} object. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @param format Indicates the pointer to the format obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image type unsupported. + * @see ImageReceiverNative + + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_GetFormat(const ImageReceiverNative* native, int32_t* format); + +/** + * @brief Releases an {@link ImageReceiverNative} object at the native layer. + * + * This API is not used to release an ImageReceiver object at the application layer. + * + * @param native Indicates the pointer to an {@link ImageReceiverNative} object at the native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * @see ImageReceiverNative + * @since 10 + * @version 2.0 + */ +int32_t OH_Image_Receiver_Release(ImageReceiverNative* native); +#ifdef __cplusplus +}; +#endif +/** @} */ + +#endif // INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_RECEIVER_MDK_H_ diff --git a/multimedia/image_framework/include/image_source_mdk.h b/multimedia/image_framework/include/image_source_mdk.h new file mode 100644 index 000000000..3f40a28eb --- /dev/null +++ b/multimedia/image_framework/include/image_source_mdk.h @@ -0,0 +1,827 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup image + * @{ + * + * @brief Provides native APIs for image sources. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ + +/** + * @file image_source_mdk.h + * + * @brief Declares APIs for decoding an image source into a pixel map. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ + +#ifndef INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_SOURCE_MDK_H_ +#define INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_SOURCE_MDK_H_ +#include +#include "napi/native_api.h" +#include "image_mdk_common.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Defines a native image source object for the image source APIs. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct ImageSourceNative_; + +/** + * @brief Defines a native image source object for the image source APIs. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +typedef struct ImageSourceNative_ ImageSourceNative; + +/** + * @brief Defines a pointer to bits per sample, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_BITS_PER_SAMPLE = "BitsPerSample"; + +/** + * @brief Defines a pointer to the orientation, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_ORIENTATION = "Orientation"; + +/** + * @brief Defines a pointer to the image length, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_IMAGE_LENGTH = "ImageLength"; + +/** + * @brief Defines a pointer to the image width, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_IMAGE_WIDTH = "ImageWidth"; + +/** + * @brief Defines a pointer to the GPS latitude, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_GPS_LATITUDE = "GPSLatitude"; + +/** + * @brief Defines a pointer to the GPS longitude, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_GPS_LONGITUDE = "GPSLongitude"; + +/** + * @brief Defines a pointer to the GPS latitude reference information, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_GPS_LATITUDE_REF = "GPSLatitudeRef"; + +/** + * @brief Defines a pointer to the GPS longitude reference information, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_GPS_LONGITUDE_REF = "GPSLongitudeRef"; + +/** + * @brief Defines a pointer to the created date and time, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_DATE_TIME_ORIGINAL = "DateTimeOriginal"; + +/** + * @brief Defines a pointer to the exposure time, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_EXPOSURE_TIME = "ExposureTime"; + +/** + * @brief Defines a pointer to the scene type, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_SCENE_TYPE = "SceneType"; + +/** + * @brief Defines a pointer to the ISO speed ratings, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_ISO_SPEED_RATINGS = "ISOSpeedRatings"; + +/** + * @brief Defines a pointer to the f-number of the image, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_F_NUMBER = "FNumber"; + +/** + * @brief Defines a pointer to the compressed bits per pixel, one of the image properties. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +const char* OHOS_IMAGE_PROPERTY_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel"; + +/** + * @brief Defines the region of the image source to decode. + * It is used in {@link OhosImageDecodingOps}, {@link OH_ImageSource_CreatePixelMap}, and + * {@link OH_ImageSource_CreatePixelMapList}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageRegion { + /** X coordinate of the start point, in pixels. */ + int32_t x; + /** Y coordinate of the start point, in pixels. */ + int32_t y; + /** Width of the region, in pixels. */ + int32_t width; + /** Height of the region, in pixels. */ + int32_t height; +}; + +/** + * @brief Defines image source options infomation + * {@link OH_ImageSource_Create} and {@link OH_ImageSource_CreateIncremental}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceOps { + /** Pixel density of the image source. */ + int32_t density; + /** Image source pixel format, used to describe YUV buffer usually. */ + int32_t pixelFormat; + /** Image source pixel size of width and height. */ + struct OhosImageSize size; +}; + +/** + * @brief Defines the options for decoding the image source. + * It is used in {@link OH_ImageSource_CreatePixelMap} and {@link OH_ImageSource_CreatePixelMapList}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageDecodingOps { + /** Defines output pixel map editable. */ + int8_t editable; + /** Defines output pixel format. */ + int32_t pixelFormat; + /** Defines decoding target pixel density. */ + int32_t fitDensity; + /** Defines decoding index of image source. */ + uint32_t index; + /** Defines decoding sample size option. */ + uint32_t sampleSize; + /** Defines decoding rotate option. */ + uint32_t rotate; + /** Defines decoding target pixel size of width and height. */ + struct OhosImageSize size; + /** Defines image source pixel region for decoding. */ + struct OhosImageRegion region; +}; + +/** + * @brief Defines the image source information, which is obtained by calling {@link OH_ImageSource_GetImageInfo}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceInfo { + /** Pixel format of the image source. It is set in {@link OH_ImageSource_Create}. */ + int32_t pixelFormat; + /** Color space of the image source. */ + int32_t colorSpace; + /** Alpha type of the image source. */ + int32_t alphaType; + /** Image density of the image source. It is set in {@link OH_ImageSource_Create}. */ + int32_t density; + /** Pixel width and height of the image source. */ + struct OhosImageSize size; +}; + +/** + * @brief Defines the input resource of the image source. It is obtained by calling {@link OH_ImageSource_Create}. + * Only one type of resource is accepted at a time. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSource { + /** Pointer to the image source URI. Only a file URI or Base64 URI is accepted. */ + char* uri = nullptr; + /** Length of the image source URI. */ + size_t uriSize = 0; + /** Descriptor of the image source. */ + int32_t fd = -1; + /** Pointer to the image source buffer. Only a formatted packet buffer or Base64 buffer is accepted. */ + uint8_t* buffer = nullptr; + /** Size of the image source buffer. */ + size_t bufferSize = 0; +}; + +/** + * @brief Defines the delay time list of the image source. It is obtained by calling + * {@link OH_ImageSource_GetDelayTime}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceDelayTimeList { + /** Pointer to the head of the image source delay time list. */ + int32_t* delayTimeList; + /** Size of the image source delay time list. */ + size_t size = 0; +}; + +/** + * @brief Defines image source supported format string. + * {@link OhosImageSourceSupportedFormatList} and {@link OH_ImageSource_GetSupportedFormats} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceSupportedFormat { + /** Image source supported format string head.*/ + char* format = nullptr; + /** Image source supported format string size.*/ + size_t size = 0; +}; + +/** + * @brief Defines the format string list supported by the image source. + * It is obtained by calling {@link OH_ImageSource_GetSupportedFormats}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceSupportedFormatList { + /** Image source supported format string list head.*/ + struct OhosImageSourceSupportedFormat** supportedFormatList = nullptr; + /** Image source supported format string list size.*/ + size_t size = 0; +}; + +/** + * @brief Defines the property string (in key-value format) of the image source. + * It is used in {@link OH_ImageSource_GetImageProperty} and {@link OH_ImageSource_ModifyImageProperty}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceProperty { + /** Image source property key and value string head.*/ + char* value = nullptr; + /** Image source property key and value string size.*/ + size_t size = 0; +}; + +/** + * @brief Defines the update data of the image source. It is obtained by calling {@link OH_ImageSource_UpdateData}. + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +struct OhosImageSourceUpdateData { + /** Image source update data buffer.*/ + uint8_t* buffer = nullptr; + /** Image source update data buffer size.*/ + size_t bufferSize = 0; + /** Image source offset of update data buffer.*/ + uint32_t offset = 0; + /** Image source update data length in update data buffer.*/ + uint32_t updateLength = 0; + /** Image source update data is completed in this session.*/ + int8_t isCompleted = 0; +}; + +/** + * @brief Creates an ImageSource object at the JavaScript native layer based on the specified + * {@link OhosImageSource} and {@link OhosImageSourceOps} structs. + * + * @param env Indicates a pointer to the Java Native Interface (JNI) environment. + * @param src Indicates a pointer to the input resource of the image source. For details, see {@link OhosImageSource}. + * @param ops Indicates a pointer to the options for creating the image source. + * For details, see {@link OhosImageSourceOps}. + * @param res Indicates a pointer to the ImageSource object created at the JavaScript native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SOURCE_DATA_INCOMPLETE - if image source data incomplete. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SOURCE_DATA - if image source data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_TOO_LARGE - if image data too large. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * returns {@link IRNdkErrCode} IMAGE_RESULT_FILE_DAMAGED - if file damaged. + * returns {@link IRNdkErrCode} IMAGE_RESULT_FILE_FD_ERROR - if file fd is bad. + * returns {@link IRNdkErrCode} IMAGE_RESULT_STREAM_SIZE_ERROR - if stream bad. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SEEK_FAILED - if seek file failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PEEK_FAILED - if peek file failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_FREAD_FAILED - if read file failed. + * @see {@link OhosImageSource}, {@link OhosImageSourceOps} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_Create(napi_env env, struct OhosImageSource* src, + struct OhosImageSourceOps* ops, napi_value *res); + +/** + * @brief Creates an incremental ImageSource object at the JavaScript native layer based on the specified + * {@link OhosImageSource} and {@link OhosImageSourceOps} structs. + * The image source data will be updated through {@link OH_ImageSource_UpdateData}. + * + * @param env Indicates a pointer to the JNI environment. + * @param src Indicates a pointer to the input resource of the image source. Only the buffer type is accepted. + * For details, see {@link OhosImageSource}. + * @param ops Indicates a pointer to the options for creating the image source. + * For details, see {@link OhosImageSourceOps}. + * @param res Indicates a pointer to the ImageSource object created at the JavaScript native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SOURCE_DATA_INCOMPLETE - if image source data incomplete. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SOURCE_DATA - if image source data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_TOO_LARGE - if image data too large. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * returns {@link IRNdkErrCode} IMAGE_RESULT_FILE_DAMAGED - if file damaged. + * returns {@link IRNdkErrCode} IMAGE_RESULT_FILE_FD_ERROR - if file fd is bad. + * returns {@link IRNdkErrCode} IMAGE_RESULT_STREAM_SIZE_ERROR - if stream bad. + * returns {@link IRNdkErrCode} IMAGE_RESULT_SEEK_FAILED - if seek file failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PEEK_FAILED - if peek file failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_FREAD_FAILED - if read file failed. + * @see {@link OhosImageSource}, {@link OhosImageSourceOps}, {@link OH_ImageSource_UpdateData} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_CreateIncremental(napi_env env, struct OhosImageSource* source, + struct OhosImageSourceOps* ops, napi_value *res); + +/** + * @brief Obtains all supported decoding formats. + * + * @param res Indicates a pointer to the OhosImageSourceSupportedFormatList struct. + * When the input supportedFormatList is a null pointer and size is 0, the size of the supported formats + * is returned through size in res. + * To obtain all formats, a space larger than size is required. + * In addition, sufficient space must be reserved for each format supported. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if decode fail. + * @see {@link OhosImageSourceSupportedFormatList}, {@link OhosImageSourceSupportedFormat} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_GetSupportedFormats(struct OhosImageSourceSupportedFormatList* res); + +/** + * @brief Converts an {@link ImageSource} object at the JavaScript native layer to an ImageSourceNative object + * at the C++ native layer. + * + * @param env Indicates a pointer to the JNI environment. + * @param source Indicates a pointer to the ImageSource object at the JavaScript native layer. + * @return Returns a pointer to the {@link ImageSourceNative} object if the operation is successful; + * returns a null pointer otherwise. + * @see {@link ImageSourceNative}, {@link OH_ImageSource_Release} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +ImageSourceNative* OH_ImageSource_InitNative(napi_env env, napi_value source); + +/** + * @brief Decodes an ImageSource object to obtain a PixelMap object at the JavaScript native layer + * based on the specified {@link OhosImageDecodingOps} struct. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param ops Indicates a pointer to the options for decoding the image source. + * For details, see {@link OhosImageDecodingOps}. + * @param res Indicates a pointer to the PixelMap object obtained at the JavaScript native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_ENCODER_FAILED - if create encoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INIT_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ENCODE_FAILED - if image add pixel map fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_UNSUPPORT - if image hardware decode unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_FAILED - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_IPC - if ipc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see {@link ImageSourceNative}, {@link OhosImageDecodingOps} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_CreatePixelMap(const ImageSourceNative* native, + struct OhosImageDecodingOps* ops, napi_value *res); + +/** + * @brief Decodes an ImageSource to obtain all the PixelMap objects at the JavaScript native layer + * based on the specified {@link OhosImageDecodingOps} struct. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param ops Indicates a pointer to the options for decoding the image source. + * For details, see {@link OhosImageDecodingOps}. + * @param res Indicates a pointer to the PixelMap objects obtained at the JavaScript native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_ENCODER_FAILED - if create encoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INIT_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ENCODE_FAILED - if image add pixel map fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_UNSUPPORT - if image hardware decode unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_FAILED - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_IPC - if ipc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * @see {@link ImageSourceNative}, {@link OhosImageDecodingOps} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_CreatePixelMapList(const ImageSourceNative* native, + struct OhosImageDecodingOps* ops, napi_value *res); + +/** + * @brief Obtains the delay time list from some ImageSource objects (such as GIF image sources). + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param res Indicates a pointer to the delay time list obtained. + * For details, see {@link OhosImageSourceDelayTimeList}. When the input delayTimeList is a null pointer and + * size is 0, the size of the delay time list is returned through size in res. + * To obtain the complete delay time list, a space greater than size is required. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * @see {@link ImageSourceNative}, {@link OhosImageSourceDelayTimeList} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_GetDelayTime(const ImageSourceNative* native, + struct OhosImageSourceDelayTimeList* res); + +/** + * @brief Obtains the number of frames from an ImageSource object. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param res Indicates a pointer to the number of frames obtained. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * @see {@link ImageSourceNative} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_GetFrameCount(const ImageSourceNative* native, uint32_t *res); + +/** + * @brief Obtains image source information from an ImageSource object by index. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param index Indicates the index of the frame. + * @param info Indicates a pointer to the image source information obtained. + * For details, see {@link OhosImageSourceInfo}. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * @see {@link ImageSourceNative}, {@link OhosImageSourceInfo} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_GetImageInfo(const ImageSourceNative* native, int32_t index, + struct OhosImageSourceInfo* info); + +/** + * @brief Obtains the value of an image property from an ImageSource object. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param key Indicates a pointer to the property. For details, see {@link OhosImageSourceProperty}. + * @param value Indicates a pointer to the property value obtained. + * If the input value is a null pointer and size is 0, the size of the property value is returned + * through size in value. + * To obtain the complete property value, a space greater than size is required. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * @see {@link ImageSourceNative}, {@link OhosImageSourceProperty} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_GetImageProperty(const ImageSourceNative* native, + struct OhosImageSourceProperty* key, struct OhosImageSourceProperty* value); + +/** + * @brief Modifies the value of an image property of an ImageSource object. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param key Indicates a pointer to the property. For details, see {@link OhosImageSourceProperty}. + * @param value Indicates a pointer to the new value of the property. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_EXIF_UNSUPPORT - if image decode exif unsupport. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PROPERTY_NOT_EXIST - if image property not exist. + * @see {@link ImageSourceNative}, {@link OhosImageSourceProperty} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_ModifyImageProperty(const ImageSourceNative* native, + struct OhosImageSourceProperty* key, struct OhosImageSourceProperty* value); + +/** + * @brief Updates the data of an ImageSource object. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @param data Indicates a pointer to the update data. For details, see {@link OhosImageSourceUpdateData}. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_FAILED - if decode fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_HEAD_ABNORMAL - if image decode head error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_DECODER_FAILED - if create decoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CREATE_ENCODER_FAILED - if create encoder failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CHECK_FORMAT_ERROR - if check format failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_THIRDPART_SKIA_ERROR - if skia error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_NOT_EXIST - if sharememory error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_SHAMEM_DATA_ABNORMAL - if sharememory data abnormal. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DECODE_ABNORMAL - if image decode error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_MALLOC_ABNORMAL - if image malloc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_UNSUPPORT - if image init error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INIT_ABNORMAL - if image input data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_CROP - if crop error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_UNKNOWN_FORMAT - if image unknown format. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_REGISTER_FAILED - if register plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_PLUGIN_CREATE_FAILED - if create plugin fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ENCODE_FAILED - image add pixel map fail. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_UNSUPPORT - if image hardware decode unsupported. + * returns {@link IRNdkErrCode} IMAGE_RESULT_HW_DECODE_FAILED - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ERR_IPC - if ipc error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INDEX_INVALID - if invalid index. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALPHA_TYPE_ERROR - if hard decode failed. + * returns {@link IRNdkErrCode} IMAGE_RESULT_ALLOCATER_TYPE_ERROR - if hard decode failed. + * @see {@link ImageSourceNative}, {@link OhosImageSourceUpdateData} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_UpdateData(const ImageSourceNative* native, struct OhosImageSourceUpdateData* data); + + +/** + * @brief Releases an ImageSourceNative object. + * + * @param native Indicates a pointer to the {@link ImageSourceNative} object at the C++ native layer. + * @return Returns {@link IRNdkErrCode} IMAGE_RESULT_SUCCESS - if the operation is successful. + * returns {@link IRNdkErrCode} IMAGE_RESULT_BAD_PARAMETER - if bad parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_JNI_ENV_ABNORMAL - if Abnormal JNI environment. + * returns {@link IRNdkErrCode} IMAGE_RESULT_INVALID_PARAMETER - if invalid parameter. + * returns {@link IRNdkErrCode} IMAGE_RESULT_GET_DATA_ABNORMAL - if image get data error. + * returns {@link IRNdkErrCode} IMAGE_RESULT_DATA_ABNORMAL - if image input data error. + * @see {@link ImageSourceNative}, {@link OH_ImageSource_Create}, {@link OH_ImageSource_CreateIncremental} + * + * @Syscap SystemCapability.Multimedia.Image + * @since 10 + * @version 4.0 + */ +int32_t OH_ImageSource_Release(ImageSourceNative* native); +#ifdef __cplusplus +}; +#endif +#endif // INTERFACES_KITS_NATIVE_INCLUDE_IMAGE_SOURCE_MDK_H_ diff --git a/multimedia/image_framework/libimage_ndk.ndk.json b/multimedia/image_framework/libimage_ndk.ndk.json new file mode 100644 index 000000000..b7bba91e2 --- /dev/null +++ b/multimedia/image_framework/libimage_ndk.ndk.json @@ -0,0 +1,21 @@ +[ + { + "first_introduced": "1", + "name": "OH_Image_InitImageNative" + }, + { + "name": "OH_Image_ClipRect" + }, + { + "name": "OH_Image_Size" + }, + { + "name": "OH_Image_Format" + }, + { + "name": "OH_Image_GetComponent" + }, + { + "name": "OH_Image_Release" + } +] \ No newline at end of file diff --git a/multimedia/image_framework/libimage_pixelmap_napi.ndk.json b/multimedia/image_framework/libimage_pixelmap_napi.ndk.json new file mode 100644 index 000000000..64800fe82 --- /dev/null +++ b/multimedia/image_framework/libimage_pixelmap_napi.ndk.json @@ -0,0 +1,66 @@ +[ + { + "first_introduced": "1", + "name": "OH_GetImageInfo" + }, + { + "name": "OH_AccessPixels" + }, + { + "name": "OH_UnAccessPixels" + }, + { + "name": "OH_PixelMap_CreatePixelMap" + }, + { + "name": "OH_PixelMap_CreateAlphaPixelMap" + }, + { + "name": "OH_PixelMap_InitNativePixelMap" + }, + { + "name": "OH_PixelMap_GetBytesNumberPerRow" + }, + { + "name": "OH_PixelMap_GetIsEditable" + }, + { + "name": "OH_PixelMap_IsSupportAlpha" + }, + { + "name": "OH_PixelMap_SetAlphaAble" + }, + { + "name": "OH_PixelMap_GetDensity" + }, + { + "name": "OH_PixelMap_SetDensity" + }, + { + "name": "OH_PixelMap_SetOpacity" + }, + { + "name": "OH_PixelMap_Scale" + }, + { + "name": "OH_PixelMap_Translate" + }, + { + "name": "OH_PixelMap_Rotate" + }, + { + "name": "OH_PixelMap_Flip" + }, + { + "name": "OH_PixelMap_Crop" + }, + { + "name": "OH_PixelMap_GetImageInfo" + }, + { + "name": "OH_PixelMap_AccessPixels" + }, + { + "name": "OH_PixelMap_UnAccessPixels" + } +] \ No newline at end of file diff --git a/multimedia/image_framework/libimage_receiver_ndk.ndk.json b/multimedia/image_framework/libimage_receiver_ndk.ndk.json new file mode 100644 index 000000000..c92209afc --- /dev/null +++ b/multimedia/image_framework/libimage_receiver_ndk.ndk.json @@ -0,0 +1,33 @@ +[ + { + "first_introduced": "1", + "name": "OH_Image_Receiver_CreateImageReceiver" + }, + { + "name": "OH_Image_Receiver_InitImageReceiverNative" + }, + { + "name": "OH_Image_Receiver_GetReceivingSurfaceId" + }, + { + "name": "OH_Image_Receiver_ReadLatestImage" + }, + { + "name": "OH_Image_Receiver_ReadNextImage" + }, + { + "name": "OH_Image_Receiver_On" + }, + { + "name": "OH_Image_Receiver_GetSize" + }, + { + "name": "OH_Image_Receiver_GetCapacity" + }, + { + "name": "OH_Image_Receiver_GetFormat" + }, + { + "name": "OH_Image_Receiver_Release" + } +] \ No newline at end of file diff --git a/multimedia/image_framework/libimage_source_ndk.ndk.json b/multimedia/image_framework/libimage_source_ndk.ndk.json new file mode 100644 index 000000000..b2606bfb2 --- /dev/null +++ b/multimedia/image_framework/libimage_source_ndk.ndk.json @@ -0,0 +1,42 @@ +[ + { + "first_introduced": "1", + "name": "OH_ImageSource_Create" + }, + { + "name": "OH_ImageSource_CreateIncremental" + }, + { + "name": "OH_ImageSource_InitNative" + }, + { + "name": "OH_ImageSource_CreatePixelMap" + }, + { + "name": "OH_ImageSource_CreatePixelMapList" + }, + { + "name": "OH_ImageSource_GetDelayTime" + }, + { + "name": "OH_ImageSource_GetFrameCount" + }, + { + "name": "OH_ImageSource_GetSupportedFormats" + }, + { + "name": "OH_ImageSource_GetImageInfo" + }, + { + "name": "OH_ImageSource_GetImageProperty" + }, + { + "name": "OH_ImageSource_ModifyImageProperty" + }, + { + "name": "OH_ImageSource_UpdateData" + }, + { + "name": "OH_ImageSource_Release" + } +] \ No newline at end of file diff --git a/multimedia/image_framework/ndk_test_example/@ohos.xtstest.mypixelmap.d.ts b/multimedia/image_framework/ndk_test_example/@ohos.xtstest.mypixelmap.d.ts new file mode 100644 index 000000000..baff7239a --- /dev/null +++ b/multimedia/image_framework/ndk_test_example/@ohos.xtstest.mypixelmap.d.ts @@ -0,0 +1,23 @@ +/* +* Copyright (C) 2022 Huawei Device Co., Ltd. +* 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. +*/ +import image from '@ohos.multimedia.image' + +declare namespace mypixelmap { + function testGetImageInfo(PixelMap pixelMap): void; + function testAccessPixels(PixelMap pixelMap): void; + function testUnAccessPixels(PixelMap pixelMap): void; +} + +export default mypixelmap; \ No newline at end of file diff --git a/multimedia/image_framework/ndk_test_example/BUILD.gn b/multimedia/image_framework/ndk_test_example/BUILD.gn new file mode 100644 index 000000000..8834d5e1f --- /dev/null +++ b/multimedia/image_framework/ndk_test_example/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +############################################################################ +# Debug Used : mypixelmap +############################################################################ + +js_declaration("mypixelmap_js") { + part_name = "multimedia_image" + sources = [ "//foundation/multimedia/image_framework/interfaces/kits/native/ndk_test_example/@ohos.xtstest.mypixelmap.d.ts" ] +} + +ohos_copy("mypixelmap_declaration") { + sources = [ "//foundation/multimedia/image_framework/interfaces/kits/native/ndk_test_example/@ohos.xtstest.mypixelmap.d.ts" ] + outputs = [ target_out_dir + "/$target_name/" ] + module_source_dir = target_out_dir + "/$target_name" + module_install_name = "" +} + +ohos_shared_library("mypixelmap") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + install_enable = true + + sources = [ "my_pixel_map.cpp" ] + + include_dirs = [ + "include", + "//foundation/multimedia/image_framework/interfaces/kits/native/include", + ] + + deps = [ + "//foundation/arkui/napi:ace_napi", + "//foundation/multimedia/image_framework/frameworks/kits/js/common/pixelmap_ndk:pixelmap_ndk", + ] + + external_deps = [ "hilog:libhilog" ] + + relative_install_dir = "module" + + subsystem_name = "multimedia" + part_name = "multimedia_image" +} diff --git a/multimedia/image_framework/ndk_test_example/my_pixel_map.cpp b/multimedia/image_framework/ndk_test_example/my_pixel_map.cpp new file mode 100644 index 000000000..a4172f198 --- /dev/null +++ b/multimedia/image_framework/ndk_test_example/my_pixel_map.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "my_pixel_map.h" +#include "media_errors.h" +#include "hilog/log.h" +#include "image_napi_utils.h" +#include "image_pixel_map_napi.h" + +using OHOS::HiviewDFX::HiLog; +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "MyPixelMapNapiTest"}; +constexpr uint32_t TEST_ARG_SUM = 1; +} +namespace OHOS { +namespace Media { +static const std::string CLASS_NAME = "MyPixelMap"; +napi_ref MyPixelMap::sConstructor_ = nullptr; +MyPixelMap::MyPixelMap():env_(nullptr) +{ +} + +MyPixelMap::~MyPixelMap() +{ +} + +napi_value MyPixelMap::Init(napi_env env, napi_value exports) +{ + napi_property_descriptor props[] = { + }; + + napi_property_descriptor static_prop[] = { + DECLARE_NAPI_STATIC_FUNCTION("testGetImageInfo", TestGetImageInfo), + DECLARE_NAPI_STATIC_FUNCTION("testAccessPixels", TestAccessPixels), + DECLARE_NAPI_STATIC_FUNCTION("testUnAccessPixels", TestUnAccessPixels), + }; + + napi_value constructor = nullptr; + + if (napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, nullptr, IMG_ARRAY_SIZE(props), + props, &constructor) != napi_ok) { + HiLog::Error(LABEL, "define class fail"); + return nullptr; + } + + if (napi_create_reference(env, constructor, 1, &sConstructor_) != napi_ok) { + HiLog::Error(LABEL, "create reference fail"); + return nullptr; + } + + if (napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor) != napi_ok) { + HiLog::Error(LABEL, "set named property fail"); + return nullptr; + } + + if (napi_define_properties(env, exports, IMG_ARRAY_SIZE(static_prop), static_prop) != napi_ok) { + HiLog::Error(LABEL, "define properties fail"); + return nullptr; + } + + HiLog::Debug(LABEL, "Init success"); + return exports; +} + +napi_value MyPixelMap::Constructor(napi_env env, napi_callback_info info) +{ + HiLog::Debug(LABEL, "Constructor IN"); + napi_value undefineVar = nullptr; + napi_get_undefined(env, &undefineVar); + + napi_status status; + napi_value thisVar = nullptr; + napi_get_undefined(env, &thisVar); + + napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + + HiLog::Debug(LABEL, "Constructor OUT"); + return thisVar; +} + +napi_value MyPixelMap::TestGetImageInfo(napi_env env, napi_callback_info info) +{ + HiLog::Debug(LABEL, "TestGetImageInfo IN"); + + napi_value result = nullptr; + napi_get_undefined(env, &result); + + napi_status status; + napi_value thisVar = nullptr; + napi_value argValue[TEST_ARG_SUM] = {0}; + size_t argCount = TEST_ARG_SUM; + + status = napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr); + if (status != napi_ok) { + HiLog::Error(LABEL, "napi_get_cb_info fail"); + } + + HiLog::Debug(LABEL, "OH_GetImageInfo Test|Begin"); + OhosPixelMapInfo pixelMapInfo; + int32_t res = OH_GetImageInfo(env, argValue[0], &pixelMapInfo); + HiLog::Debug(LABEL, "OH_GetImageInfo Test|End, res=%{public}d", res); + HiLog::Debug(LABEL, "OH_GetImageInfo, w=%{public}u, h=%{public}u, r=%{public}u, f=%{public}d", + pixelMapInfo.width, pixelMapInfo.height, pixelMapInfo.rowSize, pixelMapInfo.pixelFormat); + + HiLog::Debug(LABEL, "TestGetImageInfo OUT"); + return result; +} + +napi_value MyPixelMap::TestAccessPixels(napi_env env, napi_callback_info info) +{ + HiLog::Debug(LABEL, "TestAccessPixels IN"); + + napi_value result = nullptr; + napi_get_undefined(env, &result); + + napi_status status; + napi_value thisVar = nullptr; + napi_value argValue[TEST_ARG_SUM] = {0}; + size_t argCount = TEST_ARG_SUM; + + status = napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr); + if (status != napi_ok) { + HiLog::Error(LABEL, "napi_get_cb_info fail"); + } + + HiLog::Debug(LABEL, "OH_AccessPixels Test|Begin"); + void* addrPtr = nullptr; + int32_t res = OH_AccessPixels(env, argValue[0], &addrPtr); + HiLog::Debug(LABEL, "OH_AccessPixels Test|End, res=%{public}d", res); + + HiLog::Debug(LABEL, "TestAccessPixels OUT"); + return result; +} + +napi_value MyPixelMap::TestUnAccessPixels(napi_env env, napi_callback_info info) +{ + HiLog::Debug(LABEL, "TestUnAccessPixels IN"); + + napi_value result = nullptr; + napi_get_undefined(env, &result); + + napi_status status; + napi_value thisVar = nullptr; + napi_value argValue[TEST_ARG_SUM] = {0}; + size_t argCount = TEST_ARG_SUM; + + status = napi_get_cb_info(env, info, &argCount, argValue, &thisVar, nullptr); + if (status != napi_ok) { + HiLog::Error(LABEL, "napi_get_cb_info fail"); + } + + HiLog::Debug(LABEL, "OH_UnAccessPixels Test|Begin"); + int32_t res = OH_UnAccessPixels(env, argValue[0]); + HiLog::Debug(LABEL, "OH_UnAccessPixels Test|End, res=%{public}d", res); + + HiLog::Debug(LABEL, "TestUnAccessPixels OUT"); + return result; +} + +/* + * Function registering all props and functions of ohos.medialibrary module + */ +static napi_value Export(napi_env env, napi_value exports) +{ + HiLog::Error(LABEL, "MyPixelMap CALL"); + MyPixelMap::Init(env, exports); + return exports; +} + +/* + * module define + */ +static napi_module g_module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Export, + .nm_modname = "xtstest.mypixelmap", + .nm_priv = ((void*)0), + .reserved = {0} +}; + +/* + * module register + */ +extern "C" __attribute__((constructor)) void MyPixelMapRegisterModule(void) +{ + napi_module_register(&g_module); +} +} // namespace Media +} // namespace OHOS diff --git a/multimedia/image_framework/ndk_test_example/my_pixel_map.h b/multimedia/image_framework/ndk_test_example/my_pixel_map.h new file mode 100644 index 000000000..5542df1f0 --- /dev/null +++ b/multimedia/image_framework/ndk_test_example/my_pixel_map.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef PIXEL_MAP_NAPI_TEST_H_ +#define PIXEL_MAP_NAPI_TEST_H_ + +#include "pixel_map.h" +#include "image_type.h" +#include "image_source.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace Media { +class MyPixelMap { +public: + MyPixelMap(); + ~MyPixelMap(); + + static napi_value Init(napi_env env, napi_value exports); + + static napi_value TestGetImageInfo(napi_env env, napi_callback_info info); + static napi_value TestAccessPixels(napi_env env, napi_callback_info info); + static napi_value TestUnAccessPixels(napi_env env, napi_callback_info info); + +private: + static napi_value Constructor(napi_env env, napi_callback_info info); + + static napi_ref sConstructor_; + + napi_env env_ = nullptr; +}; +} // namespace Media +} // namespace OHOS +#endif /* PIXEL_MAP_NAPI_TEST_H_ */ diff --git a/multimedia/player_framework/avscreen_capture/BUILD.gn b/multimedia/player_framework/avscreen_capture/BUILD.gn new file mode 100644 index 000000000..35f4bdef9 --- /dev/null +++ b/multimedia/player_framework/avscreen_capture/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/player_framework/config.gni") + +ohos_ndk_headers("native_avscreen_capture_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ + "$MEDIA_PLAYER_ROOT_DIR/interfaces/kits/c/native_avscreen_capture.h", + "$MEDIA_PLAYER_ROOT_DIR/interfaces/kits/c/native_avscreen_capture_base.h", + "$MEDIA_PLAYER_ROOT_DIR/interfaces/kits/c/native_avscreen_capture_errors.h", + ] +} + +ohos_ndk_library("libnative_avscreen_capture") { + ndk_description_file = "./libnative_avscreen_capture.ndk.json" + min_compact_version = "1" + output_name = "native_avscreen_capture" + output_extension = "so" + + system_capability = "SystemCapability.Multimedia.Media.AVScreenCapture" + system_capability_headers = [ + "multimedia/player_framework/native_avscreen_capture.h", + "multimedia/player_framework/native_avscreen_capture_base.h", + "multimedia/player_framework/native_avscreen_capture_errors.h", + ] +} diff --git a/multimedia/player_framework/avscreen_capture/libnative_avscreen_capture.ndk.json b/multimedia/player_framework/avscreen_capture/libnative_avscreen_capture.ndk.json new file mode 100644 index 000000000..cf7bda8c5 --- /dev/null +++ b/multimedia/player_framework/avscreen_capture/libnative_avscreen_capture.ndk.json @@ -0,0 +1,13 @@ +[ + { "name": "OH_AVScreenCapture_Create" }, + { "name": "OH_AVScreenCapture_Init" }, + { "name": "OH_AVScreenCapture_StartScreenCapture" }, + { "name": "OH_AVScreenCapture_StopScreenCapture" }, + { "name": "OH_AVScreenCapture_AcquireAudioBuffer" }, + { "name": "OH_AVScreenCapture_AcquireVideoBuffer" }, + { "name": "OH_AVScreenCapture_ReleaseAudioBuffer" }, + { "name": "OH_AVScreenCapture_ReleaseVideoBuffer" }, + { "name": "OH_AVScreenCapture_SetCallback" }, + { "name": "OH_AVScreenCapture_Release" }, + { "name": "OH_AVScreenCapture_SetMicrophoneEnabled" } +] \ No newline at end of file diff --git a/multimedia/player_framework/native_avscreen_capture.h b/multimedia/player_framework/native_avscreen_capture.h new file mode 100644 index 000000000..22837a29d --- /dev/null +++ b/multimedia/player_framework/native_avscreen_capture.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVSCREEN_CAPTURE_H +#define NATIVE_AVSCREEN_CAPTURE_H + +#include +#include +#include "native_avscreen_capture_errors.h" +#include "native_avscreen_capture_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @return Returns a pointer to an OH_AVScreenCapture instance + * @since 10 + * @version 1.0 + */ +struct OH_AVScreenCapture *OH_AVScreenCapture_Create(void); + +/** + * @brief To init the screen capture, typically, you need to configure the description information of the audio + * and video, which can be extracted from the container. This interface must be called before StartAVScreenCapture + * called. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param config Information describing the audio and video config + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_Init(struct OH_AVScreenCapture *capture, + OH_AVScreenCaptureConfig config); + +/** + * @brief Start the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param type Information describing the data type of the capture + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_StartScreenCapture(struct OH_AVScreenCapture *capture); + +/** + * @brief Stop the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_StopScreenCapture(struct OH_AVScreenCapture *capture); + +/** + * @brief Start av screen record use to start save screen record file. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_StartScreenRecording(struct OH_AVScreenCapture *capture); + +/** + * @brief Start av screen record use to stop save screen record file. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_StopScreenRecording(struct OH_AVScreenCapture *capture); + +/** + * @brief Acquire the audio buffer for the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param audiobuffer Information describing the audio buffer of the capture + * @param type Information describing the audio source type + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_AcquireAudioBuffer(struct OH_AVScreenCapture *capture, + OH_AudioBuffer **audiobuffer, OH_AudioCaptureSourceType type); + +/** + * @brief Acquire the video buffer for the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param fence A processing state of display buffer + * @param timestamp Information about the video buffer + * @param region Information about the video buffer + * @return Returns a pointer to an OH_NativeBuffer instance + * @since 10 + * @version 1.0 + */ +OH_NativeBuffer* OH_AVScreenCapture_AcquireVideoBuffer(struct OH_AVScreenCapture *capture, + int32_t *fence, int64_t *timestamp, struct OH_Rect *region); + +/** + * @brief Release the audio buffer for the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param type Information describing the audio source type + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_ReleaseAudioBuffer(struct OH_AVScreenCapture *capture, + OH_AudioCaptureSourceType type); + +/** + * @brief Release the video buffer for the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_ReleaseVideoBuffer(struct OH_AVScreenCapture *capture); + +/** + * @brief Set the callback function so that your application + * can respond to the events generated by the av screen capture. This interface must be called before Init is called. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param callback A collection of all callback functions, see {@link OH_AVScreenCaptureCallback} + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetCallback(struct OH_AVScreenCapture *capture, + struct OH_AVScreenCaptureCallback callback); + +/** + * @brief Release the av screen capture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_Release(struct OH_AVScreenCapture *capture); + +/** + * @brief Controls the switch of the microphone, which is turned on by default + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param isMicrophone The switch of the microphone + * @return Returns AVSCREEN_CAPTURE_ERR_OK if the execution is successful, + * otherwise returns a specific error code, refer to {@link OH_AVSCREEN_CAPTURE_ErrCode} + * @since 10 + * @version 1.0 + */ +OH_AVSCREEN_CAPTURE_ErrCode OH_AVScreenCapture_SetMicrophoneEnabled(struct OH_AVScreenCapture *capture, + bool isMicrophone); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVSCREEN_CAPTURE_H \ No newline at end of file diff --git a/multimedia/player_framework/native_avscreen_capture_base.h b/multimedia/player_framework/native_avscreen_capture_base.h new file mode 100644 index 000000000..97b27e3f1 --- /dev/null +++ b/multimedia/player_framework/native_avscreen_capture_base.h @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVSCREEN_CAPTURE_BASE_H +#define NATIVE_AVSCREEN_CAPTURE_BASE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Nativebuffer of avscreeencapture that from graphics. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_NativeBuffer OH_NativeBuffer; + +/** + * @brief Initialization of avscreeencapture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AVScreenCapture OH_AVScreenCapture; + +/** + * @brief Enumerates screen capture mode. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_CaptureMode { + /* capture home screen */ + OH_CAPTURE_HOME_SCREEN = 0, + /* capture a specified screen */ + OH_CAPTURE_SPECIFIED_SCREEN = 1, + /* capture a specified window */ + OH_CAPTURE_SPECIFIED_WINDOW = 2, + OH_CAPTURE_INVAILD = -1 +} OH_CaptureMode; + +/** + * @brief Enumerates audio cap source type. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_AudioCaptureSourceType { + /* Invalid audio source */ + OH_SOURCE_INVALID = -1, + /* Default audio source */ + OH_SOURCE_DEFAULT = 0, + /* Microphone */ + OH_MIC = 1, + /* inner all PlayBack */ + OH_ALL_PLAYBACK = 2, + /* inner app PlayBack */ + OH_APP_PLAYBACK = 3, +} OH_AudioCaptureSourceType; + +/** + * @brief Enumerates audio codec formats. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_AudioCodecFormat { + /* Default format */ + OH_AUDIO_DEFAULT = 0, + /* Advanced Audio Coding Low Complexity (AAC-LC) */ + OH_AAC_LC = 3, + /* Invalid value */ + OH_AUDIO_CODEC_FORMAT_BUTT, +} OH_AudioCodecFormat; + +/** + * @brief Enumerates video codec formats. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_VideoCodecFormat { + /* Default format */ + OH_VIDEO_DEFAULT = 0, + /* H.264 */ + OH_H264 = 2, + /* H.265/HEVC */ + OH_H265 = 4, + /* MPEG4 */ + OH_MPEG4 = 6, + /* VP8 */ + OH_VP8 = 8, + /* VP9 */ + OH_VP9 = 10, + /* Invalid format */ + OH_VIDEO_CODEC_FORMAT_BUTT, +} OH_VideoCodecFormat; + +/** + * @brief Enumerates screen capture data type. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_DataType { + /* YUV/RGBA/PCM, etc. original stream */ + OH_ORIGINAL_STREAM = 0, + /* h264/AAC, etc. encoded stream */ + OH_ENCODED_STREAM = 1, + /* mp4 file */ + OH_CAPTURE_FILE = 2, + OH_INVAILD = -1 +} OH_DataType; + +/** + * @brief Enumerates video source types. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_VideoSourceType { + /* Unsupported App Usage. */ + /* YUV video data provided through graphic */ + OH_VIDEO_SOURCE_SURFACE_YUV = 0, + /* Raw encoded data provided through graphic */ + OH_VIDEO_SOURCE_SURFACE_ES, + /* RGBA video data provided through graphic */ + OH_VIDEO_SOURCE_SURFACE_RGBA, + /* Invalid value */ + OH_VIDEO_SOURCE_BUTT +} OH_VideoSourceType; + +/** + * @brief Enumerates the container format types. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef enum OH_ContainerFormatType { + /* Audio format type -- m4a */ + CFT_MPEG_4A = 0, + /* Video format type -- mp4 */ + CFT_MPEG_4 = 1 +} OH_ContainerFormatType; + +/** + * @brief Audio capture info struct + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AudioCaptureInfo { + /* Audio capture sample rate info */ + int32_t audioSampleRate; + /* Audio capture channel info */ + int32_t audioChannels; + /* Audio capture source type */ + OH_AudioCaptureSourceType audioSource; +} OH_AudioCaptureInfo; + +/** + * @brief Audio encoder info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AudioEncInfo { + /* Audio encoder bitrate */ + int32_t audioBitrate; + /* Audio codec format */ + OH_AudioCodecFormat audioCodecformat; +} OH_AudioEncInfo; + +/** + * @brief The audio info of avscreeencapture + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AudioInfo { + /* Audio capture info of microphone */ + OH_AudioCaptureInfo micCapInfo; + /* Audio capture info of inner */ + OH_AudioCaptureInfo innerCapInfo; + /* Audio encoder info, no need to set, while dataType = OH_ORIGINAL_STREAM */ + OH_AudioEncInfo audioEncInfo; +} OH_AudioInfo; + +/** + * @brief Video capture info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_VideoCaptureInfo { + /* Display id, should be set while captureMode = CAPTURE_SPECIFIED_SCREEN */ + uint64_t displayId; + /* The ids of mission, should be set while captureMode = CAPTURE_SPECIFIED_WINDOW */ + int32_t *missionIDs; + /* Mission ids length, should be set while captureMode = CAPTURE_SPECIFIED_WINDOW */ + int32_t missionIDsLen; + /* Video frame width of avscreeencapture */ + int32_t videoFrameWidth; + /* Video frame height of avscreeencapture */ + int32_t videoFrameHeight; + /* Video source type of avscreeencapture */ + OH_VideoSourceType videoSource; +} OH_VideoCaptureInfo; + +/** + * @brief Videoc encoder info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_VideoEncInfo { + /* Video encoder format */ + OH_VideoCodecFormat videoCodec; + /* Video encoder bitrate */ + int32_t videoBitrate; + /* Video encoder frame rate */ + int32_t videoFrameRate; +} OH_VideoEncInfo; + +/** + * @brief Video info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_VideoInfo { + /* Video capture info */ + OH_VideoCaptureInfo videoCapInfo; + /* Video encoder info */ + OH_VideoEncInfo videoEncInfo; +} OH_VideoInfo; + +/** + * @brief Recorder file info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_RecorderInfo { + /* Recorder file url */ + char *url; + /* Recorder file url length */ + uint32_t urlLen; + /* Recorder file format */ + OH_ContainerFormatType fileFormat; +} OH_RecorderInfo; + +/** + * @brief AV screeen capture config info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AVScreenCaptureConfig { + OH_CaptureMode captureMode; + OH_DataType dataType; + OH_AudioInfo audioInfo; + OH_VideoInfo videoInfo; + /* should be set, while dataType = OH_CAPTURE_FILE */ + OH_RecorderInfo recorderInfo; +} OH_AVScreenCaptureConfig; + +/** + * @brief When an error occurs in the running of the OH_AVScreenCapture instance, the function pointer will be called + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param errorCode specific error code + * + * @since 10 + * @version 1.0 + */ +typedef void (*OH_AVScreenCaptureOnError)(OH_AVScreenCapture *capture, int32_t errorCode); + +/** + * @brief When audio buffer is available during the operation of OH_AVScreenCapture, the function pointer will + * be called. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param isReady Information describing whether audio buffer is available + * @param type Information describing the audio source type + * + * @since 10 + * @version 1.0 + */ +typedef void (*OH_AVScreenCaptureOnAudioBufferAvailable)(OH_AVScreenCapture *capture, bool isReady, + OH_AudioCaptureSourceType type); + +/** + * @brief When video buffer is available during the operation of OH_AVScreenCapture, the function pointer will + * be called. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param capture Pointer to an OH_AVScreenCapture instance + * @param isReady Information describing whether video buffer is available + * + * @since 10 + * @version 1.0 + */ +typedef void (*OH_AVScreenCaptureOnVideoBufferAvailable)(OH_AVScreenCapture *capture, bool isReady); + +/** + * @brief A collection of all callback function pointers in OH_AVScreenCapture. Register an instance of this + * structure to the OH_AVScreenCapture instance, and process the information reported through the callback to ensure the + * normal operation of OH_AVScreenCapture. + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @param onError Monitor OH_AVScreenCapture operation errors, refer to {@link OH_AVScreenCaptureOnError} + * @param onAudioBufferAvailable Monitor audio buffer, refer to {@link OH_AVScreenCaptureOnAudioBufferAvailable} + * @param onVideoBufferAvailable Monitor video buffer, refer to {@link OH_AVScreenCaptureOnVideoBufferAvailable} + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AVScreenCaptureCallback { + OH_AVScreenCaptureOnError onError; + OH_AVScreenCaptureOnAudioBufferAvailable onAudioBufferAvailable; + OH_AVScreenCaptureOnVideoBufferAvailable onVideoBufferAvailable; +} OH_AVScreenCaptureCallback; + +/** + * @brief avscreeencapture rect info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_Rect { + /* X-coordinate of screen recording */ + int32_t x; + /* y-coordinate of screen recording */ + int32_t y; + /* Width of screen recording */ + int32_t width; + /* Height of screen recording */ + int32_t height; +} OH_Rect; + + +/** + * @brief Audiobuffer struct info + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_AudioBuffer { + /* Audio buffer memory block */ + uint8_t *buf; + /* Audio buffer memory block size */ + int32_t size; + /* Audio buffer timestamp info */ + int64_t timestamp; + /* Audio capture source type */ + OH_AudioCaptureSourceType type; +} OH_AudioBuffer; + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVSCREEN_CAPTURE_BASE_H \ No newline at end of file diff --git a/multimedia/player_framework/native_avscreen_capture_errors.h b/multimedia/player_framework/native_avscreen_capture_errors.h new file mode 100644 index 000000000..d202659f0 --- /dev/null +++ b/multimedia/player_framework/native_avscreen_capture_errors.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_AVSCREEN_CAPTURE_ERRORS_H +#define NATIVE_AVSCREEN_CAPTURE_ERRORS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Screen capture error code + * @syscap SystemCapability.Multimedia.Media.AVScreenCapture + * @since 10 + * @version 1.0 + */ + +typedef enum OH_AVSCREEN_CAPTURE_ErrCode { + /** + * basic error mask for screen recording. + */ + AV_SCREEN_CAPTURE_ERR_BASE = 0, + /** + * the operation completed successfully. + */ + AV_SCREEN_CAPTURE_ERR_OK = AV_SCREEN_CAPTURE_ERR_BASE, + /** + * no memory. + */ + AV_SCREEN_CAPTURE_ERR_NO_MEMORY = AV_SCREEN_CAPTURE_ERR_BASE + 1, + /** + * opertation not be permitted. + */ + AV_SCREEN_CAPTURE_ERR_OPERATE_NOT_PERMIT = AV_SCREEN_CAPTURE_ERR_BASE + 2, + /** + * invalid argument. + */ + AV_SCREEN_CAPTURE_ERR_INVALID_VAL = AV_SCREEN_CAPTURE_ERR_BASE + 3, + /** + * IO error. + */ + AV_SCREEN_CAPTURE_ERR_IO = AV_SCREEN_CAPTURE_ERR_BASE + 4, + /** + * network timeout. + */ + AV_SCREEN_CAPTURE_ERR_TIMEOUT = AV_SCREEN_CAPTURE_ERR_BASE + 5, + /** + * unknown error. + */ + AV_SCREEN_CAPTURE_ERR_UNKNOWN = AV_SCREEN_CAPTURE_ERR_BASE + 6, + /** + * media service died. + */ + AV_SCREEN_CAPTURE_ERR_SERVICE_DIED = AV_SCREEN_CAPTURE_ERR_BASE + 7, + /** + * the state is not support this operation. + */ + AV_SCREEN_CAPTURE_ERR_INVALID_STATE = AV_SCREEN_CAPTURE_ERR_BASE + 8, + /** + * unsupport interface. + */ + AV_SCREEN_CAPTURE_ERR_UNSUPPORT = AV_SCREEN_CAPTURE_ERR_BASE + 9, + /** + * extend err start. + */ + AV_SCREEN_CAPTURE_ERR_EXTEND_START = AV_SCREEN_CAPTURE_ERR_BASE + 100, +} OH_AVSCREEN_CAPTURE_ErrCode; + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_AVSCREEN_CAPTURE_ERRORS_H \ No newline at end of file diff --git a/patches/patches.json b/patches/patches.json new file mode 100644 index 000000000..10f322548 --- /dev/null +++ b/patches/patches.json @@ -0,0 +1,9 @@ +{ + "patches": [ + { + "project":"build", + "path":"build", + "pr_url":"https://gitee.com/openharmony/build/pulls/2215" + } + ] +} \ No newline at end of file diff --git a/security/huks/BUILD.gn b/security/huks/BUILD.gn new file mode 100644 index 000000000..e2d44a30a --- /dev/null +++ b/security/huks/BUILD.gn @@ -0,0 +1,71 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_library("libhuks_ndk") { + output_name = "huks_ndk" + output_extension = "z.so" + ndk_description_file = "./libhuks.ndk.json" + min_compact_version = "1" + + # system_capability = "SystemCapability.Security.Huks" +} + +ohos_ndk_headers("huks_header") { + dest_dir = "$ndk_headers_out_dir/huks" + sources = [ + "./include/native_huks_api.h", + "./include/native_huks_param.h", + "./include/native_huks_type.h", + ] +} + +config("huks_config") { + include_dirs = [ "include" ] +} + +ohos_shared_library("huks_ndk") { + public_configs = [ ":huks_config" ] + defines = [ + "L2_STANDARD", + "_HARDWARE_ROOT_KEY_", + "_HUKS_LOG_ENABLE_", + ] + + include_dirs = [ + "//base/security/huks/interfaces/kits/c/include", + "//base/security/huks/interfaces/inner_api/huks_standard/main/include", + "//base/security/huks/frameworks/huks_standard/main/common/include", + ] + + sources = [ + "//base/security/huks/interfaces/kits/c/src/native_huks_api_adapter.c", + "src/native_huks_api.c", + "src/native_huks_param.c", + ] + + deps = [ + "//base/security/huks/interfaces/inner_api/huks_standard/main:libhukssdk", + ] + + external_deps = [ "hilog:libhilog" ] + + cflags_cc = [ + "-Wall", + "-Werror", + ] + + part_name = "huks" + subsystem_name = "security" +} diff --git a/security/huks/include/native_huks_api.h b/security/huks/include/native_huks_api.h new file mode 100644 index 000000000..f052661e2 --- /dev/null +++ b/security/huks/include/native_huks_api.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_HUKS_API_H +#define NATIVE_HUKS_API_H + +/** + * @addtogroup HuksKeyApi + * @{ + * + * @brief Describes the OpenHarmony Universal KeyStore (HUKS) capabilities, including key management and + * cryptography operations, provided for applications. + * The keys managed by HUKS can be imported by applications or generated by calling the HUKS APIs. + * + * @syscap SystemCapability.Security.Huks + * @since 9 + * @version 1.0 + */ + +/** + * @file native_huks_api.h + * + * @brief Declares the APIs used to access the HUKS. + * + * @since 9 + * @version 1.0 + */ + +#include "native_huks_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Obtains the current HUKS SDK version. + * + * @param sdkVersion Indicates the pointer to the SDK version (in string format) obtained. + * return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_GetSdkVersion(struct OH_Huks_Blob *sdkVersion); + +/** + * @brief Generates a key. + * + * @param keyAlias Indicates the pointer to the alias of the key to generate. + * The alias must be unique in the process of the service. Otherwise, the key will be overwritten. + * @param paramSetIn Indicates the pointer to the parameter set for generating the key. + * @param paramSetOut Indicates the pointer to a temporary key generated. If the generated key is + * not of a temporary type, this parameter is a null pointer. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_GenerateKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSetIn, struct OH_Huks_ParamSet *paramSetOut); + +/** + * @brief Imports a key in plaintext. + * + * @param keyAlias Indicates the pointer to the alias of the key to import. + * The alias must be unique in the process of the service. Otherwise, the key will be overwritten. + * @param paramSet Indicates the pointer to the parameters of the key to import. + * @param key Indicates the pointer to the key to import. The key must be in the format required by the HUKS. + * For details, see {@link HuksTypeApi}. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_ImportKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *key); + +/** + * @brief Imports a wrapped key. + * + * @param keyAlias Indicates the pointer to the alias of the key to import. + * The alias must be unique in the process of the service. Otherwise, the key will be overwritten. + * @param wrappingKeyAlias Indicates the pointer to the alias of the wrapping key, + * which is obtained through key agreement and used to decrypt the key to import. + * @param paramSet Indicates the pointer to the parameters of the wrapped key to import. + * @param wrappedKeyData Indicates the pointer to the wrapped key to import. + * The key must be in the format required by the HUKS. For details, see {@link OH_Huks_AlgSuite}. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_ImportWrappedKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_Blob *wrappingKeyAlias, const struct OH_Huks_ParamSet *paramSet, + const struct OH_Huks_Blob *wrappedKeyData); + +/** + * @brief Exports a public key. + * + * @param keyAlias Indicates the pointer to the alias of the public key to export. + * The alias must be the same as the alias for the key generated. + * @param paramSet Indicates the pointer to the parameters required for exporting the public key. + * @param key Indicates the pointer to the public key exported. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_ExportPublicKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, struct OH_Huks_Blob *key); + +/** + * @brief Deletes a key. + * + * @param keyAlias Indicates the pointer to the alias of the key to delete. + * The alias must be the same as the alias for the key generated. + * @param paramSet Indicates the pointer to the parameters required for deleting the key. + * By default, this parameter is a null pointer. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_DeleteKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet); + +/** + * @brief Obtains the attributes of a key. + * + * @param keyAlias Indicates the pointer to the alias of the target key. + * @param paramSetIn Indicates the pointer to the attribute tag required for + * obtaining the attributes. By default, this parameter is a null pointer. + * @param paramSetOut Indicates the pointer to the attributes obtained. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_GetKeyItemParamSet(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSetIn, struct OH_Huks_ParamSet *paramSetOut); + +/** + * @brief Checks whether a key exists. + * + * @param keyAlias Indicates the pointer to the alias of the target key. + * @param paramSet Indicates the pointer to the attribute tag required for checking the key. + * By default, this parameter is a null pointer. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the key exists. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_ERR_CODE_ITEM_NOT_EXIST} if the key does not exist. + * @return Returns any other error code for other cases. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_IsKeyItemExist(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet); + +/** + * @brief Obtain the key certificate chain. + * + * @param keyAlias Indicates the pointer to the alias of the target key. + * @param paramSet Indicates the pointer to the parameters required for obtaining the key certificate. + * @param certChain Indicates the pointer to the key certificate chain obtained. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_AttestKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, struct OH_Huks_CertChain *certChain); + +/** + * @brief Initializes the key session interface and obtains a handle (mandatory) and challenge value (optional). + * + * @param keyAlias Indicates the pointer to the alias of the target key. + * @param paramSet Indicates the pointer to the parameters for the initialization operation. + * @param handle Indicates the pointer to the handle of the key session obtained. + * This handle is required for subsequent operations, including {@link OH_Huks_UpdateSession}, + * {@link OH_Huks_FinishSession}, and {@link OH_Huks_AbortSession}. + * @param challenge Indicates the pointer to the challenge value obtained. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + * @see OH_Huks_UpdateSession + * @see OH_Huks_FinishSession + * @see OH_Huks_AbortSession + */ +struct OH_Huks_Result OH_Huks_InitSession(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, struct OH_Huks_Blob *handle, struct OH_Huks_Blob *token); + +/** + * @brief Adds data by segment for the key operation, performs the related key operation, + * and outputs the processed data. + * + * @param handle Indicates the pointer to the key session handle, which is generated by {@link OH_Huks_InitSession}. + * @param paramSet Indicates the pointer to the parameters required for the key operation. + * @param inData Indicates the pointer to the data to be processed. + * This API can be called multiples time to process large data by segment. + * @param outData Indicates the pointer to the output data. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + * @see OH_Huks_InitSession + * @see OH_Huks_FinishSession + * @see OH_Huks_AbortSession + */ +struct OH_Huks_Result OH_Huks_UpdateSession(const struct OH_Huks_Blob *handle, + const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *outData); + +/** + * @brief Ends the key session. + * + * @param handle Indicates the pointer to the key session handle, which is generated by {@link OH_Huks_InitSession}. + * @param paramSet Indicates the pointer to the parameters required for the key operation. + * @param inData Indicates the pointer to the data to be processed. + * @param outData Indicates the pointer to the output data. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + * @see OH_Huks_InitSession + * @see OH_Huks_UpdateSession + * @see OH_Huks_AbortSession + */ +struct OH_Huks_Result OH_Huks_FinishSession(const struct OH_Huks_Blob *handle, + const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *outData); + +/** + * @brief Aborts a key session. + * + * @param handle Indicates the pointer to the key session handle, which is generated by {@link OH_Huks_InitSession}. + * @param paramSet Indicates the pointer to the parameters required for aborting the key session. + * By default, this parameter is a null pointer. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + * @see OH_Huks_InitSession + * @see OH_Huks_UpdateSession + * @see OH_Huks_FinishSession + */ +struct OH_Huks_Result OH_Huks_AbortSession(const struct OH_Huks_Blob *handle, + const struct OH_Huks_ParamSet *paramSet); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* NATIVE_HUKS_API_H */ diff --git a/security/huks/include/native_huks_api_adapter.h b/security/huks/include/native_huks_api_adapter.h new file mode 100644 index 000000000..25f187cc3 --- /dev/null +++ b/security/huks/include/native_huks_api_adapter.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_HUKS_API_ADAPTER_H +#define NATIVE_HUKS_API_ADAPTER_H + +#include "native_huks_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t HuksAttestAdapter(const struct OH_Huks_Blob *keyAlias, const struct OH_Huks_ParamSet *paramSet, + struct OH_Huks_CertChain *certChain); + +#ifdef __cplusplus +} +#endif + +#endif /* NATIVE_HUKS_API_ADAPTER_H */ diff --git a/security/huks/include/native_huks_param.h b/security/huks/include/native_huks_param.h new file mode 100644 index 000000000..c375fe1f9 --- /dev/null +++ b/security/huks/include/native_huks_param.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_HUKS_PARAM_H +#define NATIVE_HUKS_PARAM_H + +/** + * @addtogroup HuksParamSetApi + * @{ + * + * @brief Defines the capabilities of OpenHarmony Universal KeyStore (HUKS) parameter sets. + * The HUKS APIs can be used to perform parameter set lifecycle management, + * including initializing a parameter set, adding parameters to a parameter set, constructing + * a parameter set, and destroying a parameter set. + * They can also be used to obtain parameters, copy parameter sets, and check parameter validity. + * + * @syscap SystemCapability.Security.Huks + * @since 9 + * @version 1.0 + */ + +/** + * @file native_huks_param.h + * + * @brief Provides APIs for constructing, using, and destroying parameter sets. + * + * @since 9 + * @version 1.0 + */ + +#include "native_huks_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initializes a parameter set. + * + * @param paramSet Indicates the double pointer to the parameter set to initialize. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the initialization is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_InitParamSet(struct OH_Huks_ParamSet **paramSet); + +/** + * @brief Adds parameters to a parameter set. + * + * @param paramSet Indicates the pointer to the parameter set to which parameters are to be added. + * @param params Indicates the pointer to the array of parameters to add. + * @param paramCnt Indicates the number of parameters to add. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_AddParams(struct OH_Huks_ParamSet *paramSet, + const struct OH_Huks_Param *params, uint32_t paramCnt); + +/** + * @brief Constructs a parameter set. + * + * @param paramSet Indicates the double pointer to the parameter set to construct. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_BuildParamSet(struct OH_Huks_ParamSet **paramSet); + +/** + * @brief Destroys a parameter set. + * + * @param paramSet Indicates the double pointer to the parameter set to destroy. + * @since 9 + * @version 1.0 + */ +void OH_Huks_FreeParamSet(struct OH_Huks_ParamSet **paramSet); + +/** + * @brief Copies a parameter set (deep copy). + * + * @param fromParamSet Indicates the pointer to the parameter set to copy. + * @param fromParamSetSize Indicates the memory size occupied by the source parameter set. + * @param paramSet Indicates the double pointer to the new parameter set generated. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_CopyParamSet(const struct OH_Huks_ParamSet *fromParamSet, + uint32_t fromParamSetSize, struct OH_Huks_ParamSet **paramSet); + +/** + * @brief Obtains parameters from a parameter set. + * + * @param paramSet Indicates the pointer to the target parameter set. + * @param tag Indicates the value of the parameter to be obtained. + * @param param Indicates the double pointer to the parameter obtained. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the operation is successful, + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_GetParam(const struct OH_Huks_ParamSet *paramSet, uint32_t tag, + struct OH_Huks_Param **param); + +/** + * @brief Refreshes data of the Blob type in a parameter set. + * + * @param paramSet Indicates the pointer to the target parameter set. + * @param isCopy Specifies whether to copy the data of the Blob type to the parameter set. + * If yes, the data of the Blob type will be copied to the parameter set. + * Otherwise, only the address of the Blob data will be refreshed. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if operation is successful; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_FreshParamSet(struct OH_Huks_ParamSet *paramSet, bool isCopy); + +/** + * @brief Checks whether the parameters in a parameter set are valid. + * + * @param paramSet Indicates the pointer to the parameter set to check. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the parameters in the parameter set are valid; + * returns other values if the parameter set has invalid, duplicate, or incorrect parameters. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_IsParamSetTagValid(const struct OH_Huks_ParamSet *paramSet); + +/** + * @brief Checks whether a parameter set is of the valid size. + * + * @param paramSet Indicates the pointer to the parameter set to check. + * @param size Indicates the memory size occupied by the parameter set. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the parameter set is of the valid size; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_IsParamSetValid(const struct OH_Huks_ParamSet *paramSet, uint32_t size); + +/** + * @brief Checks whether two parameters are the same. + * + * @param baseParam Indicates the pointer to the first parameter. + * @param param Indicates the pointer to the second parameter. + * @return Returns {@link OH_Huks_ErrCode#OH_HUKS_SUCCESS} if the two parameters are the same; + * returns an error code otherwise. + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result OH_Huks_CheckParamMatch(const struct OH_Huks_Param *baseParam, const struct OH_Huks_Param *param); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* NATIVE_HUKS_PARAM_H */ diff --git a/security/huks/include/native_huks_type.h b/security/huks/include/native_huks_type.h new file mode 100644 index 000000000..9b51f56c9 --- /dev/null +++ b/security/huks/include/native_huks_type.h @@ -0,0 +1,861 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef NATIVE_OH_HUKS_TYPE_H +#define NATIVE_OH_HUKS_TYPE_H + +/** + * @addtogroup HuksTypeApi + * @{ + * + * @brief Defines the macros, enumerated values, data structures, + * and error codes used by OpenHarmony Universal KeyStore (HUKS) APIs. + * + * @syscap SystemCapability.Security.Huks + * @since 9 + * @version 1.0 + */ + +/** + * @file native_huks_type.h + * + * @brief Defines the enumerated variables, structures, and macros used in the HUKS APIs. + * + * @since 9 + * @version 1.0 + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define OH_HUKS_AE_TAG_LEN 16 +#define OH_HUKS_BITS_PER_BYTE 8 +#define OH_HUKS_MAX_KEY_SIZE 2048 +#define OH_HUKS_AE_NONCE_LEN 12 +#define OH_HUKS_MAX_KEY_ALIAS_LEN 64 +#define OH_HUKS_MAX_PROCESS_NAME_LEN 50 +#define OH_HUKS_MAX_RANDOM_LEN 1024 +#define OH_HUKS_SIGNATURE_MIN_SIZE 64 +#define OH_HUKS_MAX_OUT_BLOB_SIZE (5 * 1024 * 1024) +#define OH_HUKS_WRAPPED_FORMAT_MAX_SIZE (1024 * 1024) +#define OH_HUKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS 10 +#define TOKEN_CHALLENGE_LEN 32 +#define SHA256_SIGN_LEN 32 +#define TOKEN_SIZE 32 +#define MAX_AUTH_TIMEOUT_SECOND 60 +#define SECURE_SIGN_VERSION 0x01000001 + +/** + * @brief Enumerates the key purposes. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyPurpose { + /** Used to encrypt the plaintext. */ + OH_HUKS_KEY_PURPOSE_ENCRYPT = 1, + /** Used to decrypt the cipher text. */ + OH_HUKS_KEY_PURPOSE_DECRYPT = 2, + /** Used to sign data. */ + OH_HUKS_KEY_PURPOSE_SIGN = 4, + /** Used to verify the signature. */ + OH_HUKS_KEY_PURPOSE_VERIFY = 8, + /** Used to derive a key. */ + OH_HUKS_KEY_PURPOSE_DERIVE = 16, + /** Used for an encrypted export. */ + OH_HUKS_KEY_PURPOSE_WRAP = 32, + /** Used for an encrypted import. */ + OH_HUKS_KEY_PURPOSE_UNWRAP = 64, + /** Used to generate a message authentication code (MAC). */ + OH_HUKS_KEY_PURPOSE_MAC = 128, + /** Used for key agreement. */ + OH_HUKS_KEY_PURPOSE_AGREE = 256, +}; + +/** + * @brief Enumerates the digest algorithms. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyDigest { + /** No digest algorithm. */ + OH_HUKS_DIGEST_NONE = 0, + /** MD5. */ + OH_HUKS_DIGEST_MD5 = 1, + /** SM3. */ + OH_HUKS_DIGEST_SM3 = 2, + /** SHA-1. */ + OH_HUKS_DIGEST_SHA1 = 10, + /** SHA-224. */ + OH_HUKS_DIGEST_SHA224 = 11, + /** SHA-256. */ + OH_HUKS_DIGEST_SHA256 = 12, + /** SHA-384. */ + OH_HUKS_DIGEST_SHA384 = 13, + /** SHA-512. */ + OH_HUKS_DIGEST_SHA512 = 14, +}; + +/** + * @brief Enumerates the padding algorithms. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyPadding { + /** No padding algorithm. */ + OH_HUKS_PADDING_NONE = 0, + /** Optimal Asymmetric Encryption Padding (OAEP). */ + OH_HUKS_PADDING_OAEP = 1, + /** Probabilistic Signature Scheme (PSS). */ + OH_HUKS_PADDING_PSS = 2, + /** Public Key Cryptography Standards (PKCS) #1 v1.5. */ + OH_HUKS_PADDING_PKCS1_V1_5 = 3, + /** PKCS #5. */ + OH_HUKS_PADDING_PKCS5 = 4, + /** PKCS #7. */ + OH_HUKS_PADDING_PKCS7 = 5, +}; + +/** + * @brief Enumerates the cipher modes. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_CipherMode { + /** Electronic Code Block (ECB) mode. */ + OH_HUKS_MODE_ECB = 1, + /** Cipher Block Chaining (CBC) mode. */ + OH_HUKS_MODE_CBC = 2, + /** Counter (CTR) mode. */ + OH_HUKS_MODE_CTR = 3, + /** Output Feedback (OFB) mode. */ + OH_HUKS_MODE_OFB = 4, + /** Counter with CBC-MAC (CCM) mode. */ + OH_HUKS_MODE_CCM = 31, + /** Galois/Counter (GCM) mode. */ + OH_HUKS_MODE_GCM = 32, +}; + +/** + * @brief Enumerates the key sizes. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeySize { + /** Rivest-Shamir-Adleman (RSA) key of 512 bits. */ + OH_HUKS_RSA_KEY_SIZE_512 = 512, + /** RSA key of 768 bits. */ + OH_HUKS_RSA_KEY_SIZE_768 = 768, + /** RSA key of 1024 bits. */ + OH_HUKS_RSA_KEY_SIZE_1024 = 1024, + /** RSA key of 2048 bits. */ + OH_HUKS_RSA_KEY_SIZE_2048 = 2048, + /** RSA key of 3072 bits. */ + OH_HUKS_RSA_KEY_SIZE_3072 = 3072, + /** RSA key of 4096 bits. */ + OH_HUKS_RSA_KEY_SIZE_4096 = 4096, + + /** Elliptic Curve Cryptography (ECC) key of 224 bits. */ + OH_HUKS_ECC_KEY_SIZE_224 = 224, + /** ECC key of 256 bits. */ + OH_HUKS_ECC_KEY_SIZE_256 = 256, + /** ECC key of 384 bits. */ + OH_HUKS_ECC_KEY_SIZE_384 = 384, + /** ECC key of 521 bits. */ + OH_HUKS_ECC_KEY_SIZE_521 = 521, + + /** Advanced Encryption Standard (AES) key of 128 bits. */ + OH_HUKS_AES_KEY_SIZE_128 = 128, + /** AES key of 192 bits. */ + OH_HUKS_AES_KEY_SIZE_192 = 192, + /** AES key of 256 bits. */ + OH_HUKS_AES_KEY_SIZE_256 = 256, + /** AES key of 512 bits. */ + OH_HUKS_AES_KEY_SIZE_512 = 512, + + /** Curve25519 key of 256 bits. */ + OH_HUKS_CURVE25519_KEY_SIZE_256 = 256, + + /** Diffie-Hellman (DH) key of 2048 bits. */ + OH_HUKS_DH_KEY_SIZE_2048 = 2048, + /** DH key of 3072 bits. */ + OH_HUKS_DH_KEY_SIZE_3072 = 3072, + /** DH key of 4096 bits. */ + OH_HUKS_DH_KEY_SIZE_4096 = 4096, + + /** ShangMi2 (SM2) key of 256 bits. */ + OH_HUKS_SM2_KEY_SIZE_256 = 256, + /** ShangMi4 (SM4) key of 128 bits. */ + OH_HUKS_SM4_KEY_SIZE_128 = 128, +}; + +/** + * @brief Enumerates the key algorithms. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyAlg { + /** RSA. */ + OH_HUKS_ALG_RSA = 1, + /** ECC. */ + OH_HUKS_ALG_ECC = 2, + /** DSA. */ + OH_HUKS_ALG_DSA = 3, + + /** AES. */ + OH_HUKS_ALG_AES = 20, + /** HMAC. */ + OH_HUKS_ALG_HMAC = 50, + /** HKDF. */ + OH_HUKS_ALG_HKDF = 51, + /** PBKDF2. */ + OH_HUKS_ALG_PBKDF2 = 52, + + /** ECDH. */ + OH_HUKS_ALG_ECDH = 100, + /** X25519. */ + OH_HUKS_ALG_X25519 = 101, + /** Ed25519. */ + OH_HUKS_ALG_ED25519 = 102, + /** DH. */ + OH_HUKS_ALG_DH = 103, + + /** SM2. */ + OH_HUKS_ALG_SM2 = 150, + /** SM3. */ + OH_HUKS_ALG_SM3 = 151, + /** SM4. */ + OH_HUKS_ALG_SM4 = 152, +}; + +/** + * @brief Enumerates the algorithm suites required for ciphertext imports. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_AlgSuite { + /** Key material format (Length-Value format), X25519 key agreement, and AES-256-GCM encryption and decryption. + * | x25519_plain_pubkey_length (4 Byte) | x25519_plain_pubkey | agreekey_aad_length (4 Byte) | agreekey_aad + * | agreekey_nonce_length (4 Byte) | agreekey_nonce | + * | agreekey_aead_tag_len (4 Byte) | agreekey_aead_tag | + * | kek_enc_data_length (4 Byte) | kek_enc_data | kek_aad_length (4 Byte) | kek_aad + * | kek_nonce_length (4 Byte) | kek_nonce | kek_aead_tag_len (4 Byte) | kek_aead_tag + * | key_material_size_len (4 Byte) | key_material_size | key_mat_enc_length (4 Byte) | key_mat_enc_data + */ + OH_HUKS_UNWRAP_SUITE_X25519_AES_256_GCM_NOPADDING = 1, + + /** Key material format (Length-Value format), ECDH-p256 key agreement, and AES-256-GCM encryption and decryption. + * | ECC_plain_pubkey_length (4 Byte) | ECC_plain_pubkey | agreekey_aad_length (4 Byte) | agreekey_aad + * | agreekey_nonce_length (4 Byte) | agreekey_nonce | + * | agreekey_aead_tag_len (4 Byte) | agreekey_aead_tag | + * | kek_enc_data_length (4 Byte) | kek_enc_data | kek_aad_length (4 Byte) | kek_aad + * | kek_nonce_length (4 Byte) | kek_nonce | kek_aead_tag_len (4 Byte) | kek_aead_tag + * | key_material_size_len (4 Byte) | key_material_size | key_mat_enc_length (4 Byte) | key_mat_enc_data + */ + OH_HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING = 2, +}; + +/** + * @brief Enumerates the key generation types. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyGenerateType { + /** Key generated by default. */ + OH_HUKS_KEY_GENERATE_TYPE_DEFAULT = 0, + /** Derived key. */ + OH_HUKS_KEY_GENERATE_TYPE_DERIVE = 1, + /** Key obtained by key agreement. */ + OH_HUKS_KEY_GENERATE_TYPE_AGREE = 2, +}; + +/** + * @brief Enumerates the key generation modes. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyFlag { + /** Import a public key using an API. */ + OH_HUKS_KEY_FLAG_IMPORT_KEY = 1, + /** Generate a key by using an API. */ + OH_HUKS_KEY_FLAG_GENERATE_KEY = 2, + /** Generate a key by using a key agreement API. */ + OH_HUKS_KEY_FLAG_AGREE_KEY = 3, + /** Derive a key by using an API. */ + OH_HUKS_KEY_FLAG_DERIVE_KEY = 4, +}; + +/** + * @brief Enumerates the key storage modes. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_KeyStorageType { + /** The key is managed locally. */ + OH_HUKS_STORAGE_TEMP = 0, + /** The key is managed by the HUKS service. */ + OH_HUKS_STORAGE_PERSISTENT = 1, + /** The key is only used in huks. */ + OH_HUKS_STORAGE_ONLY_USED_IN_HUKS = 2, + /** The key can be allowed to export. */ + OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED = 3, +}; + +/** + * @brief Enumerates the types of keys to import. By default, + * a public key is imported. This field is not required when a symmetric key is imported. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_ImportKeyType { + /** Public key. */ + OH_HUKS_KEY_TYPE_PUBLIC_KEY = 0, + /** Private key. */ + OH_HUKS_KEY_TYPE_PRIVATE_KEY = 1, + /** Public and private key pair. */ + OH_HUKS_KEY_TYPE_KEY_PAIR = 2, +}; + +/** + * @brief Enumerates the key storage modes. + * + * @since 10 + * @version 1.0 + */ +enum OH_Huks_RsaPssSaltLenType { + /** Salt length matches digest. */ + OH_HUKS_RSA_PSS_SALT_LEN_DIGEST = 0, + /** Set salt length to maximum possible, default type. */ + OH_HUKS_RSA_PSS_SALT_LEN_MAX = 1, +}; + +/** + * @brief Enumerates the error codes. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_ErrCode { + /** The operation is successful. */ + OH_HUKS_SUCCESS = 0, + /** Permission verification failed. */ + OH_HUKS_ERR_CODE_PERMISSION_FAIL = 201, + /** Invalid parameters are detected. */ + OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT = 401, + /** The API is not supported. */ + OH_HUKS_ERR_CODE_NOT_SUPPORTED_API = 801, + + /** The feature is not supported. */ + OH_HUKS_ERR_CODE_FEATURE_NOT_SUPPORTED = 12000001, + /** Key algorithm parameters are missing. */ + OH_HUKS_ERR_CODE_MISSING_CRYPTO_ALG_ARGUMENT = 12000002, + /** Invalid key algorithm parameters are detected. */ + OH_HUKS_ERR_CODE_INVALID_CRYPTO_ALG_ARGUMENT = 12000003, + /** Failed to operate the file. */ + OH_HUKS_ERR_CODE_FILE_OPERATION_FAIL = 12000004, + /** The process communication failed. */ + OH_HUKS_ERR_CODE_COMMUNICATION_FAIL = 12000005, + /** Failed to operate the algorithm library. */ + OH_HUKS_ERR_CODE_CRYPTO_FAIL = 12000006, + /** Failed to access the key because the key has expired. */ + OH_HUKS_ERR_CODE_KEY_AUTH_PERMANENTLY_INVALIDATED = 12000007, + /** Failed to access the key because the authentication has failed. */ + OH_HUKS_ERR_CODE_KEY_AUTH_VERIFY_FAILED = 12000008, + /** Key access timed out. */ + OH_HUKS_ERR_CODE_KEY_AUTH_TIME_OUT = 12000009, + /** The number of key operation sessions has reached the limit. */ + OH_HUKS_ERR_CODE_SESSION_LIMIT = 12000010, + /** The entity does not exist. */ + OH_HUKS_ERR_CODE_ITEM_NOT_EXIST = 12000011, + /** Internal error. */ + OH_HUKS_ERR_CODE_INTERNAL_ERROR = 12000012, + /** The authentication credential does not exist. */ + OH_HUKS_ERR_CODE_CREDENTIAL_NOT_EXIST = 12000013, +}; + +/** + * @brief Enumerates the tag types. + * @see OH_Huks_Param + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_TagType { + /** Invalid tag type. */ + OH_HUKS_TAG_TYPE_INVALID = 0 << 28, + /** int32_t. */ + OH_HUKS_TAG_TYPE_INT = 1 << 28, + /** uin32_t. */ + OH_HUKS_TAG_TYPE_UINT = 2 << 28, + /** uin64_t. */ + OH_HUKS_TAG_TYPE_ULONG = 3 << 28, + /** Boolean. */ + OH_HUKS_TAG_TYPE_BOOL = 4 << 28, + /** OH_Huks_Blob. */ + OH_HUKS_TAG_TYPE_BYTES = 5 << 28, +}; + +/** + * @brief Enumerates the user authentication types. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_UserAuthType { + /** Fingerprint authentication. */ + OH_HUKS_USER_AUTH_TYPE_FINGERPRINT = 1 << 0, + /** Facial authentication. */ + OH_HUKS_USER_AUTH_TYPE_FACE = 1 << 1, + /** PIN authentication. */ + OH_HUKS_USER_AUTH_TYPE_PIN = 1 << 2, +}; + +/** + * @brief Enumerates the access control types. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_AuthAccessType { + /** The key is invalid after the password is cleared. */ + OH_HUKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD = 1 << 0, + /** The key is invalid after a new biometric feature is enrolled. */ + OH_HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL = 1 << 1, +}; + +/** + * @brief Enumerates the types of the challenges generated when a key is used. + * @see OH_Huks_ChallengePosition + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_ChallengeType { + /** Normal challenge, which is of 32 bytes by default. */ + OH_HUKS_CHALLENGE_TYPE_NORMAL = 0, + /** Custom challenge, which supports only one authentication for multiple keys. + * The valid value of a custom challenge is of 8 bytes. + */ + OH_HUKS_CHALLENGE_TYPE_CUSTOM = 1, + /** Challenge is not required. */ + OH_HUKS_CHALLENGE_TYPE_NONE = 2, +}; + +/** + * @brief Enumerates the positions of the 8-byte valid value in a custom challenge generated. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_ChallengePosition { + /** Bytes 0 to 7. */ + OH_HUKS_CHALLENGE_POS_0 = 0, + /** Bytes 8 to 15. */ + OH_HUKS_CHALLENGE_POS_1, + /** Bytes 16 to 23. */ + OH_HUKS_CHALLENGE_POS_2, + /** Bytes 24 to 31. */ + OH_HUKS_CHALLENGE_POS_3, +}; + +/** + * @brief Enumerates the signature types of the keys generated or imported. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_SecureSignType { + /** + * The signature carries authentication information. This field is specified when a key + * is generated or imported. When the key is used to sign data, the data will be added with + * the authentication information and then be signed. + */ + OH_HUKS_SECURE_SIGN_WITH_AUTHINFO = 1, +}; + +/** + * @brief Enumerates the tag values used in parameter sets. + * + * @since 9 + * @version 1.0 + */ +enum OH_Huks_Tag { + /** Tags for key parameters. The value range is 1 to 200. */ + /** Algorithm. */ + OH_HUKS_TAG_ALGORITHM = OH_HUKS_TAG_TYPE_UINT | 1, + /** Key purpose. */ + OH_HUKS_TAG_PURPOSE = OH_HUKS_TAG_TYPE_UINT | 2, + /** Key size. */ + OH_HUKS_TAG_KEY_SIZE = OH_HUKS_TAG_TYPE_UINT | 3, + /** Digest algorithm. */ + OH_HUKS_TAG_DIGEST = OH_HUKS_TAG_TYPE_UINT | 4, + /** Padding algorithm. */ + OH_HUKS_TAG_PADDING = OH_HUKS_TAG_TYPE_UINT | 5, + /** Cipher mode. */ + OH_HUKS_TAG_BLOCK_MODE = OH_HUKS_TAG_TYPE_UINT | 6, + /** Key type. */ + OH_HUKS_TAG_KEY_TYPE = OH_HUKS_TAG_TYPE_UINT | 7, + /** Associated authentication data. */ + OH_HUKS_TAG_ASSOCIATED_DATA = OH_HUKS_TAG_TYPE_BYTES | 8, + /** Field for key encryption and decryption. */ + OH_HUKS_TAG_NONCE = OH_HUKS_TAG_TYPE_BYTES | 9, + /** Initialized vector (IV). */ + OH_HUKS_TAG_IV = OH_HUKS_TAG_TYPE_BYTES | 10, + + /** Information generated during key derivation. */ + OH_HUKS_TAG_INFO = OH_HUKS_TAG_TYPE_BYTES | 11, + /** Salt value used for key derivation. */ + OH_HUKS_TAG_SALT = OH_HUKS_TAG_TYPE_BYTES | 12, + /** Number of iterations for key derivation. */ + OH_HUKS_TAG_ITERATION = OH_HUKS_TAG_TYPE_UINT | 14, + + /** Type of the generated key. For details, see {@link OH_Huks_KeyGenerateType}. */ + OH_HUKS_TAG_KEY_GENERATE_TYPE = OH_HUKS_TAG_TYPE_UINT | 15, + /** Algorithm used in key agreement. */ + OH_HUKS_TAG_AGREE_ALG = OH_HUKS_TAG_TYPE_UINT | 19, + /** Alias of the public key used for key agreement. */ + OH_HUKS_TAG_AGREE_PUBLIC_KEY_IS_KEY_ALIAS = OH_HUKS_TAG_TYPE_BOOL | 20, + /** Alias of the private key used for key agreement. */ + OH_HUKS_TAG_AGREE_PRIVATE_KEY_ALIAS = OH_HUKS_TAG_TYPE_BYTES | 21, + /** Public key used for key agreement. */ + OH_HUKS_TAG_AGREE_PUBLIC_KEY = OH_HUKS_TAG_TYPE_BYTES | 22, + /** Alias of the key. */ + OH_HUKS_TAG_KEY_ALIAS = OH_HUKS_TAG_TYPE_BYTES | 23, + /** Size of the derived key. */ + OH_HUKS_TAG_DERIVE_KEY_SIZE = OH_HUKS_TAG_TYPE_UINT | 24, + /** Type of the key to import. For details, see {@link OH_Huks_ImportKeyType}. */ + OH_HUKS_TAG_IMPORT_KEY_TYPE = OH_HUKS_TAG_TYPE_UINT | 25, + /** Algorithm suite required for encrypted imports. */ + OH_HUKS_TAG_UNWRAP_ALGORITHM_SUITE = OH_HUKS_TAG_TYPE_UINT | 26, + /** Storage mode of derived or agree keys. For details, see {@link OH_Huks_KeyStorageType}. */ + OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG = OH_HUKS_TAG_TYPE_UINT | 29, + /** Type of rsa pss salt length. */ + OH_HUKS_TAG_RSA_PSS_SALT_LEN_TYPE = OH_HUKS_TAG_TYPE_UINT | 30, + + /** Tags for access control and user authentication. The value range is 301 to 500. */ + /** All users in the multi-user scenario. */ + OH_HUKS_TAG_ALL_USERS = OH_HUKS_TAG_TYPE_BOOL | 301, + /** Multi-user ID. */ + OH_HUKS_TAG_USER_ID = OH_HUKS_TAG_TYPE_UINT | 302, + /** Specifies whether key access control is required. */ + OH_HUKS_TAG_NO_AUTH_REQUIRED = OH_HUKS_TAG_TYPE_BOOL | 303, + /** User authentication type in key access control. */ + OH_HUKS_TAG_USER_AUTH_TYPE = OH_HUKS_TAG_TYPE_UINT | 304, + /** Timeout duration for key access. */ + OH_HUKS_TAG_AUTH_TIMEOUT = OH_HUKS_TAG_TYPE_UINT | 305, + /** Authentication token for the key. */ + OH_HUKS_TAG_AUTH_TOKEN = OH_HUKS_TAG_TYPE_BYTES | 306, + /** + * Access control type. For details, see {@link OH_Huks_AuthAccessType}. + * This parameter must be set together with the user authentication type. + */ + OH_HUKS_TAG_KEY_AUTH_ACCESS_TYPE = OH_HUKS_TAG_TYPE_UINT | 307, + /** Signature type for the key to be generated or imported. */ + OH_HUKS_TAG_KEY_SECURE_SIGN_TYPE = OH_HUKS_TAG_TYPE_UINT | 308, + /** Challenge type. For details, see {@link OH_Huks_ChallengeType}. */ + OH_HUKS_TAG_CHALLENGE_TYPE = OH_HUKS_TAG_TYPE_UINT | 309, + /** + * Position of the 8-byte valid value in a custom challenge. + * For details, see {@link OH_Huks_ChallengePosition}. + */ + OH_HUKS_TAG_CHALLENGE_POS = OH_HUKS_TAG_TYPE_UINT | 310, + + /** Purpose of key authentication */ + OH_HUKS_TAG_KEY_AUTH_PURPOSE = OH_HUKS_TAG_TYPE_UINT | 311, + + /** Tags for key attestation. The value range is 501 to 600. */ + /** Challenge value used in the attestation. */ + OH_HUKS_TAG_ATTESTATION_CHALLENGE = OH_HUKS_TAG_TYPE_BYTES | 501, + /** Application ID used in the attestation. */ + OH_HUKS_TAG_ATTESTATION_APPLICATION_ID = OH_HUKS_TAG_TYPE_BYTES | 502, + /** Alias of the key. */ + OH_HUKS_TAG_ATTESTATION_ID_ALIAS = OH_HUKS_TAG_TYPE_BYTES | 511, + /** Security level used in the attestation. */ + OH_HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO = OH_HUKS_TAG_TYPE_BYTES | 514, + /** Version information used in the attestation. */ + OH_HUKS_TAG_ATTESTATION_ID_VERSION_INFO = OH_HUKS_TAG_TYPE_BYTES | 515, + + /** + * 601 to 1000 are reserved for other tags. + * + * Extended tags. The value range is 1001 to 9999. + */ + /** Specifies whether it is a key alias. */ + OH_HUKS_TAG_IS_KEY_ALIAS = OH_HUKS_TAG_TYPE_BOOL | 1001, + /** Key storage mode. For details, see {@link OH_Huks_KeyStorageType}. */ + OH_HUKS_TAG_KEY_STORAGE_FLAG = OH_HUKS_TAG_TYPE_UINT | 1002, + /** Specifies whether to allow the key to be wrapped. */ + OH_HUKS_TAG_IS_ALLOWED_WRAP = OH_HUKS_TAG_TYPE_BOOL | 1003, + /** Key wrap type. */ + OH_HUKS_TAG_KEY_WRAP_TYPE = OH_HUKS_TAG_TYPE_UINT | 1004, + /** Authentication ID. */ + OH_HUKS_TAG_KEY_AUTH_ID = OH_HUKS_TAG_TYPE_BYTES | 1005, + /** Role of the key. */ + OH_HUKS_TAG_KEY_ROLE = OH_HUKS_TAG_TYPE_UINT | 1006, + /** Key flag. For details, see {@link OH_Huks_KeyFlag}. */ + OH_HUKS_TAG_KEY_FLAG = OH_HUKS_TAG_TYPE_UINT | 1007, + /** Specifies whether this API is asynchronous. */ + OH_HUKS_TAG_IS_ASYNCHRONIZED = OH_HUKS_TAG_TYPE_UINT | 1008, + /** Key domain. */ + OH_HUKS_TAG_KEY_DOMAIN = OH_HUKS_TAG_TYPE_UINT | 1011, + + /** Authenticated Encryption. */ + OH_HUKS_TAG_AE_TAG = OH_HUKS_TAG_TYPE_BYTES | 10009, + + /** + * 11000 to 12000 are reserved. + * + * 20001 to N are reserved for other tags. + */ + /** Symmetric key data. */ + OH_HUKS_TAG_SYMMETRIC_KEY_DATA = OH_HUKS_TAG_TYPE_BYTES | 20001, + /** Public key data of the asymmetric key pair. */ + OH_HUKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA = OH_HUKS_TAG_TYPE_BYTES | 20002, + /** Private key data of the asymmetric key pair. */ + OH_HUKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA = OH_HUKS_TAG_TYPE_BYTES | 20003, +}; + +/** + * @brief Defines the return data, including the result code and message. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Result { + /** Result code. */ + int32_t errorCode; + /** Description of the result code. */ + const char *errorMsg; + /** Other data returned. */ + uint8_t *data; +}; + +/** + * @brief Defines the structure for storing data. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Blob { + /** Data size. */ + uint32_t size; + /** Pointer to the memory in which the data is stored. */ + uint8_t *data; +}; + +/** + * @brief Defines the parameter structure in a parameter set. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_Param { + /** Tag value. */ + uint32_t tag; + + union { + /** Parameter of the Boolean type. */ + bool boolParam; + /** Parameter of the int32_t type. */ + int32_t int32Param; + /** Parameter of the uint32_t type. */ + uint32_t uint32Param; + /** Parameter of the uint64_t type. */ + uint64_t uint64Param; + /** Parameter of the struct OH_Huks_Blob type. */ + struct OH_Huks_Blob blob; + }; +}; + +/** + * @brief Defines the structure of the parameter set. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_ParamSet { + /** Memory size of the parameter set. */ + uint32_t paramSetSize; + /** Number of parameters in the parameter set. */ + uint32_t paramsCnt; + /** Parameter array. */ + struct OH_Huks_Param params[]; +}; + +/** + * @brief Defines the structure of the certificate chain. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_CertChain { + /** Pointer to the certificate data. */ + struct OH_Huks_Blob *certs; + /** Number of certificates. */ + uint32_t certsCount; +}; + +/** + * @brief Defines the key information structure. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_KeyInfo { + /** Alias of the key. */ + struct OH_Huks_Blob alias; + /** Pointer to the key parameter set. */ + struct OH_Huks_ParamSet *paramSet; +}; + +/** + * @brief Defines the structure of a public key. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_PubKeyInfo { + /** Algorithm of the public key. */ + enum OH_Huks_KeyAlg keyAlg; + /** Length of the public key. */ + uint32_t keySize; + /** Length of the n or X value. */ + uint32_t nOrXSize; + /** Length of the e or Y value. */ + uint32_t eOrYSize; + /** Placeholder size. */ + uint32_t placeHolder; +}; + +/** + * @brief Defines the structure of an RSA key. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_KeyMaterialRsa { + /** Algorithm of the key. */ + enum OH_Huks_KeyAlg keyAlg; + /** Length of the key. */ + uint32_t keySize; + /** Length of the n value. */ + uint32_t nSize; + /** Length of the e value. */ + uint32_t eSize; + /** Length of the d value. */ + uint32_t dSize; +}; + +/** + * @brief Defines the structure of an ECC key. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_KeyMaterialEcc { + /** Algorithm of the key. */ + enum OH_Huks_KeyAlg keyAlg; + /** Length of the key. */ + uint32_t keySize; + /** Length of the x value. */ + uint32_t xSize; + /** Length of the y value. */ + uint32_t ySize; + /** Length of the z value. */ + uint32_t zSize; +}; + +/** + * @brief Defines the structure of a DSA key. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_KeyMaterialDsa { + /** Algorithm of the key. */ + enum OH_Huks_KeyAlg keyAlg; + /** Length of the key. */ + uint32_t keySize; + /** Length of the x value. */ + uint32_t xSize; + /** Length of the y value. */ + uint32_t ySize; + /** Length of the p value. */ + uint32_t pSize; + /** Length of the q value. */ + uint32_t qSize; + /** Length of the g value. */ + uint32_t gSize; +}; + +/** + * @brief Defines the structure of a DH key. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_KeyMaterialDh { + /** Algorithm of the key. */ + enum OH_Huks_KeyAlg keyAlg; + /** Length of the DH key. */ + uint32_t keySize; + /** Length of the public key. */ + uint32_t pubKeySize; + /** Length of the private key. */ + uint32_t priKeySize; + /** Reserved. */ + uint32_t reserved; +}; + +/** + * @brief Defines the structure of a 25519 key. + * + * @since 9 + * @version 1.0 + */ +struct OH_Huks_KeyMaterial25519 { + /** Algorithm of the key. */ + enum OH_Huks_KeyAlg keyAlg; + /** Length of the 25519 key. */ + uint32_t keySize; + /** Length of the public key. */ + uint32_t pubKeySize; + /** Length of the private key. */ + uint32_t priKeySize; + /** Reserved. */ + uint32_t reserved; +}; + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* NATIVE_OH_HUKS_TYPE_H */ diff --git a/security/huks/libhuks.ndk.json b/security/huks/libhuks.ndk.json new file mode 100644 index 000000000..a07592c0b --- /dev/null +++ b/security/huks/libhuks.ndk.json @@ -0,0 +1,71 @@ +[ + { + "name": "OH_Huks_GetSdkVersion" + }, + { + "name": "OH_Huks_GenerateKeyItem" + }, + { + "name": "OH_Huks_ImportKeyItem" + }, + { + "name": "OH_Huks_ImportWrappedKeyItem" + }, + { + "name": "OH_Huks_ExportPublicKeyItem" + }, + { + "name": "OH_Huks_DeleteKeyItem" + }, + { + "name": "OH_Huks_GetKeyItemParamSet" + }, + { + "name": "OH_Huks_IsKeyItemExist" + }, + { + "name": "OH_Huks_AttestKeyItem" + }, + { + "name": "OH_Huks_InitSession" + }, + { + "name": "OH_Huks_UpdateSession" + }, + { + "name": "OH_Huks_FinishSession" + }, + { + "name": "OH_Huks_AbortSession" + }, + { + "name": "OH_Huks_InitParamSet" + }, + { + "name": "OH_Huks_AddParams" + }, + { + "name": "OH_Huks_BuildParamSet" + }, + { + "name": "OH_Huks_FreeParamSet" + }, + { + "name": "OH_Huks_CopyParamSet" + }, + { + "name": "OH_Huks_GetParam" + }, + { + "name": "OH_Huks_FreshParamSet" + }, + { + "name": "OH_Huks_IsParamSetTagValid" + }, + { + "name": "OH_Huks_IsParamSetValid" + }, + { + "name": "OH_Huks_CheckParamMatch" + } +] \ No newline at end of file diff --git a/security/huks/src/native_huks_api.c b/security/huks/src/native_huks_api.c new file mode 100644 index 000000000..2a6ab5cd2 --- /dev/null +++ b/security/huks/src/native_huks_api.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "native_huks_api.h" + +#include "hks_api.h" +#include "hks_errcode_adapter.h" +#include "native_huks_api_adapter.h" + +static struct OH_Huks_Result ConvertApiResult(int32_t ret) +{ + struct HksResult result = HksConvertErrCode(ret); + return *((struct OH_Huks_Result *)(&result)); +} + +struct OH_Huks_Result OH_Huks_GetSdkVersion(struct OH_Huks_Blob *sdkVersion) +{ + int32_t result = HksGetSdkVersion((struct HksBlob *) sdkVersion); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_GenerateKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSetIn, struct OH_Huks_ParamSet *paramSetOut) +{ + int32_t result = HksGenerateKey((const struct HksBlob *) keyAlias, + (const struct HksParamSet *) paramSetIn, (struct HksParamSet *) paramSetOut); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_ImportKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *key) +{ + int32_t result = HksImportKey((const struct HksBlob *) keyAlias, + (const struct HksParamSet *) paramSet, (const struct HksBlob *) key); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_ImportWrappedKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_Blob *wrappingKeyAlias, const struct OH_Huks_ParamSet *paramSet, + const struct OH_Huks_Blob *wrappedKeyData) +{ + int32_t result = HksImportWrappedKey((const struct HksBlob *) keyAlias, + (const struct HksBlob *) wrappingKeyAlias, (const struct HksParamSet *) paramSet, + (const struct HksBlob *) wrappedKeyData); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_ExportPublicKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, struct OH_Huks_Blob *key) +{ + int32_t result = HksExportPublicKey((const struct HksBlob *) keyAlias, + (const struct HksParamSet *) paramSet, (struct HksBlob *) key); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_DeleteKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet) +{ + int32_t result = HksDeleteKey((const struct HksBlob *) keyAlias, (const struct HksParamSet *) paramSet); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_GetKeyItemParamSet(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSetIn, struct OH_Huks_ParamSet *paramSetOut) +{ + int32_t result = HksGetKeyParamSet((const struct HksBlob *) keyAlias, + (const struct HksParamSet *) paramSetIn, (struct HksParamSet *) paramSetOut); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_IsKeyItemExist(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet) +{ + int32_t result = HksKeyExist((const struct HksBlob *) keyAlias, (const struct HksParamSet *) paramSet); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_AttestKeyItem(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, struct OH_Huks_CertChain *certChain) +{ + int32_t result = HuksAttestAdapter(keyAlias, paramSet, certChain); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_InitSession(const struct OH_Huks_Blob *keyAlias, + const struct OH_Huks_ParamSet *paramSet, struct OH_Huks_Blob *handle, struct OH_Huks_Blob *token) +{ + int32_t result = HksInit((const struct HksBlob *) keyAlias, + (const struct HksParamSet *) paramSet, (struct HksBlob *) handle, (struct HksBlob *) token); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_UpdateSession(const struct OH_Huks_Blob *handle, + const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *outData) +{ + int32_t result = HksUpdate((const struct HksBlob *) handle, + (const struct HksParamSet *) paramSet, (const struct HksBlob *) inData, (struct HksBlob *) outData); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_FinishSession(const struct OH_Huks_Blob *handle, + const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *outData) +{ + int32_t result = HksFinish((const struct HksBlob *) handle, + (const struct HksParamSet *) paramSet, (const struct HksBlob *) inData, (struct HksBlob *) outData); + return ConvertApiResult(result); +} + +struct OH_Huks_Result OH_Huks_AbortSession(const struct OH_Huks_Blob *handle, + const struct OH_Huks_ParamSet *paramSet) +{ + int32_t result = HksAbort((const struct HksBlob *) handle, (const struct HksParamSet *) paramSet); + return ConvertApiResult(result); +} diff --git a/security/huks/src/native_huks_api_adapter.c b/security/huks/src/native_huks_api_adapter.c new file mode 100644 index 000000000..792b6b50e --- /dev/null +++ b/security/huks/src/native_huks_api_adapter.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "hks_api.h" +#include "hks_param.h" + +#include "native_huks_api_adapter.h" +#include "native_huks_param.h" + +int32_t HuksAttestAdapter(const struct OH_Huks_Blob *keyAlias, const struct OH_Huks_ParamSet *paramSet, + struct OH_Huks_CertChain *certChain) +{ + int32_t ret; + struct HksParamSet *newParamSet = NULL; + do { + if (paramSet == NULL) { + ret = HKS_ERROR_NULL_POINTER; + break; + } + ret = HksCheckParamSet((struct HksParamSet *)paramSet, paramSet->paramSetSize); + if (ret != HKS_SUCCESS) { + break; + } + ret = HksInitParamSet(&newParamSet); + if (ret != HKS_SUCCESS) { + break; + } + ret = HksFreshParamSet((struct HksParamSet *)paramSet, false); + if (ret != HKS_SUCCESS) { + break; + } + ret = HksAddParams(newParamSet, (const struct HksParam *)paramSet->params, paramSet->paramsCnt); + if (ret != HKS_SUCCESS) { + break; + } + struct HksParam isBase64Param = { .tag = HKS_TAG_ATTESTATION_BASE64, .boolParam = true }; + ret = HksAddParams(newParamSet, &isBase64Param, 1); + if (ret != HKS_SUCCESS) { + break; + } + ret = HksBuildParamSet(&newParamSet); + if (ret != HKS_SUCCESS) { + break; + } + ret = HksAttestKey((const struct HksBlob *)keyAlias, (struct HksParamSet *)newParamSet, + (struct HksCertChain *)certChain); + } while (0); + HksFreeParamSet(&newParamSet); + return ret; +} \ No newline at end of file diff --git a/security/huks/src/native_huks_param.c b/security/huks/src/native_huks_param.c new file mode 100644 index 000000000..9fab8b6c4 --- /dev/null +++ b/security/huks/src/native_huks_param.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include "native_huks_param.h" + +#include "hks_param.h" +#include "hks_errcode_adapter.h" + +static struct OH_Huks_Result ConvertParamResult(int32_t ret) +{ + struct HksResult result = HksConvertErrCode(ret); + return *((struct OH_Huks_Result *)(&result)); +} + +struct OH_Huks_Result OH_Huks_InitParamSet(struct OH_Huks_ParamSet **paramSet) +{ + int32_t result = HksInitParamSet((struct HksParamSet **) paramSet); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_AddParams(struct OH_Huks_ParamSet *paramSet, + const struct OH_Huks_Param *params, uint32_t paramCnt) +{ + int32_t result = HksAddParams((struct HksParamSet *) paramSet, + (const struct HksParam *) params, paramCnt); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_BuildParamSet(struct OH_Huks_ParamSet **paramSet) +{ + int32_t result = HksBuildParamSet((struct HksParamSet **) paramSet); + return ConvertParamResult(result); +} + +void OH_Huks_FreeParamSet(struct OH_Huks_ParamSet **paramSet) +{ + HksFreeParamSet((struct HksParamSet **) paramSet); +} + +struct OH_Huks_Result OH_Huks_CopyParamSet(const struct OH_Huks_ParamSet *fromParamSet, + uint32_t fromParamSetSize, struct OH_Huks_ParamSet **paramSet) +{ + int32_t result = HksGetParamSet((const struct HksParamSet *) fromParamSet, + fromParamSetSize, (struct HksParamSet **) paramSet); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_GetParam(const struct OH_Huks_ParamSet *paramSet, uint32_t tag, + struct OH_Huks_Param **param) +{ + int32_t result = HksGetParam((const struct HksParamSet *) paramSet, tag, (struct HksParam **) param); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_FreshParamSet(struct OH_Huks_ParamSet *paramSet, bool isCopy) +{ + int32_t result = HksFreshParamSet((struct HksParamSet *) paramSet, isCopy); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_IsParamSetTagValid(const struct OH_Huks_ParamSet *paramSet) +{ + int32_t result = HksCheckParamSetTag((const struct HksParamSet *) paramSet); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_IsParamSetValid(const struct OH_Huks_ParamSet *paramSet, uint32_t size) +{ + int32_t result = HksCheckParamSet((const struct HksParamSet *) paramSet, size); + return ConvertParamResult(result); +} + +struct OH_Huks_Result OH_Huks_CheckParamMatch(const struct OH_Huks_Param *baseParam, const struct OH_Huks_Param *param) +{ + int32_t result = HksCheckParamMatch((const struct HksParam *) baseParam, (const struct HksParam *) param); + return ConvertParamResult(result); +} diff --git a/startup/init/syscap/BUILD.gn b/startup/init/syscap/BUILD.gn new file mode 100644 index 000000000..715c6cf41 --- /dev/null +++ b/startup/init/syscap/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_shared_library("deviceinfo_ndk") { + cflags = [ "-fstack-protector-all" ] + sources = [ + "src/deviceinfo.c", + "src/syscap_ndk.c", + ] + include_dirs = [ "./include" ] + deps = [ "//base/startup/init/interfaces/innerkits:libbegetutil" ] + part_name = "init" + subsystem_name = "startup" +} + +ohos_ndk_library("libdeviceinfo_ndk") { + cflags = [ "-fstack-protector-all" ] + output_name = "deviceinfo_ndk" + ndk_description_file = "./libdeviceinfo.ndk.json" + min_compact_version = "1" +} + +ohos_ndk_headers("deviceinfo_header") { + dest_dir = "$ndk_headers_out_dir/" + sources = [ + "./include/deviceinfo.h", + "./include/syscap_ndk.h", + ] +} diff --git a/startup/init/syscap/include/deviceinfo.h b/startup/init/syscap/include/deviceinfo.h new file mode 100644 index 000000000..cc1a504ff --- /dev/null +++ b/startup/init/syscap/include/deviceinfo.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef DEVICEINFO_CSDK_H +#define DEVICEINFO_CSDK_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/** + * Obtains the device type represented by a string, + * which can be {@code phone} (or {@code default} for phones), {@code wearable}, {@code liteWearable}, + * {@code tablet}, {@code tv}, {@code car}, or {@code smartVision}. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetDeviceType(void); + +/** + * Obtains the device manufacturer represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetManufacture(void); + +/** + * Obtains the device brand represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBrand(void); + +/** + * Obtains the external product series represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetMarketName(void); + +/** + * Obtains the product series represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetProductSeries(void); + +/** + * Obtains the product model represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetProductModel(void); + +/** + * Obtains the software model represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetSoftwareModel(void); + +/** + * Obtains the hardware model represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetHardwareModel(void); + +/** + * Obtains the bootloader version number represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBootloaderVersion(void); + +/** + * Obtains the application binary interface (Abi) list represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetAbiList(void); + +/** + * Obtains the security patch level represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetSecurityPatchTag(void); + +/** + * Obtains the product version represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetDisplayVersion(void); + +/** + * Obtains the incremental version represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetIncrementalVersion(void); + +/** + * Obtains the OS release type represented by a string. + * + *

The OS release category can be {@code Release}, {@code Beta}, or {@code Canary}. + * The specific release type may be {@code Release}, {@code Beta1}, or others alike. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetOsReleaseType(void); + +/** + * Obtains the OS version represented by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetOSFullName(void); + +/** + * Obtains the SDK API version number. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +int OH_GetSdkApiVersion(void); + +/** + * Obtains the first API version number. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +int OH_GetFirstApiVersion(void); + +/** + * Obtains the version ID by a string. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetVersionId(void); + +/** + * Obtains the build types of the same baseline code. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBuildType(void); + +/** + * Obtains the different build user of the same baseline code. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBuildUser(void); + +/** + * Obtains the different build host of the same baseline code. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBuildHost(void); + +/** + * Obtains the build time. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBuildTime(void); + +/** + * Obtains the version hash. + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetBuildRootHash(void); + +/** + * Obtains the Distribution OS name represented by a string. + * + *

Independent Software Vendor (ISV) may distribute OHOS with their own OS name. + * If ISV not specified, it will return an empty string + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetDistributionOSName(void); + +/** + * Obtains the ISV distribution OS version represented by a string. + * If ISV not specified, it will return the same value as OH_GetOSFullName + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetDistributionOSVersion(void); + +/** + * Obtains the ISV distribution OS api version represented by a integer. + * If ISV not specified, it will return the same value as OH_GetSdkApiVersion + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +int OH_GetDistributionOSApiVersion(void); + +/** + * Obtains the ISV distribution OS release type represented by a string. + * If ISV not specified, it will return the same value as OH_GetOsReleaseType + * @syscap SystemCapability.Startup.SystemInfo + * @since 10 + */ +const char *OH_GetDistributionOSReleaseType(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif diff --git a/startup/init/syscap/include/syscap_ndk.h b/startup/init/syscap/include/syscap_ndk.h new file mode 100644 index 000000000..070a6cb1e --- /dev/null +++ b/startup/init/syscap/include/syscap_ndk.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef SYSCAP_NDK_H +#define SYSCAP_NDK_H + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +bool canIUse(const char *cap); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/startup/init/syscap/init_sync.h b/startup/init/syscap/init_sync.h new file mode 100644 index 000000000..ceeefbce3 --- /dev/null +++ b/startup/init/syscap/init_sync.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef BASE_STARTUP_INITLITE_NOTIFY_H +#define BASE_STARTUP_INITLITE_NOTIFY_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define EVENT1 0xf +#define EVENT1_WAITTIME 10000 // 10s = 10*1000 * 1 tick(1ms) + +#define EVENT2 0xf0 +/* Define EVENT2_WAITTIME 0 means QS_STAGE2 is no used */ +#define EVENT2_WAITTIME 0 + +#define EVENT3 0xf00 +/* Define EVENT3_WAITTIME 0 means QS_STAGE3 is no used */ +#define EVENT3_WAITTIME 0 + +/* + * Notify the event to Init process. + * All processes can call. Usually called by the listened process. + * event: There needs to be a consensus between the listener(init process) and the notifier. + */ +extern int NotifyInit(unsigned long event); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_INITLITE_NOTIFY_H diff --git a/startup/init/syscap/libdeviceinfo.ndk.json b/startup/init/syscap/libdeviceinfo.ndk.json new file mode 100644 index 000000000..dfed92796 --- /dev/null +++ b/startup/init/syscap/libdeviceinfo.ndk.json @@ -0,0 +1,30 @@ +[ + {"name": "canIUse"}, + {"name": "OH_GetDeviceType"}, + {"name": "OH_GetManufacture"}, + {"name": "OH_GetBrand"}, + {"name": "OH_GetMarketName"}, + {"name": "OH_GetProductSeries"}, + {"name": "OH_GetProductModel"}, + {"name": "OH_GetSoftwareModel"}, + {"name": "OH_GetHardwareModel"}, + {"name": "OH_GetBootloaderVersion"}, + {"name": "OH_GetAbiList"}, + {"name": "OH_GetSecurityPatchTag"}, + {"name": "OH_GetDisplayVersion"}, + {"name": "OH_GetIncrementalVersion"}, + {"name": "OH_GetOsReleaseType"}, + {"name": "OH_GetOSFullName"}, + {"name": "OH_GetSdkApiVersion"}, + {"name": "OH_GetFirstApiVersion"}, + {"name": "OH_GetVersionId"}, + {"name": "OH_GetBuildType"}, + {"name": "OH_GetBuildUser"}, + {"name": "OH_GetBuildHost"}, + {"name": "OH_GetBuildTime"}, + {"name": "OH_GetBuildRootHash"}, + {"name": "OH_GetDistributionOSName"}, + {"name": "OH_GetDistributionOSVersion"}, + {"name": "OH_GetDistributionOSApiVersion"}, + {"name": "OH_GetDistributionOSReleaseType"} +] diff --git a/startup/init/syscap/src/deviceinfo.c b/startup/init/syscap/src/deviceinfo.c new file mode 100644 index 000000000..aca89b5cb --- /dev/null +++ b/startup/init/syscap/src/deviceinfo.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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. + */ +#include "parameter.h" + +const char *OH_GetDeviceType(void) +{ + return GetDeviceType(); +} + +const char *OH_GetManufacture(void) +{ + return GetManufacture(); +} + +const char *OH_GetBrand(void) +{ + return GetBrand(); +} + +const char *OH_GetMarketName(void) +{ + return GetMarketName(); +} + +const char *OH_GetProductSeries(void) +{ + return GetProductSeries(); +} + +const char *OH_GetProductModel(void) +{ + return GetProductModel(); +} + +const char *OH_GetSoftwareModel(void) +{ + return GetSoftwareModel(); +} + +const char *OH_GetHardwareModel(void) +{ + return GetHardwareModel(); +} + +const char *OH_GetBootloaderVersion(void) +{ + return GetBootloaderVersion(); +} + +const char *OH_GetAbiList(void) +{ + return GetAbiList(); +} + +const char *OH_GetSecurityPatchTag(void) +{ + return GetSecurityPatchTag(); +} + +const char *OH_GetDisplayVersion(void) +{ + return GetDisplayVersion(); +} + +const char *OH_GetIncrementalVersion(void) +{ + return GetIncrementalVersion(); +} + +const char *OH_GetOsReleaseType(void) +{ + return GetOsReleaseType(); +} + +const char *OH_GetOSFullName(void) +{ + return GetOSFullName(); +} + +int OH_GetSdkApiVersion(void) +{ + return GetSdkApiVersion(); +} + +int OH_GetFirstApiVersion(void) +{ + return GetFirstApiVersion(); +} + +const char *OH_GetVersionId(void) +{ + return GetVersionId(); +} + +const char *OH_GetBuildType(void) +{ + return GetBuildType(); +} + +const char *OH_GetBuildUser(void) +{ + return GetBuildUser(); +} + +const char *OH_GetBuildHost(void) +{ + return GetBuildHost(); +} + +const char *OH_GetBuildTime(void) +{ + return GetBuildTime(); +} + +const char *OH_GetBuildRootHash(void) +{ + return GetBuildRootHash(); +} + +const char *OH_GetDistributionOSName(void) +{ + return GetDistributionOSName(); +} + +const char *OH_GetDistributionOSVersion(void) +{ + return GetDistributionOSVersion(); +} + +int OH_GetDistributionOSApiVersion(void) +{ + return GetDistributionOSApiVersion(); +} + +const char *OH_GetDistributionOSReleaseType(void) +{ + return GetDistributionOSReleaseType(); +} diff --git a/startup/init/syscap/src/syscap_ndk.c b/startup/init/syscap/src/syscap_ndk.c new file mode 100644 index 000000000..ece845472 --- /dev/null +++ b/startup/init/syscap/src/syscap_ndk.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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. + */ + +#include +#include "systemcapability.h" +#include "syscap_ndk.h" + +bool canIUse(const char *cap) +{ + return HasSystemCapability(cap); +} diff --git a/third_party/libuv/BUILD.gn b/third_party/libuv/BUILD.gn new file mode 100644 index 000000000..6b4a49b2c --- /dev/null +++ b/third_party/libuv/BUILD.gn @@ -0,0 +1,375 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +if (defined(ohos_lite)) { + import("//build/lite/config/component/lite_component.gni") + import("//build/lite/ndk/ndk.gni") + import("//third_party/libuv/libuv.gni") + + # This is the configuration needed to use libuv. + config("libuv_config") { + include_dirs = [ + "include", + "src", + "src/unix", + ] + cflags = [ + "-Wno-unused-parameter", + "-Wno-incompatible-pointer-types", + "-D_GNU_SOURCE", + "-D_POSIX_C_SOURCE=200112", + ] + + # Adding NDEBUG macro manually to avoid compilation + # error in debug version, FIX ME + # https://gitee.com/openharmony/build/pulls/1206/files + defines += [ "NDEBUG" ] + } + + # This is the configuration used to build libuv itself. + # It should not be needed outside of this library. + config("libuv_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "src", + "src/unix", + ] + + # Adding NDEBUG macro manually to avoid compilation + # error in debug version, FIX ME + # https://gitee.com/openharmony/build/pulls/1206/files + defines += [ "NDEBUG" ] + } + + source_set("libuv_source") { + include_dirs = [ + "include", + "src", + "src/unix", + ] + + cflags = [ + "-Wno-unused-parameter", + "-Wno-incompatible-pointer-types", + "-D_GNU_SOURCE", + "-D_POSIX_C_SOURCE=200112", + "-U__linux__", + "-D__GNU__", + "-fPIC", + ] + + sources = [ + # common_source + "src/fs-poll.c", + "src/idna.c", + "src/inet.c", + "src/random.c", + "src/strscpy.c", + "src/threadpool.c", + "src/timer.c", + "src/uv-common.c", + "src/uv-data-getter-setters.c", + "src/version.c", + + # nonwin_srcs + "src/unix/async.c", + "src/unix/core.c", + "src/unix/dl.c", + "src/unix/epoll.c", + "src/unix/fs.c", + "src/unix/getaddrinfo.c", + "src/unix/getnameinfo.c", + "src/unix/loop-watcher.c", + "src/unix/loop.c", + "src/unix/no-fsevents.c", + "src/unix/pipe.c", + "src/unix/poll.c", + "src/unix/posix-hrtime.c", + "src/unix/posix-poll.c", + "src/unix/process.c", + "src/unix/random-devurandom.c", + "src/unix/signal.c", + "src/unix/stream.c", + "src/unix/tcp.c", + "src/unix/thread.c", + "src/unix/tty.c", + "src/unix/udp.c", + ] + } + + static_library("uv_static") { + deps = [ ":libuv_source" ] + public_configs = [ ":libuv_config" ] + } + + shared_library("uv") { + deps = [ ":libuv_source" ] + public_configs = [ ":libuv_config" ] + libs = [ + "pthread", + "dl", + ] + } +} else { + import("//build/ohos.gni") + import("//third_party/libuv/libuv.gni") + + common_source = [ + "src/fs-poll.c", + "src/idna.c", + "src/inet.c", + "src/random.c", + "src/strscpy.c", + "src/threadpool.c", + "src/timer.c", + "src/uv-common.c", + "src/uv-data-getter-setters.c", + "src/version.c", + ] + if (!is_mingw && !is_win) { + nonwin_srcs = [ + "src/unix/epoll.c", + "src/unix/async.c", + "src/unix/core.c", + "src/unix/dl.c", + "src/unix/fs.c", + "src/unix/getaddrinfo.c", + "src/unix/getnameinfo.c", + "src/unix/loop.c", + "src/unix/loop-watcher.c", + "src/unix/pipe.c", + "src/unix/poll.c", + "src/unix/process.c", + "src/unix/random-devurandom.c", + "src/unix/signal.c", + "src/unix/stream.c", + "src/unix/tcp.c", + "src/unix/thread.c", + "src/unix/tty.c", + "src/unix/udp.c", + ] + } + + # This is the configuration needed to use libuv. + config("libuv_config") { + include_dirs = [ + "include", + "src", + "src/unix", + ] + cflags = [ "-Wno-unused-parameter" ] + if (is_linux || is_ohos) { + cflags += [ + "-Wno-incompatible-pointer-types", + "-D_GNU_SOURCE", + "-D_POSIX_C_SOURCE=200112", + ] + + # Adding NDEBUG macro manually to avoid compilation + # error in debug version, FIX ME + # https://gitee.com/openharmony/build/pulls/1206/files + defines = [ "NDEBUG" ] + if (use_ffrt && is_ohos) { + defines += [ "USE_FFRT" ] + } + } else if (is_mingw || is_win) { + cflags += [ + "-Wno-missing-braces", + "-Wno-implicit-function-declaration", + "-Wno-error=return-type", + "-Wno-error=sign-compare", + "-Wno-error=unused-variable", + "-Wno-error=unknown-pragmas", + "-Wno-unused-variable", + ] + defines = [ + "WIN32_LEAN_AND_MEAN", + "_WIN32_WINNT=0x0600", + ] + + # Adding NDEBUG macro manually to avoid compilation + # error in debug version, FIX ME + # https://gitee.com/openharmony/build/pulls/1206/files + defines += [ "NDEBUG" ] + + libs = [ + "psapi", + "user32", + "advapi32", + "iphlpapi", + "userenv", + "ws2_32", + ] + } + } + + # This is the configuration used to build libuv itself. + # It should not be needed outside of this library. + config("libuv_private_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "src", + "src/unix", + ] + + # Adding NDEBUG macro manually to avoid compilation + # error in debug version, FIX ME + # https://gitee.com/openharmony/build/pulls/1206/files + defines = [ "NDEBUG" ] + } + + ohos_source_set("libuv_source") { + configs = [ ":libuv_config" ] + sources = common_source + + if (is_mac || (defined(is_ios) && is_ios)) { + sources += nonwin_srcs + [ + "src/unix/bsd-ifaddrs.c", + "src/unix/kqueue.c", + "src/unix/random-getentropy.c", + "src/unix/darwin-proctitle.c", + "src/unix/darwin.c", + "src/unix/fsevents.c", + "src/unix/os390-proctitle.c", + ] + sources -= [ "src/unix/epoll.c" ] + } else if (is_mingw || is_win) { + sources += [ + "src/win/async.c", + "src/win/core.c", + "src/win/detect-wakeup.c", + "src/win/dl.c", + "src/win/error.c", + "src/win/fs-event.c", + "src/win/fs.c", + "src/win/getaddrinfo.c", + "src/win/getnameinfo.c", + "src/win/handle.c", + "src/win/loop-watcher.c", + "src/win/pipe.c", + "src/win/poll.c", + "src/win/process-stdio.c", + "src/win/process.c", + "src/win/signal.c", + "src/win/snprintf.c", + "src/win/stream.c", + "src/win/tcp.c", + "src/win/thread.c", + "src/win/tty.c", + "src/win/udp.c", + "src/win/util.c", + "src/win/winapi.c", + "src/win/winsock.c", + ] + } else if (is_ohos || (defined(is_android) && is_android)) { + sources += nonwin_srcs + [ + "src/unix/linux-core.c", + "src/unix/linux-inotify.c", + "src/unix/linux-syscalls.c", + "src/unix/procfs-exepath.c", + "src/unix/pthread-fixes.c", + "src/unix/random-getentropy.c", + "src/unix/random-getrandom.c", + "src/unix/random-sysctl-linux.c", + "src/unix/proctitle.c", + ] + if (use_ffrt) { + external_deps = [ "ffrt:libffrt" ] + } + } else if (is_linux) { + sources += nonwin_srcs + [ + "src/unix/linux-core.c", + "src/unix/linux-inotify.c", + "src/unix/linux-syscalls.c", + "src/unix/procfs-exepath.c", + "src/unix/random-getrandom.c", + "src/unix/random-sysctl-linux.c", + "src/unix/proctitle.c", + ] + } else { + sources += nonwin_srcs + [ + "src/unix/linux-core.c", + "src/unix/linux-inotify.c", + "src/unix/linux-syscalls.c", + "src/unix/procfs-exepath.c", + "src/unix/random-getrandom.c", + "src/unix/random-sysctl-linux.c", + "src/unix/proctitle.c", + ] + } + subsystem_name = "thirdparty" + part_name = "libuv" + } + + ohos_static_library("uv_static") { + deps = [ ":libuv_source" ] + public_configs = [ ":libuv_config" ] + subsystem_name = "thirdparty" + part_name = "libuv" + } + ohos_shared_library("uv") { + deps = [ ":libuv_source" ] + public_configs = [ ":libuv_config" ] + subsystem_name = "thirdparty" + innerapi_tags = [ "platformsdk" ] + part_name = "libuv" + if (is_ohos) { + output_extension = "so" + } + install_images = [ + "system", + "updater", + ] + } +} + +ohos_ndk_library("libuv_ndk") { + ndk_description_file = "./libuv.ndk.json" + min_compact_version = "1" + output_name = "uv" + output_extension = "so" +} + +ohos_ndk_headers("libuv_header") { + dest_dir = "$ndk_headers_out_dir" + sources = [ "include/uv_ndk/uv.h" ] +} + +ohos_ndk_headers("libuv_uv_header") { + dest_dir = "$ndk_headers_out_dir/uv" + sources = [ + "include/uv/aix.h", + "include/uv/bsd.h", + "include/uv/darwin.h", + "include/uv/errno.h", + "include/uv/linux.h", + "include/uv/os390.h", + "include/uv/posix.h", + "include/uv/stdint-msvc2008.h", + "include/uv/sunos.h", + "include/uv/threadpool.h", + "include/uv/tree.h", + "include/uv/unix.h", + "include/uv/version.h", + "include/uv/win.h", + ] +} diff --git a/third_party/libuv/include/uv.h b/third_party/libuv/include/uv.h new file mode 100644 index 000000000..bd5976730 --- /dev/null +++ b/third_party/libuv/include/uv.h @@ -0,0 +1,1862 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* See https://github.com/libuv/libuv#documentation for documentation. */ + +#ifndef UV_H +#define UV_H +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED) +#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both." +#endif + +#ifdef _WIN32 + /* Windows - set up dll import/export decorators. */ +# if defined(BUILDING_UV_SHARED) + /* Building shared library. */ +# define UV_EXTERN __declspec(dllexport) +# elif defined(USING_UV_SHARED) + /* Using shared library. */ +# define UV_EXTERN __declspec(dllimport) +# else + /* Building static library. */ +# define UV_EXTERN /* nothing */ +# endif +#elif __GNUC__ >= 4 +# define UV_EXTERN __attribute__((visibility("default"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) /* Sun Studio >= 8 */ +# define UV_EXTERN __global +#else +# define UV_EXTERN /* nothing */ +#endif + +#include "uv/errno.h" +#include "uv/version.h" +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#if defined(_WIN32) +# include "uv/win.h" +#else +# include "uv/unix.h" +#endif + +/* Expand this list if necessary. */ +#define UV_ERRNO_MAP(XX) \ + XX(E2BIG, "argument list too long") \ + XX(EACCES, "permission denied") \ + XX(EADDRINUSE, "address already in use") \ + XX(EADDRNOTAVAIL, "address not available") \ + XX(EAFNOSUPPORT, "address family not supported") \ + XX(EAGAIN, "resource temporarily unavailable") \ + XX(EAI_ADDRFAMILY, "address family not supported") \ + XX(EAI_AGAIN, "temporary failure") \ + XX(EAI_BADFLAGS, "bad ai_flags value") \ + XX(EAI_BADHINTS, "invalid value for hints") \ + XX(EAI_CANCELED, "request canceled") \ + XX(EAI_FAIL, "permanent failure") \ + XX(EAI_FAMILY, "ai_family not supported") \ + XX(EAI_MEMORY, "out of memory") \ + XX(EAI_NODATA, "no address") \ + XX(EAI_NONAME, "unknown node or service") \ + XX(EAI_OVERFLOW, "argument buffer overflow") \ + XX(EAI_PROTOCOL, "resolved protocol is unknown") \ + XX(EAI_SERVICE, "service not available for socket type") \ + XX(EAI_SOCKTYPE, "socket type not supported") \ + XX(EALREADY, "connection already in progress") \ + XX(EBADF, "bad file descriptor") \ + XX(EBUSY, "resource busy or locked") \ + XX(ECANCELED, "operation canceled") \ + XX(ECHARSET, "invalid Unicode character") \ + XX(ECONNABORTED, "software caused connection abort") \ + XX(ECONNREFUSED, "connection refused") \ + XX(ECONNRESET, "connection reset by peer") \ + XX(EDESTADDRREQ, "destination address required") \ + XX(EEXIST, "file already exists") \ + XX(EFAULT, "bad address in system call argument") \ + XX(EFBIG, "file too large") \ + XX(EHOSTUNREACH, "host is unreachable") \ + XX(EINTR, "interrupted system call") \ + XX(EINVAL, "invalid argument") \ + XX(EIO, "i/o error") \ + XX(EISCONN, "socket is already connected") \ + XX(EISDIR, "illegal operation on a directory") \ + XX(ELOOP, "too many symbolic links encountered") \ + XX(EMFILE, "too many open files") \ + XX(EMSGSIZE, "message too long") \ + XX(ENAMETOOLONG, "name too long") \ + XX(ENETDOWN, "network is down") \ + XX(ENETUNREACH, "network is unreachable") \ + XX(ENFILE, "file table overflow") \ + XX(ENOBUFS, "no buffer space available") \ + XX(ENODEV, "no such device") \ + XX(ENOENT, "no such file or directory") \ + XX(ENOMEM, "not enough memory") \ + XX(ENONET, "machine is not on the network") \ + XX(ENOPROTOOPT, "protocol not available") \ + XX(ENOSPC, "no space left on device") \ + XX(ENOSYS, "function not implemented") \ + XX(ENOTCONN, "socket is not connected") \ + XX(ENOTDIR, "not a directory") \ + XX(ENOTEMPTY, "directory not empty") \ + XX(ENOTSOCK, "socket operation on non-socket") \ + XX(ENOTSUP, "operation not supported on socket") \ + XX(EOVERFLOW, "value too large for defined data type") \ + XX(EPERM, "operation not permitted") \ + XX(EPIPE, "broken pipe") \ + XX(EPROTO, "protocol error") \ + XX(EPROTONOSUPPORT, "protocol not supported") \ + XX(EPROTOTYPE, "protocol wrong type for socket") \ + XX(ERANGE, "result too large") \ + XX(EROFS, "read-only file system") \ + XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \ + XX(ESPIPE, "invalid seek") \ + XX(ESRCH, "no such process") \ + XX(ETIMEDOUT, "connection timed out") \ + XX(ETXTBSY, "text file is busy") \ + XX(EXDEV, "cross-device link not permitted") \ + XX(UNKNOWN, "unknown error") \ + XX(EOF, "end of file") \ + XX(ENXIO, "no such device or address") \ + XX(EMLINK, "too many links") \ + XX(EHOSTDOWN, "host is down") \ + XX(EREMOTEIO, "remote I/O error") \ + XX(ENOTTY, "inappropriate ioctl for device") \ + XX(EFTYPE, "inappropriate file type or format") \ + XX(EILSEQ, "illegal byte sequence") \ + XX(ESOCKTNOSUPPORT, "socket type not supported") \ + +#define UV_HANDLE_TYPE_MAP(XX) \ + XX(ASYNC, async) \ + XX(CHECK, check) \ + XX(FS_EVENT, fs_event) \ + XX(FS_POLL, fs_poll) \ + XX(HANDLE, handle) \ + XX(IDLE, idle) \ + XX(NAMED_PIPE, pipe) \ + XX(POLL, poll) \ + XX(PREPARE, prepare) \ + XX(PROCESS, process) \ + XX(STREAM, stream) \ + XX(TCP, tcp) \ + XX(TIMER, timer) \ + XX(TTY, tty) \ + XX(UDP, udp) \ + XX(SIGNAL, signal) \ + +#define UV_REQ_TYPE_MAP(XX) \ + XX(REQ, req) \ + XX(CONNECT, connect) \ + XX(WRITE, write) \ + XX(SHUTDOWN, shutdown) \ + XX(UDP_SEND, udp_send) \ + XX(FS, fs) \ + XX(WORK, work) \ + XX(GETADDRINFO, getaddrinfo) \ + XX(GETNAMEINFO, getnameinfo) \ + XX(RANDOM, random) \ + +typedef enum { +#define XX(code, _) UV_ ## code = UV__ ## code, + UV_ERRNO_MAP(XX) +#undef XX + UV_ERRNO_MAX = UV__EOF - 1 +} uv_errno_t; + +typedef enum { + UV_UNKNOWN_HANDLE = 0, +#define XX(uc, lc) UV_##uc, + UV_HANDLE_TYPE_MAP(XX) +#undef XX + UV_FILE, + UV_HANDLE_TYPE_MAX +} uv_handle_type; + +typedef enum { + UV_UNKNOWN_REQ = 0, +#define XX(uc, lc) UV_##uc, + UV_REQ_TYPE_MAP(XX) +#undef XX + UV_REQ_TYPE_PRIVATE + UV_REQ_TYPE_MAX +} uv_req_type; + + +/* Handle types. */ +typedef struct uv_loop_s uv_loop_t; +typedef struct uv_handle_s uv_handle_t; +typedef struct uv_dir_s uv_dir_t; +typedef struct uv_stream_s uv_stream_t; +typedef struct uv_tcp_s uv_tcp_t; +typedef struct uv_udp_s uv_udp_t; +typedef struct uv_pipe_s uv_pipe_t; +typedef struct uv_tty_s uv_tty_t; +typedef struct uv_poll_s uv_poll_t; +typedef struct uv_timer_s uv_timer_t; +typedef struct uv_prepare_s uv_prepare_t; +typedef struct uv_check_s uv_check_t; +typedef struct uv_idle_s uv_idle_t; +typedef struct uv_async_s uv_async_t; +typedef struct uv_process_s uv_process_t; +typedef struct uv_fs_event_s uv_fs_event_t; +typedef struct uv_fs_poll_s uv_fs_poll_t; +typedef struct uv_signal_s uv_signal_t; + +/* Request types. */ +typedef struct uv_req_s uv_req_t; +typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; +typedef struct uv_getnameinfo_s uv_getnameinfo_t; +typedef struct uv_shutdown_s uv_shutdown_t; +typedef struct uv_write_s uv_write_t; +typedef struct uv_connect_s uv_connect_t; +typedef struct uv_udp_send_s uv_udp_send_t; +typedef struct uv_fs_s uv_fs_t; +typedef struct uv_work_s uv_work_t; +typedef struct uv_random_s uv_random_t; + +/* None of the above. */ +typedef struct uv_env_item_s uv_env_item_t; +typedef struct uv_cpu_info_s uv_cpu_info_t; +typedef struct uv_interface_address_s uv_interface_address_t; +typedef struct uv_dirent_s uv_dirent_t; +typedef struct uv_passwd_s uv_passwd_t; +typedef struct uv_utsname_s uv_utsname_t; +typedef struct uv_statfs_s uv_statfs_t; + +typedef enum { + UV_LOOP_BLOCK_SIGNAL = 0, + UV_METRICS_IDLE_TIME +} uv_loop_option; + +typedef enum { + UV_RUN_DEFAULT = 0, + UV_RUN_ONCE, + UV_RUN_NOWAIT +} uv_run_mode; + + +UV_EXTERN unsigned int uv_version(void); +UV_EXTERN const char* uv_version_string(void); + +typedef void* (*uv_malloc_func)(size_t size); +typedef void* (*uv_realloc_func)(void* ptr, size_t size); +typedef void* (*uv_calloc_func)(size_t count, size_t size); +typedef void (*uv_free_func)(void* ptr); + +UV_EXTERN void uv_library_shutdown(void); + +UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func, + uv_realloc_func realloc_func, + uv_calloc_func calloc_func, + uv_free_func free_func); + +UV_EXTERN uv_loop_t* uv_default_loop(void); +UV_EXTERN int uv_loop_init(uv_loop_t* loop); +UV_EXTERN int uv_loop_close(uv_loop_t* loop); +/* + * NOTE: + * This function is DEPRECATED (to be removed after 0.12), users should + * allocate the loop manually and use uv_loop_init instead. + */ +UV_EXTERN uv_loop_t* uv_loop_new(void); +/* + * NOTE: + * This function is DEPRECATED (to be removed after 0.12). Users should use + * uv_loop_close and free the memory manually instead. + */ +UV_EXTERN void uv_loop_delete(uv_loop_t*); +UV_EXTERN size_t uv_loop_size(void); +UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); +UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); +UV_EXTERN int uv_loop_fork(uv_loop_t* loop); + +UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); +UV_EXTERN void uv_stop(uv_loop_t*); + +UV_EXTERN void uv_ref(uv_handle_t*); +UV_EXTERN void uv_unref(uv_handle_t*); +UV_EXTERN int uv_has_ref(const uv_handle_t*); + +UV_EXTERN void uv_update_time(uv_loop_t*); +UV_EXTERN uint64_t uv_now(const uv_loop_t*); + +UV_EXTERN int uv_backend_fd(const uv_loop_t*); +UV_EXTERN int uv_backend_timeout(const uv_loop_t*); + +typedef void (*uv_alloc_cb)(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf); +typedef void (*uv_read_cb)(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf); +typedef void (*uv_write_cb)(uv_write_t* req, int status); +typedef void (*uv_connect_cb)(uv_connect_t* req, int status); +typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status); +typedef void (*uv_connection_cb)(uv_stream_t* server, int status); +typedef void (*uv_close_cb)(uv_handle_t* handle); +typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events); +typedef void (*uv_timer_cb)(uv_timer_t* handle); +typedef void (*uv_async_cb)(uv_async_t* handle); +typedef void (*uv_prepare_cb)(uv_prepare_t* handle); +typedef void (*uv_check_cb)(uv_check_t* handle); +typedef void (*uv_idle_cb)(uv_idle_t* handle); +typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal); +typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg); +typedef void (*uv_fs_cb)(uv_fs_t* req); +typedef void (*uv_work_cb)(uv_work_t* req); +typedef void (*uv_after_work_cb)(uv_work_t* req, int status); +typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, + int status, + struct addrinfo* res); +typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, + int status, + const char* hostname, + const char* service); +typedef void (*uv_random_cb)(uv_random_t* req, + int status, + void* buf, + size_t buflen); + +typedef struct { + long tv_sec; + long tv_nsec; +} uv_timespec_t; + + +typedef struct { + uint64_t st_dev; + uint64_t st_mode; + uint64_t st_nlink; + uint64_t st_uid; + uint64_t st_gid; + uint64_t st_rdev; + uint64_t st_ino; + uint64_t st_size; + uint64_t st_blksize; + uint64_t st_blocks; + uint64_t st_flags; + uint64_t st_gen; + uv_timespec_t st_atim; + uv_timespec_t st_mtim; + uv_timespec_t st_ctim; + uv_timespec_t st_birthtim; +} uv_stat_t; + + +typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, + const char* filename, + int events, + int status); + +typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); + +typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum); + + +typedef enum { + UV_LEAVE_GROUP = 0, + UV_JOIN_GROUP +} uv_membership; + + +UV_EXTERN int uv_translate_sys_error(int sys_errno); + +UV_EXTERN const char* uv_strerror(int err); +UV_EXTERN char* uv_strerror_r(int err, char* buf, size_t buflen); + +UV_EXTERN const char* uv_err_name(int err); +UV_EXTERN char* uv_err_name_r(int err, char* buf, size_t buflen); + + +#define UV_REQ_FIELDS \ + /* public */ \ + void* data; \ + /* read-only */ \ + uv_req_type type; \ + /* private */ \ + void* reserved[6]; \ + UV_REQ_PRIVATE_FIELDS \ + +/* Abstract base class of all requests. */ +struct uv_req_s { + UV_REQ_FIELDS +}; + + +/* Platform-specific request types. */ +UV_PRIVATE_REQ_TYPES + + +UV_EXTERN int uv_shutdown(uv_shutdown_t* req, + uv_stream_t* handle, + uv_shutdown_cb cb); + +struct uv_shutdown_s { + UV_REQ_FIELDS + uv_stream_t* handle; + uv_shutdown_cb cb; + UV_SHUTDOWN_PRIVATE_FIELDS +}; + + +#define UV_HANDLE_FIELDS \ + /* public */ \ + void* data; \ + /* read-only */ \ + uv_loop_t* loop; \ + uv_handle_type type; \ + /* private */ \ + uv_close_cb close_cb; \ + void* handle_queue[2]; \ + union { \ + int fd; \ + void* reserved[4]; \ + } u; \ + UV_HANDLE_PRIVATE_FIELDS \ + +/* The abstract base class of all handles. */ +struct uv_handle_s { + UV_HANDLE_FIELDS +}; + +UV_EXTERN size_t uv_handle_size(uv_handle_type type); +UV_EXTERN uv_handle_type uv_handle_get_type(const uv_handle_t* handle); +UV_EXTERN const char* uv_handle_type_name(uv_handle_type type); +UV_EXTERN void* uv_handle_get_data(const uv_handle_t* handle); +UV_EXTERN uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle); +UV_EXTERN void uv_handle_set_data(uv_handle_t* handle, void* data); + +UV_EXTERN size_t uv_req_size(uv_req_type type); +UV_EXTERN void* uv_req_get_data(const uv_req_t* req); +UV_EXTERN void uv_req_set_data(uv_req_t* req, void* data); +UV_EXTERN uv_req_type uv_req_get_type(const uv_req_t* req); +UV_EXTERN const char* uv_req_type_name(uv_req_type type); + +UV_EXTERN int uv_is_active(const uv_handle_t* handle); + +UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg); + +/* Helpers for ad hoc debugging, no API/ABI stability guaranteed. */ +UV_EXTERN void uv_print_all_handles(uv_loop_t* loop, FILE* stream); +UV_EXTERN void uv_print_active_handles(uv_loop_t* loop, FILE* stream); + +UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb); + +UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value); +UV_EXTERN int uv_recv_buffer_size(uv_handle_t* handle, int* value); + +UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd); + +UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len); + +UV_EXTERN int uv_pipe(uv_file fds[2], int read_flags, int write_flags); +UV_EXTERN int uv_socketpair(int type, + int protocol, + uv_os_sock_t socket_vector[2], + int flags0, + int flags1); + +#define UV_STREAM_FIELDS \ + /* number of bytes queued for writing */ \ + size_t write_queue_size; \ + uv_alloc_cb alloc_cb; \ + uv_read_cb read_cb; \ + /* private */ \ + UV_STREAM_PRIVATE_FIELDS + +/* + * uv_stream_t is a subclass of uv_handle_t. + * + * uv_stream is an abstract class. + * + * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t. + */ +struct uv_stream_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS +}; + +UV_EXTERN size_t uv_stream_get_write_queue_size(const uv_stream_t* stream); + +UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb); +UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client); + +UV_EXTERN int uv_read_start(uv_stream_t*, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb); +UV_EXTERN int uv_read_stop(uv_stream_t*); + +UV_EXTERN int uv_write(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb); +UV_EXTERN int uv_write2(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb); +UV_EXTERN int uv_try_write(uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs); +UV_EXTERN int uv_try_write2(uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle); + +/* uv_write_t is a subclass of uv_req_t. */ +struct uv_write_s { + UV_REQ_FIELDS + uv_write_cb cb; + uv_stream_t* send_handle; /* TODO: make private and unix-only in v2.x. */ + uv_stream_t* handle; + UV_WRITE_PRIVATE_FIELDS +}; + + +UV_EXTERN int uv_is_readable(const uv_stream_t* handle); +UV_EXTERN int uv_is_writable(const uv_stream_t* handle); + +UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking); + +UV_EXTERN int uv_is_closing(const uv_handle_t* handle); + + +/* + * uv_tcp_t is a subclass of uv_stream_t. + * + * Represents a TCP stream or TCP server. + */ +struct uv_tcp_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_TCP_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle); +UV_EXTERN int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags); +UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock); +UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable); +UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, + int enable, + unsigned int delay); +UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); + +enum uv_tcp_flags { + /* Used with uv_tcp_bind, when an IPv6 address is used. */ + UV_TCP_IPV6ONLY = 1 +}; + +UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int flags); +UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb); +UV_EXTERN int uv_tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + uv_connect_cb cb); + +/* uv_connect_t is a subclass of uv_req_t. */ +struct uv_connect_s { + UV_REQ_FIELDS + uv_connect_cb cb; + uv_stream_t* handle; + UV_CONNECT_PRIVATE_FIELDS +}; + + +/* + * UDP support. + */ + +enum uv_udp_flags { + /* Disables dual stack mode. */ + UV_UDP_IPV6ONLY = 1, + /* + * Indicates message was truncated because read buffer was too small. The + * remainder was discarded by the OS. Used in uv_udp_recv_cb. + */ + UV_UDP_PARTIAL = 2, + /* + * Indicates if SO_REUSEADDR will be set when binding the handle. + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + */ + UV_UDP_REUSEADDR = 4, + /* + * Indicates that the message was received by recvmmsg, so the buffer provided + * must not be freed by the recv_cb callback. + */ + UV_UDP_MMSG_CHUNK = 8, + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UV_UDP_MMSG_FREE = 16, + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from suppressing some ICMP error + * messages and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UV_UDP_LINUX_RECVERR = 32, + /* + * Indicates that recvmmsg should be used, if available. + */ + UV_UDP_RECVMMSG = 256 +}; + +typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status); +typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags); + +/* uv_udp_t is a subclass of uv_handle_t. */ +struct uv_udp_s { + UV_HANDLE_FIELDS + /* read-only */ + /* + * Number of bytes queued for sending. This field strictly shows how much + * information is currently queued. + */ + size_t send_queue_size; + /* + * Number of send requests currently in the queue awaiting to be processed. + */ + size_t send_queue_count; + UV_UDP_PRIVATE_FIELDS +}; + +/* uv_udp_send_t is a subclass of uv_req_t. */ +struct uv_udp_send_s { + UV_REQ_FIELDS + uv_udp_t* handle; + uv_udp_send_cb cb; + UV_UDP_SEND_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle); +UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags); +UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock); +UV_EXTERN int uv_udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int flags); +UV_EXTERN int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr); + +UV_EXTERN int uv_udp_getpeername(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_udp_getsockname(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + uv_membership membership); +UV_EXTERN int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership); +UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle, + const char* interface_addr); +UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + uv_udp_send_cb send_cb); +UV_EXTERN int uv_udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr); +UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, + uv_alloc_cb alloc_cb, + uv_udp_recv_cb recv_cb); +UV_EXTERN int uv_udp_using_recvmmsg(const uv_udp_t* handle); +UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_size(const uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_count(const uv_udp_t* handle); + + +/* + * uv_tty_t is a subclass of uv_stream_t. + * + * Representing a stream for the console. + */ +struct uv_tty_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_TTY_PRIVATE_FIELDS +}; + +typedef enum { + /* Initial/normal terminal mode */ + UV_TTY_MODE_NORMAL, + /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */ + UV_TTY_MODE_RAW, + /* Binary-safe I/O mode for IPC (Unix-only) */ + UV_TTY_MODE_IO +} uv_tty_mode_t; + +typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process the virtual terminal sequence. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED +} uv_tty_vtermstate_t; + + +UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); +UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode); +UV_EXTERN int uv_tty_reset_mode(void); +UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); +UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state); +UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state); + +#ifdef __cplusplus +extern "C++" { + +inline int uv_tty_set_mode(uv_tty_t* handle, int mode) { + return uv_tty_set_mode(handle, static_cast(mode)); +} + +} +#endif + +UV_EXTERN uv_handle_type uv_guess_handle(uv_file file); + +/* + * uv_pipe_t is a subclass of uv_stream_t. + * + * Representing a pipe stream or pipe server. On Windows this is a Named + * Pipe. On Unix this is a Unix domain socket. + */ +struct uv_pipe_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + int ipc; /* non-zero if this pipe is used for passing handles */ + UV_PIPE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc); +UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file); +UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name); +UV_EXTERN void uv_pipe_connect(uv_connect_t* req, + uv_pipe_t* handle, + const char* name, + uv_connect_cb cb); +UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, + char* buffer, + size_t* size); +UV_EXTERN int uv_pipe_getpeername(const uv_pipe_t* handle, + char* buffer, + size_t* size); +UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count); +UV_EXTERN int uv_pipe_pending_count(uv_pipe_t* handle); +UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle); +UV_EXTERN int uv_pipe_chmod(uv_pipe_t* handle, int flags); + + +struct uv_poll_s { + UV_HANDLE_FIELDS + uv_poll_cb poll_cb; + UV_POLL_PRIVATE_FIELDS +}; + +enum uv_poll_event { + UV_READABLE = 1, + UV_WRITABLE = 2, + UV_DISCONNECT = 4, + UV_PRIORITIZED = 8 +}; + +UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd); +UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, + uv_poll_t* handle, + uv_os_sock_t socket); +UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb); +UV_EXTERN int uv_poll_stop(uv_poll_t* handle); + + +struct uv_prepare_s { + UV_HANDLE_FIELDS + UV_PREPARE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare); +UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb); +UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare); + + +struct uv_check_s { + UV_HANDLE_FIELDS + UV_CHECK_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check); +UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb); +UV_EXTERN int uv_check_stop(uv_check_t* check); + + +struct uv_idle_s { + UV_HANDLE_FIELDS + UV_IDLE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle); +UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb); +UV_EXTERN int uv_idle_stop(uv_idle_t* idle); + + +struct uv_async_s { + UV_HANDLE_FIELDS + UV_ASYNC_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_async_init(uv_loop_t*, + uv_async_t* async, + uv_async_cb async_cb); +UV_EXTERN int uv_async_send(uv_async_t* async); + + +/* + * uv_timer_t is a subclass of uv_handle_t. + * + * Used to get woken up at a specified time in the future. + */ +struct uv_timer_s { + UV_HANDLE_FIELDS + UV_TIMER_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle); +UV_EXTERN int uv_timer_start(uv_timer_t* handle, + uv_timer_cb cb, + uint64_t timeout, + uint64_t repeat); +UV_EXTERN int uv_timer_stop(uv_timer_t* handle); +UV_EXTERN int uv_timer_again(uv_timer_t* handle); +UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat); +UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle); +UV_EXTERN uint64_t uv_timer_get_due_in(const uv_timer_t* handle); + + +/* + * uv_getaddrinfo_t is a subclass of uv_req_t. + * + * Request object for uv_getaddrinfo. + */ +struct uv_getaddrinfo_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* struct addrinfo* addrinfo is marked as private, but it really isn't. */ + UV_GETADDRINFO_PRIVATE_FIELDS +}; + + +UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop, + uv_getaddrinfo_t* req, + uv_getaddrinfo_cb getaddrinfo_cb, + const char* node, + const char* service, + const struct addrinfo* hints); +UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai); + + +/* +* uv_getnameinfo_t is a subclass of uv_req_t. +* +* Request object for uv_getnameinfo. +*/ +struct uv_getnameinfo_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* host and service are marked as private, but they really aren't. */ + UV_GETNAMEINFO_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_getnameinfo(uv_loop_t* loop, + uv_getnameinfo_t* req, + uv_getnameinfo_cb getnameinfo_cb, + const struct sockaddr* addr, + int flags); + + +/* uv_spawn() options. */ +typedef enum { + UV_IGNORE = 0x00, + UV_CREATE_PIPE = 0x01, + UV_INHERIT_FD = 0x02, + UV_INHERIT_STREAM = 0x04, + + /* + * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE + * determine the direction of flow, from the child process' perspective. Both + * flags may be specified to create a duplex data stream. + */ + UV_READABLE_PIPE = 0x10, + UV_WRITABLE_PIPE = 0x20, + + /* + * When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the + * handle in non-blocking mode in the child. This may cause loss of data, + * if the child is not designed to handle to encounter this mode, + * but can also be significantly more efficient. + */ + UV_NONBLOCK_PIPE = 0x40, + UV_OVERLAPPED_PIPE = 0x40 /* old name, for compatibility */ +} uv_stdio_flags; + +typedef struct uv_stdio_container_s { + uv_stdio_flags flags; + + union { + uv_stream_t* stream; + int fd; + } data; +} uv_stdio_container_t; + +typedef struct uv_process_options_s { + uv_exit_cb exit_cb; /* Called after the process exits. */ + const char* file; /* Path to program to execute. */ + /* + * Command line arguments. args[0] should be the path to the program. On + * Windows this uses CreateProcess which concatenates the arguments into a + * string this can cause some strange errors. See the note at + * windows_verbatim_arguments. + */ + char** args; + /* + * This will be set as the environ variable in the subprocess. If this is + * NULL then the parents environ will be used. + */ + char** env; + /* + * If non-null this represents a directory the subprocess should execute + * in. Stands for current working directory. + */ + const char* cwd; + /* + * Various flags that control how uv_spawn() behaves. See the definition of + * `enum uv_process_flags` below. + */ + unsigned int flags; + /* + * The `stdio` field points to an array of uv_stdio_container_t structs that + * describe the file descriptors that will be made available to the child + * process. The convention is that stdio[0] points to stdin, fd 1 is used for + * stdout, and fd 2 is stderr. + * + * Note that on windows file descriptors greater than 2 are available to the + * child process only if the child processes uses the MSVCRT runtime. + */ + int stdio_count; + uv_stdio_container_t* stdio; + /* + * Libuv can change the child process' user/group id. This happens only when + * the appropriate bits are set in the flags fields. This is not supported on + * windows; uv_spawn() will fail and set the error to UV_ENOTSUP. + */ + uv_uid_t uid; + uv_gid_t gid; +} uv_process_options_t; + +/* + * These are the flags that can be used for the uv_process_options.flags field. + */ +enum uv_process_flags { + /* + * Set the child process' user id. The user id is supplied in the `uid` field + * of the options struct. This does not work on windows; setting this flag + * will cause uv_spawn() to fail. + */ + UV_PROCESS_SETUID = (1 << 0), + /* + * Set the child process' group id. The user id is supplied in the `gid` + * field of the options struct. This does not work on windows; setting this + * flag will cause uv_spawn() to fail. + */ + UV_PROCESS_SETGID = (1 << 1), + /* + * Do not wrap any arguments in quotes, or perform any other escaping, when + * converting the argument list into a command line string. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), + /* + * Spawn the child process in a detached state - this will make it a process + * group leader, and will effectively enable the child to keep running after + * the parent exits. Note that the child process will still keep the + * parent's event loop alive unless the parent process calls uv_unref() on + * the child's process handle. + */ + UV_PROCESS_DETACHED = (1 << 3), + /* + * Hide the subprocess window that would normally be created. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_HIDE = (1 << 4), + /* + * Hide the subprocess console window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5), + /* + * Hide the subprocess GUI window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6) +}; + +/* + * uv_process_t is a subclass of uv_handle_t. + */ +struct uv_process_s { + UV_HANDLE_FIELDS + uv_exit_cb exit_cb; + int pid; + UV_PROCESS_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_spawn(uv_loop_t* loop, + uv_process_t* handle, + const uv_process_options_t* options); +UV_EXTERN int uv_process_kill(uv_process_t*, int signum); +UV_EXTERN int uv_kill(int pid, int signum); +UV_EXTERN uv_pid_t uv_process_get_pid(const uv_process_t*); + + +/* + * uv_work_t is a subclass of uv_req_t. + */ +struct uv_work_s { + UV_REQ_FIELDS + uv_loop_t* loop; + uv_work_cb work_cb; + uv_after_work_cb after_work_cb; + UV_WORK_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_queue_work(uv_loop_t* loop, + uv_work_t* req, + uv_work_cb work_cb, + uv_after_work_cb after_work_cb); + +UV_EXTERN int uv_cancel(uv_req_t* req); + +typedef enum { + uv_qos_background = 0, + uv_qos_utility = 1, + uv_qos_default = 2, + uv_qos_user_initiated = 3, +} uv_qos_t; + +UV_EXTERN int uv_queue_work_with_qos(uv_loop_t* loop, + uv_work_t* req, + uv_work_cb work_cb, + uv_after_work_cb after_work_cb, + uv_qos_t qos); + +struct uv_cpu_times_s { + uint64_t user; /* milliseconds */ + uint64_t nice; /* milliseconds */ + uint64_t sys; /* milliseconds */ + uint64_t idle; /* milliseconds */ + uint64_t irq; /* milliseconds */ +}; + +struct uv_cpu_info_s { + char* model; + int speed; + struct uv_cpu_times_s cpu_times; +}; + +struct uv_interface_address_s { + char* name; + char phys_addr[6]; + int is_internal; + union { + struct sockaddr_in address4; + struct sockaddr_in6 address6; + } address; + union { + struct sockaddr_in netmask4; + struct sockaddr_in6 netmask6; + } netmask; +}; + +struct uv_passwd_s { + char* username; + unsigned long uid; + unsigned long gid; + char* shell; + char* homedir; +}; + +struct uv_utsname_s { + char sysname[256]; + char release[256]; + char version[256]; + char machine[256]; + /* This struct does not contain the nodename and domainname fields present in + the utsname type. domainname is a GNU extension. Both fields are referred + to as meaningless in the docs. */ +}; + +struct uv_statfs_s { + uint64_t f_type; + uint64_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + uint64_t f_spare[4]; +}; + +typedef enum { + UV_DIRENT_UNKNOWN, + UV_DIRENT_FILE, + UV_DIRENT_DIR, + UV_DIRENT_LINK, + UV_DIRENT_FIFO, + UV_DIRENT_SOCKET, + UV_DIRENT_CHAR, + UV_DIRENT_BLOCK +} uv_dirent_type_t; + +struct uv_dirent_s { + const char* name; + uv_dirent_type_t type; +}; + +UV_EXTERN char** uv_setup_args(int argc, char** argv); +UV_EXTERN int uv_get_process_title(char* buffer, size_t size); +UV_EXTERN int uv_set_process_title(const char* title); +UV_EXTERN int uv_resident_set_memory(size_t* rss); +UV_EXTERN int uv_uptime(double* uptime); +UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd); +UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd); + +typedef struct { + long tv_sec; + long tv_usec; +} uv_timeval_t; + +typedef struct { + int64_t tv_sec; + int32_t tv_usec; +} uv_timeval64_t; + +typedef struct { + uv_timeval_t ru_utime; /* user CPU time used */ + uv_timeval_t ru_stime; /* system CPU time used */ + uint64_t ru_maxrss; /* maximum resident set size */ + uint64_t ru_ixrss; /* integral shared memory size */ + uint64_t ru_idrss; /* integral unshared data size */ + uint64_t ru_isrss; /* integral unshared stack size */ + uint64_t ru_minflt; /* page reclaims (soft page faults) */ + uint64_t ru_majflt; /* page faults (hard page faults) */ + uint64_t ru_nswap; /* swaps */ + uint64_t ru_inblock; /* block input operations */ + uint64_t ru_oublock; /* block output operations */ + uint64_t ru_msgsnd; /* IPC messages sent */ + uint64_t ru_msgrcv; /* IPC messages received */ + uint64_t ru_nsignals; /* signals received */ + uint64_t ru_nvcsw; /* voluntary context switches */ + uint64_t ru_nivcsw; /* involuntary context switches */ +} uv_rusage_t; + +UV_EXTERN int uv_getrusage(uv_rusage_t* rusage); + +UV_EXTERN int uv_os_homedir(char* buffer, size_t* size); +UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size); +UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd); +UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd); +UV_EXTERN uv_pid_t uv_os_getpid(void); +UV_EXTERN uv_pid_t uv_os_getppid(void); + +#if defined(__PASE__) +/* On IBM i PASE, the highest process priority is -10 */ +# define UV_PRIORITY_LOW 39 /* RUNPTY(99) */ +# define UV_PRIORITY_BELOW_NORMAL 15 /* RUNPTY(50) */ +# define UV_PRIORITY_NORMAL 0 /* RUNPTY(20) */ +# define UV_PRIORITY_ABOVE_NORMAL -4 /* RUNTY(12) */ +# define UV_PRIORITY_HIGH -7 /* RUNPTY(6) */ +# define UV_PRIORITY_HIGHEST -10 /* RUNPTY(1) */ +#else +# define UV_PRIORITY_LOW 19 +# define UV_PRIORITY_BELOW_NORMAL 10 +# define UV_PRIORITY_NORMAL 0 +# define UV_PRIORITY_ABOVE_NORMAL -7 +# define UV_PRIORITY_HIGH -14 +# define UV_PRIORITY_HIGHEST -20 +#endif + +UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority); +UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority); + +UV_EXTERN unsigned int uv_available_parallelism(void); +UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count); +UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count); + +UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, + int* count); +UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count); + +struct uv_env_item_s { + char* name; + char* value; +}; + +UV_EXTERN int uv_os_environ(uv_env_item_t** envitems, int* count); +UV_EXTERN void uv_os_free_environ(uv_env_item_t* envitems, int count); +UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); +UV_EXTERN int uv_os_setenv(const char* name, const char* value); +UV_EXTERN int uv_os_unsetenv(const char* name); + +#ifdef MAXHOSTNAMELEN +# define UV_MAXHOSTNAMESIZE (MAXHOSTNAMELEN + 1) +#else + /* + Fallback for the maximum hostname size, including the null terminator. The + Windows gethostname() documentation states that 256 bytes will always be + large enough to hold the null-terminated hostname. + */ +# define UV_MAXHOSTNAMESIZE 256 +#endif + +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + +UV_EXTERN int uv_os_uname(uv_utsname_t* buffer); + +UV_EXTERN uint64_t uv_metrics_idle_time(uv_loop_t* loop); + +typedef enum { + UV_FS_UNKNOWN = -1, + UV_FS_CUSTOM, + UV_FS_OPEN, + UV_FS_CLOSE, + UV_FS_READ, + UV_FS_WRITE, + UV_FS_SENDFILE, + UV_FS_STAT, + UV_FS_LSTAT, + UV_FS_FSTAT, + UV_FS_FTRUNCATE, + UV_FS_UTIME, + UV_FS_FUTIME, + UV_FS_ACCESS, + UV_FS_CHMOD, + UV_FS_FCHMOD, + UV_FS_FSYNC, + UV_FS_FDATASYNC, + UV_FS_UNLINK, + UV_FS_RMDIR, + UV_FS_MKDIR, + UV_FS_MKDTEMP, + UV_FS_RENAME, + UV_FS_SCANDIR, + UV_FS_LINK, + UV_FS_SYMLINK, + UV_FS_READLINK, + UV_FS_CHOWN, + UV_FS_FCHOWN, + UV_FS_REALPATH, + UV_FS_COPYFILE, + UV_FS_LCHOWN, + UV_FS_OPENDIR, + UV_FS_READDIR, + UV_FS_CLOSEDIR, + UV_FS_STATFS, + UV_FS_MKSTEMP, + UV_FS_LUTIME +} uv_fs_type; + +struct uv_dir_s { + uv_dirent_t* dirents; + size_t nentries; + void* reserved[4]; + UV_DIR_PRIVATE_FIELDS +}; + +/* uv_fs_t is a subclass of uv_req_t. */ +struct uv_fs_s { + UV_REQ_FIELDS + uv_fs_type fs_type; + uv_loop_t* loop; + uv_fs_cb cb; + ssize_t result; + void* ptr; + const char* path; + uv_stat_t statbuf; /* Stores the result of uv_fs_stat() and uv_fs_fstat(). */ + UV_FS_PRIVATE_FIELDS +}; + +UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*); +UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*); +UV_EXTERN int uv_fs_get_system_error(const uv_fs_t*); +UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*); +UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*); +UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*); + +UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req); +UV_EXTERN int uv_fs_close(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_open(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_read(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb); +UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_write(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb); +/* + * This flag can be used with uv_fs_copyfile() to return an error if the + * destination already exists. + */ +#define UV_FS_COPYFILE_EXCL 0x0001 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, a fallback copy mechanism is used. + */ +#define UV_FS_COPYFILE_FICLONE 0x0002 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, an error is returned. + */ +#define UV_FS_COPYFILE_FICLONE_FORCE 0x0004 + +UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkstemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb); +UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_scandir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req, + uv_dirent_t* ent); +UV_EXTERN int uv_fs_opendir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb); +UV_EXTERN int uv_fs_closedir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb); +UV_EXTERN int uv_fs_stat(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_rename(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int64_t offset, + uv_fs_cb cb); +UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, + uv_fs_t* req, + uv_file out_fd, + uv_file in_fd, + int64_t in_offset, + size_t length, + uv_fs_cb cb); +UV_EXTERN int uv_fs_access(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_utime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_futime(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lutime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_link(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb); + +/* + * This flag can be used with uv_fs_symlink() on Windows to specify whether + * path argument points to a directory. + */ +#define UV_FS_SYMLINK_DIR 0x0001 + +/* + * This flag can be used with uv_fs_symlink() on Windows to specify whether + * the symlink is to be created using junction points. + */ +#define UV_FS_SYMLINK_JUNCTION 0x0002 + +UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_realpath(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_chown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lchown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_statfs(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); + + +enum uv_fs_event { + UV_RENAME = 1, + UV_CHANGE = 2 +}; + + +struct uv_fs_event_s { + UV_HANDLE_FIELDS + /* private */ + char* path; + UV_FS_EVENT_PRIVATE_FIELDS +}; + + +/* + * uv_fs_stat() based polling file watcher. + */ +struct uv_fs_poll_s { + UV_HANDLE_FIELDS + /* Private, don't touch. */ + void* poll_ctx; +}; + +UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle); +UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle, + uv_fs_poll_cb poll_cb, + const char* path, + unsigned int interval); +UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle); +UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, + char* buffer, + size_t* size); + + +struct uv_signal_s { + UV_HANDLE_FIELDS + uv_signal_cb signal_cb; + int signum; + UV_SIGNAL_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); +UV_EXTERN int uv_signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); +UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); +UV_EXTERN int uv_signal_stop(uv_signal_t* handle); + +UV_EXTERN void uv_loadavg(double avg[3]); + + +/* + * Flags to be passed to uv_fs_event_start(). + */ +enum uv_fs_event_flags { + /* + * By default, if the fs event watcher is given a directory name, we will + * watch for all events in that directory. This flags overrides this behavior + * and makes fs_event report only changes to the directory entry itself. This + * flag does not affect individual files watched. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_WATCH_ENTRY = 1, + + /* + * By default uv_fs_event will try to use a kernel interface such as inotify + * or kqueue to detect events. This may not work on remote filesystems such + * as NFS mounts. This flag makes fs_event fall back to calling stat() on a + * regular interval. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_STAT = 2, + + /* + * By default, event watcher, when watching directory, is not registering + * (is ignoring) changes in it's subdirectories. + * This flag will override this behaviour on platforms that support it. + */ + UV_FS_EVENT_RECURSIVE = 4 +}; + + +UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags); +UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle, + char* buffer, + size_t* size); + +UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr); +UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); + +UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size); +UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size); +UV_EXTERN int uv_ip_name(const struct sockaddr* src, char* dst, size_t size); + +UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); +UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); + + +struct uv_random_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* private */ + int status; + void* buf; + size_t buflen; + uv_random_cb cb; + struct uv__work work_req; +}; + +UV_EXTERN int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, /* For future extension; must be 0. */ + uv_random_cb cb); + +#if defined(IF_NAMESIZE) +# define UV_IF_NAMESIZE (IF_NAMESIZE + 1) +#elif defined(IFNAMSIZ) +# define UV_IF_NAMESIZE (IFNAMSIZ + 1) +#else +# define UV_IF_NAMESIZE (16 + 1) +#endif + +UV_EXTERN int uv_if_indextoname(unsigned int ifindex, + char* buffer, + size_t* size); +UV_EXTERN int uv_if_indextoiid(unsigned int ifindex, + char* buffer, + size_t* size); + +UV_EXTERN int uv_exepath(char* buffer, size_t* size); + +UV_EXTERN int uv_cwd(char* buffer, size_t* size); + +UV_EXTERN int uv_chdir(const char* dir); + +UV_EXTERN uint64_t uv_get_free_memory(void); +UV_EXTERN uint64_t uv_get_total_memory(void); +UV_EXTERN uint64_t uv_get_constrained_memory(void); + +UV_EXTERN uint64_t uv_hrtime(void); +UV_EXTERN void uv_sleep(unsigned int msec); + +UV_EXTERN void uv_disable_stdio_inheritance(void); + +UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib); +UV_EXTERN void uv_dlclose(uv_lib_t* lib); +UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr); +UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib); + +UV_EXTERN int uv_mutex_init(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_init_recursive(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle); + +UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock); + +UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value); +UV_EXTERN void uv_sem_destroy(uv_sem_t* sem); +UV_EXTERN void uv_sem_post(uv_sem_t* sem); +UV_EXTERN void uv_sem_wait(uv_sem_t* sem); +UV_EXTERN int uv_sem_trywait(uv_sem_t* sem); + +UV_EXTERN int uv_cond_init(uv_cond_t* cond); +UV_EXTERN void uv_cond_destroy(uv_cond_t* cond); +UV_EXTERN void uv_cond_signal(uv_cond_t* cond); +UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond); + +UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count); +UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier); +UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier); + +UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex); +UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, + uv_mutex_t* mutex, + uint64_t timeout); + +UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void)); + +UV_EXTERN int uv_key_create(uv_key_t* key); +UV_EXTERN void uv_key_delete(uv_key_t* key); +UV_EXTERN void* uv_key_get(uv_key_t* key); +UV_EXTERN void uv_key_set(uv_key_t* key, void* value); + +UV_EXTERN int uv_gettimeofday(uv_timeval64_t* tv); + +typedef void (*uv_thread_cb)(void* arg); + +UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg); + +typedef enum { + UV_THREAD_NO_FLAGS = 0x00, + UV_THREAD_HAS_STACK_SIZE = 0x01 +} uv_thread_create_flags; + +struct uv_thread_options_s { + unsigned int flags; + size_t stack_size; + /* More fields may be added at any time. */ +}; + +typedef struct uv_thread_options_s uv_thread_options_t; + +UV_EXTERN int uv_thread_create_ex(uv_thread_t* tid, + const uv_thread_options_t* params, + uv_thread_cb entry, + void* arg); +UV_EXTERN uv_thread_t uv_thread_self(void); +UV_EXTERN int uv_thread_join(uv_thread_t *tid); +UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2); + +/* The presence of these unions force similar struct layout. */ +#define XX(_, name) uv_ ## name ## _t name; +union uv_any_handle { + UV_HANDLE_TYPE_MAP(XX) +}; + +union uv_any_req { + UV_REQ_TYPE_MAP(XX) +}; +#undef XX + + +struct uv_loop_s { + /* User data - use this for whatever. */ + void* data; + /* Loop reference counting. */ + unsigned int active_handles; + void* handle_queue[2]; + union { + void* unused; + unsigned int count; + } active_reqs; + /* Internal storage for future extensions. */ + void* internal_fields; + /* Internal flag to signal loop stop. */ + unsigned int stop_flag; + UV_LOOP_PRIVATE_FIELDS +}; + +UV_EXTERN void* uv_loop_get_data(const uv_loop_t*); +UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data); + +/* Don't export the private CPP symbols. */ +#undef UV_HANDLE_TYPE_PRIVATE +#undef UV_REQ_TYPE_PRIVATE +#undef UV_REQ_PRIVATE_FIELDS +#undef UV_STREAM_PRIVATE_FIELDS +#undef UV_TCP_PRIVATE_FIELDS +#undef UV_PREPARE_PRIVATE_FIELDS +#undef UV_CHECK_PRIVATE_FIELDS +#undef UV_IDLE_PRIVATE_FIELDS +#undef UV_ASYNC_PRIVATE_FIELDS +#undef UV_TIMER_PRIVATE_FIELDS +#undef UV_GETADDRINFO_PRIVATE_FIELDS +#undef UV_GETNAMEINFO_PRIVATE_FIELDS +#undef UV_FS_REQ_PRIVATE_FIELDS +#undef UV_WORK_PRIVATE_FIELDS +#undef UV_FS_EVENT_PRIVATE_FIELDS +#undef UV_SIGNAL_PRIVATE_FIELDS +#undef UV_LOOP_PRIVATE_FIELDS +#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS +#undef UV__ERR + +#ifdef __cplusplus +} +#endif +#endif /* UV_H */ diff --git a/third_party/libuv/include/uv/aix.h b/third_party/libuv/include/uv/aix.h new file mode 100644 index 000000000..7dc992fa6 --- /dev/null +++ b/third_party/libuv/include/uv/aix.h @@ -0,0 +1,32 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_AIX_H +#define UV_AIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + int fs_fd; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + uv__io_t event_watcher; \ + char *dir_filename; \ + +#endif /* UV_AIX_H */ diff --git a/third_party/libuv/include/uv/bsd.h b/third_party/libuv/include/uv/bsd.h new file mode 100644 index 000000000..2d72b3d77 --- /dev/null +++ b/third_party/libuv/include/uv/bsd.h @@ -0,0 +1,34 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_BSD_H +#define UV_BSD_H + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + uv__io_t event_watcher; \ + +#define UV_IO_PRIVATE_PLATFORM_FIELDS \ + int rcount; \ + int wcount; \ + +#define UV_HAVE_KQUEUE 1 + +#endif /* UV_BSD_H */ diff --git a/third_party/libuv/include/uv/darwin.h b/third_party/libuv/include/uv/darwin.h new file mode 100644 index 000000000..d22641582 --- /dev/null +++ b/third_party/libuv/include/uv/darwin.h @@ -0,0 +1,61 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_DARWIN_H +#define UV_DARWIN_H + +#if defined(__APPLE__) && defined(__MACH__) +# include +# include +# include +# include +# define UV_PLATFORM_SEM_T semaphore_t +#endif + +#define UV_IO_PRIVATE_PLATFORM_FIELDS \ + int rcount; \ + int wcount; \ + +#define UV_PLATFORM_LOOP_FIELDS \ + uv_thread_t cf_thread; \ + void* _cf_reserved; \ + void* cf_state; \ + uv_mutex_t cf_mutex; \ + uv_sem_t cf_sem; \ + void* cf_signals[2]; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + uv__io_t event_watcher; \ + char* realpath; \ + int realpath_len; \ + int cf_flags; \ + uv_async_t* cf_cb; \ + void* cf_events[2]; \ + void* cf_member[2]; \ + int cf_error; \ + uv_mutex_t cf_mutex; \ + +#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \ + void* select; \ + +#define UV_HAVE_KQUEUE 1 + +#endif /* UV_DARWIN_H */ diff --git a/third_party/libuv/include/uv/errno.h b/third_party/libuv/include/uv/errno.h new file mode 100644 index 000000000..71906b3f5 --- /dev/null +++ b/third_party/libuv/include/uv/errno.h @@ -0,0 +1,460 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_ERRNO_H_ +#define UV_ERRNO_H_ + +#include +#if EDOM > 0 +# define UV__ERR(x) (-(x)) +#else +# define UV__ERR(x) (x) +#endif + +#define UV__EOF (-4095) +#define UV__UNKNOWN (-4094) + +#define UV__EAI_ADDRFAMILY (-3000) +#define UV__EAI_AGAIN (-3001) +#define UV__EAI_BADFLAGS (-3002) +#define UV__EAI_CANCELED (-3003) +#define UV__EAI_FAIL (-3004) +#define UV__EAI_FAMILY (-3005) +#define UV__EAI_MEMORY (-3006) +#define UV__EAI_NODATA (-3007) +#define UV__EAI_NONAME (-3008) +#define UV__EAI_OVERFLOW (-3009) +#define UV__EAI_SERVICE (-3010) +#define UV__EAI_SOCKTYPE (-3011) +#define UV__EAI_BADHINTS (-3013) +#define UV__EAI_PROTOCOL (-3014) + +/* Only map to the system errno on non-Windows platforms. It's apparently + * a fairly common practice for Windows programmers to redefine errno codes. + */ +#if defined(E2BIG) && !defined(_WIN32) +# define UV__E2BIG UV__ERR(E2BIG) +#else +# define UV__E2BIG (-4093) +#endif + +#if defined(EACCES) && !defined(_WIN32) +# define UV__EACCES UV__ERR(EACCES) +#else +# define UV__EACCES (-4092) +#endif + +#if defined(EADDRINUSE) && !defined(_WIN32) +# define UV__EADDRINUSE UV__ERR(EADDRINUSE) +#else +# define UV__EADDRINUSE (-4091) +#endif + +#if defined(EADDRNOTAVAIL) && !defined(_WIN32) +# define UV__EADDRNOTAVAIL UV__ERR(EADDRNOTAVAIL) +#else +# define UV__EADDRNOTAVAIL (-4090) +#endif + +#if defined(EAFNOSUPPORT) && !defined(_WIN32) +# define UV__EAFNOSUPPORT UV__ERR(EAFNOSUPPORT) +#else +# define UV__EAFNOSUPPORT (-4089) +#endif + +#if defined(EAGAIN) && !defined(_WIN32) +# define UV__EAGAIN UV__ERR(EAGAIN) +#else +# define UV__EAGAIN (-4088) +#endif + +#if defined(EALREADY) && !defined(_WIN32) +# define UV__EALREADY UV__ERR(EALREADY) +#else +# define UV__EALREADY (-4084) +#endif + +#if defined(EBADF) && !defined(_WIN32) +# define UV__EBADF UV__ERR(EBADF) +#else +# define UV__EBADF (-4083) +#endif + +#if defined(EBUSY) && !defined(_WIN32) +# define UV__EBUSY UV__ERR(EBUSY) +#else +# define UV__EBUSY (-4082) +#endif + +#if defined(ECANCELED) && !defined(_WIN32) +# define UV__ECANCELED UV__ERR(ECANCELED) +#else +# define UV__ECANCELED (-4081) +#endif + +#if defined(ECHARSET) && !defined(_WIN32) +# define UV__ECHARSET UV__ERR(ECHARSET) +#else +# define UV__ECHARSET (-4080) +#endif + +#if defined(ECONNABORTED) && !defined(_WIN32) +# define UV__ECONNABORTED UV__ERR(ECONNABORTED) +#else +# define UV__ECONNABORTED (-4079) +#endif + +#if defined(ECONNREFUSED) && !defined(_WIN32) +# define UV__ECONNREFUSED UV__ERR(ECONNREFUSED) +#else +# define UV__ECONNREFUSED (-4078) +#endif + +#if defined(ECONNRESET) && !defined(_WIN32) +# define UV__ECONNRESET UV__ERR(ECONNRESET) +#else +# define UV__ECONNRESET (-4077) +#endif + +#if defined(EDESTADDRREQ) && !defined(_WIN32) +# define UV__EDESTADDRREQ UV__ERR(EDESTADDRREQ) +#else +# define UV__EDESTADDRREQ (-4076) +#endif + +#if defined(EEXIST) && !defined(_WIN32) +# define UV__EEXIST UV__ERR(EEXIST) +#else +# define UV__EEXIST (-4075) +#endif + +#if defined(EFAULT) && !defined(_WIN32) +# define UV__EFAULT UV__ERR(EFAULT) +#else +# define UV__EFAULT (-4074) +#endif + +#if defined(EHOSTUNREACH) && !defined(_WIN32) +# define UV__EHOSTUNREACH UV__ERR(EHOSTUNREACH) +#else +# define UV__EHOSTUNREACH (-4073) +#endif + +#if defined(EINTR) && !defined(_WIN32) +# define UV__EINTR UV__ERR(EINTR) +#else +# define UV__EINTR (-4072) +#endif + +#if defined(EINVAL) && !defined(_WIN32) +# define UV__EINVAL UV__ERR(EINVAL) +#else +# define UV__EINVAL (-4071) +#endif + +#if defined(EIO) && !defined(_WIN32) +# define UV__EIO UV__ERR(EIO) +#else +# define UV__EIO (-4070) +#endif + +#if defined(EISCONN) && !defined(_WIN32) +# define UV__EISCONN UV__ERR(EISCONN) +#else +# define UV__EISCONN (-4069) +#endif + +#if defined(EISDIR) && !defined(_WIN32) +# define UV__EISDIR UV__ERR(EISDIR) +#else +# define UV__EISDIR (-4068) +#endif + +#if defined(ELOOP) && !defined(_WIN32) +# define UV__ELOOP UV__ERR(ELOOP) +#else +# define UV__ELOOP (-4067) +#endif + +#if defined(EMFILE) && !defined(_WIN32) +# define UV__EMFILE UV__ERR(EMFILE) +#else +# define UV__EMFILE (-4066) +#endif + +#if defined(EMSGSIZE) && !defined(_WIN32) +# define UV__EMSGSIZE UV__ERR(EMSGSIZE) +#else +# define UV__EMSGSIZE (-4065) +#endif + +#if defined(ENAMETOOLONG) && !defined(_WIN32) +# define UV__ENAMETOOLONG UV__ERR(ENAMETOOLONG) +#else +# define UV__ENAMETOOLONG (-4064) +#endif + +#if defined(ENETDOWN) && !defined(_WIN32) +# define UV__ENETDOWN UV__ERR(ENETDOWN) +#else +# define UV__ENETDOWN (-4063) +#endif + +#if defined(ENETUNREACH) && !defined(_WIN32) +# define UV__ENETUNREACH UV__ERR(ENETUNREACH) +#else +# define UV__ENETUNREACH (-4062) +#endif + +#if defined(ENFILE) && !defined(_WIN32) +# define UV__ENFILE UV__ERR(ENFILE) +#else +# define UV__ENFILE (-4061) +#endif + +#if defined(ENOBUFS) && !defined(_WIN32) +# define UV__ENOBUFS UV__ERR(ENOBUFS) +#else +# define UV__ENOBUFS (-4060) +#endif + +#if defined(ENODEV) && !defined(_WIN32) +# define UV__ENODEV UV__ERR(ENODEV) +#else +# define UV__ENODEV (-4059) +#endif + +#if defined(ENOENT) && !defined(_WIN32) +# define UV__ENOENT UV__ERR(ENOENT) +#else +# define UV__ENOENT (-4058) +#endif + +#if defined(ENOMEM) && !defined(_WIN32) +# define UV__ENOMEM UV__ERR(ENOMEM) +#else +# define UV__ENOMEM (-4057) +#endif + +#if defined(ENONET) && !defined(_WIN32) +# define UV__ENONET UV__ERR(ENONET) +#else +# define UV__ENONET (-4056) +#endif + +#if defined(ENOSPC) && !defined(_WIN32) +# define UV__ENOSPC UV__ERR(ENOSPC) +#else +# define UV__ENOSPC (-4055) +#endif + +#if defined(ENOSYS) && !defined(_WIN32) +# define UV__ENOSYS UV__ERR(ENOSYS) +#else +# define UV__ENOSYS (-4054) +#endif + +#if defined(ENOTCONN) && !defined(_WIN32) +# define UV__ENOTCONN UV__ERR(ENOTCONN) +#else +# define UV__ENOTCONN (-4053) +#endif + +#if defined(ENOTDIR) && !defined(_WIN32) +# define UV__ENOTDIR UV__ERR(ENOTDIR) +#else +# define UV__ENOTDIR (-4052) +#endif + +#if defined(ENOTEMPTY) && !defined(_WIN32) +# define UV__ENOTEMPTY UV__ERR(ENOTEMPTY) +#else +# define UV__ENOTEMPTY (-4051) +#endif + +#if defined(ENOTSOCK) && !defined(_WIN32) +# define UV__ENOTSOCK UV__ERR(ENOTSOCK) +#else +# define UV__ENOTSOCK (-4050) +#endif + +#if defined(ENOTSUP) && !defined(_WIN32) +# define UV__ENOTSUP UV__ERR(ENOTSUP) +#else +# define UV__ENOTSUP (-4049) +#endif + +#if defined(EPERM) && !defined(_WIN32) +# define UV__EPERM UV__ERR(EPERM) +#else +# define UV__EPERM (-4048) +#endif + +#if defined(EPIPE) && !defined(_WIN32) +# define UV__EPIPE UV__ERR(EPIPE) +#else +# define UV__EPIPE (-4047) +#endif + +#if defined(EPROTO) && !defined(_WIN32) +# define UV__EPROTO UV__ERR(EPROTO) +#else +# define UV__EPROTO (-4046) +#endif + +#if defined(EPROTONOSUPPORT) && !defined(_WIN32) +# define UV__EPROTONOSUPPORT UV__ERR(EPROTONOSUPPORT) +#else +# define UV__EPROTONOSUPPORT (-4045) +#endif + +#if defined(EPROTOTYPE) && !defined(_WIN32) +# define UV__EPROTOTYPE UV__ERR(EPROTOTYPE) +#else +# define UV__EPROTOTYPE (-4044) +#endif + +#if defined(EROFS) && !defined(_WIN32) +# define UV__EROFS UV__ERR(EROFS) +#else +# define UV__EROFS (-4043) +#endif + +#if defined(ESHUTDOWN) && !defined(_WIN32) +# define UV__ESHUTDOWN UV__ERR(ESHUTDOWN) +#else +# define UV__ESHUTDOWN (-4042) +#endif + +#if defined(ESPIPE) && !defined(_WIN32) +# define UV__ESPIPE UV__ERR(ESPIPE) +#else +# define UV__ESPIPE (-4041) +#endif + +#if defined(ESRCH) && !defined(_WIN32) +# define UV__ESRCH UV__ERR(ESRCH) +#else +# define UV__ESRCH (-4040) +#endif + +#if defined(ETIMEDOUT) && !defined(_WIN32) +# define UV__ETIMEDOUT UV__ERR(ETIMEDOUT) +#else +# define UV__ETIMEDOUT (-4039) +#endif + +#if defined(ETXTBSY) && !defined(_WIN32) +# define UV__ETXTBSY UV__ERR(ETXTBSY) +#else +# define UV__ETXTBSY (-4038) +#endif + +#if defined(EXDEV) && !defined(_WIN32) +# define UV__EXDEV UV__ERR(EXDEV) +#else +# define UV__EXDEV (-4037) +#endif + +#if defined(EFBIG) && !defined(_WIN32) +# define UV__EFBIG UV__ERR(EFBIG) +#else +# define UV__EFBIG (-4036) +#endif + +#if defined(ENOPROTOOPT) && !defined(_WIN32) +# define UV__ENOPROTOOPT UV__ERR(ENOPROTOOPT) +#else +# define UV__ENOPROTOOPT (-4035) +#endif + +#if defined(ERANGE) && !defined(_WIN32) +# define UV__ERANGE UV__ERR(ERANGE) +#else +# define UV__ERANGE (-4034) +#endif + +#if defined(ENXIO) && !defined(_WIN32) +# define UV__ENXIO UV__ERR(ENXIO) +#else +# define UV__ENXIO (-4033) +#endif + +#if defined(EMLINK) && !defined(_WIN32) +# define UV__EMLINK UV__ERR(EMLINK) +#else +# define UV__EMLINK (-4032) +#endif + +/* EHOSTDOWN is not visible on BSD-like systems when _POSIX_C_SOURCE is + * defined. Fortunately, its value is always 64 so it's possible albeit + * icky to hard-code it. + */ +#if defined(EHOSTDOWN) && !defined(_WIN32) +# define UV__EHOSTDOWN UV__ERR(EHOSTDOWN) +#elif defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) +# define UV__EHOSTDOWN (-64) +#else +# define UV__EHOSTDOWN (-4031) +#endif + +#if defined(EREMOTEIO) && !defined(_WIN32) +# define UV__EREMOTEIO UV__ERR(EREMOTEIO) +#else +# define UV__EREMOTEIO (-4030) +#endif + +#if defined(ENOTTY) && !defined(_WIN32) +# define UV__ENOTTY UV__ERR(ENOTTY) +#else +# define UV__ENOTTY (-4029) +#endif + +#if defined(EFTYPE) && !defined(_WIN32) +# define UV__EFTYPE UV__ERR(EFTYPE) +#else +# define UV__EFTYPE (-4028) +#endif + +#if defined(EILSEQ) && !defined(_WIN32) +# define UV__EILSEQ UV__ERR(EILSEQ) +#else +# define UV__EILSEQ (-4027) +#endif + +#if defined(EOVERFLOW) && !defined(_WIN32) +# define UV__EOVERFLOW UV__ERR(EOVERFLOW) +#else +# define UV__EOVERFLOW (-4026) +#endif + +#if defined(ESOCKTNOSUPPORT) && !defined(_WIN32) +# define UV__ESOCKTNOSUPPORT UV__ERR(ESOCKTNOSUPPORT) +#else +# define UV__ESOCKTNOSUPPORT (-4025) +#endif + +#endif /* UV_ERRNO_H_ */ diff --git a/third_party/libuv/include/uv/linux.h b/third_party/libuv/include/uv/linux.h new file mode 100644 index 000000000..9b38405a1 --- /dev/null +++ b/third_party/libuv/include/uv/linux.h @@ -0,0 +1,34 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_LINUX_H +#define UV_LINUX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + uv__io_t inotify_read_watcher; \ + void* inotify_watchers; \ + int inotify_fd; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + void* watchers[2]; \ + int wd; \ + +#endif /* UV_LINUX_H */ diff --git a/third_party/libuv/include/uv/os390.h b/third_party/libuv/include/uv/os390.h new file mode 100644 index 000000000..0267d74cb --- /dev/null +++ b/third_party/libuv/include/uv/os390.h @@ -0,0 +1,33 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_MVS_H +#define UV_MVS_H + +#define UV_PLATFORM_SEM_T long + +#define UV_PLATFORM_LOOP_FIELDS \ + void* ep; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + char rfis_rftok[8]; \ + +#endif /* UV_MVS_H */ diff --git a/third_party/libuv/include/uv/posix.h b/third_party/libuv/include/uv/posix.h new file mode 100644 index 000000000..9a96634db --- /dev/null +++ b/third_party/libuv/include/uv/posix.h @@ -0,0 +1,31 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_POSIX_H +#define UV_POSIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + struct pollfd* poll_fds; \ + size_t poll_fds_used; \ + size_t poll_fds_size; \ + unsigned char poll_fds_iterating; \ + +#endif /* UV_POSIX_H */ diff --git a/third_party/libuv/include/uv/stdint-msvc2008.h b/third_party/libuv/include/uv/stdint-msvc2008.h new file mode 100644 index 000000000..d02608a59 --- /dev/null +++ b/third_party/libuv/include/uv/stdint-msvc2008.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/third_party/libuv/include/uv/sunos.h b/third_party/libuv/include/uv/sunos.h new file mode 100644 index 000000000..042166424 --- /dev/null +++ b/third_party/libuv/include/uv/sunos.h @@ -0,0 +1,44 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_SUNOS_H +#define UV_SUNOS_H + +#include +#include + +/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c, + * add the fs_event fields even when this version of SunOS doesn't support + * file watching. + */ +#define UV_PLATFORM_LOOP_FIELDS \ + uv__io_t fs_event_watcher; \ + int fs_fd; \ + +#if defined(PORT_SOURCE_FILE) + +# define UV_PLATFORM_FS_EVENT_FIELDS \ + file_obj_t fo; \ + int fd; \ + +#endif /* defined(PORT_SOURCE_FILE) */ + +#endif /* UV_SUNOS_H */ diff --git a/third_party/libuv/include/uv/threadpool.h b/third_party/libuv/include/uv/threadpool.h new file mode 100644 index 000000000..9708ebdd5 --- /dev/null +++ b/third_party/libuv/include/uv/threadpool.h @@ -0,0 +1,37 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * This file is private to libuv. It provides common functionality to both + * Windows and Unix backends. + */ + +#ifndef UV_THREADPOOL_H_ +#define UV_THREADPOOL_H_ + +struct uv__work { + void (*work)(struct uv__work *w); + void (*done)(struct uv__work *w, int status); + struct uv_loop_s* loop; + void* wq[2]; +}; + +#endif /* UV_THREADPOOL_H_ */ diff --git a/third_party/libuv/include/uv/tree.h b/third_party/libuv/include/uv/tree.h new file mode 100644 index 000000000..2b28835fd --- /dev/null +++ b/third_party/libuv/include/uv/tree.h @@ -0,0 +1,768 @@ +/*- + * Copyright 2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UV_TREE_H_ +#define UV_TREE_H_ + +#ifndef UV__UNUSED +# if __GNUC__ +# define UV__UNUSED __attribute__((unused)) +# else +# define UV__UNUSED +# endif +#endif + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ + \ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ + __left = __right = &__node; \ + \ + while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + \ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ + __left = __right = &__node; \ + \ + for (;;) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-black tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (/*CONSTCOND*/ 0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (/*CONSTCOND*/ 0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) do {} while (0) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (/*CONSTCOND*/ 0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_PREV(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) != NULL && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field); \ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field); \ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field); \ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field); \ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +attr void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \ + struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field); \ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)) \ + != NULL) \ + RB_COLOR(oleft, field) = RB_BLACK; \ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field); \ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \ + RB_ROTATE_LEFT(head, parent, tmp, field); \ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field); \ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)) \ + != NULL) \ + RB_COLOR(oright, field) = RB_BLACK; \ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field); \ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \ + RB_ROTATE_RIGHT(head, parent, tmp, field); \ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +attr struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field)) != NULL) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old) \ + RB_LEFT(RB_PARENT(old, field), field) = elm; \ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm; \ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field)) != NULL); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +attr struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +attr struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#endif /* UV_TREE_H_ */ diff --git a/third_party/libuv/include/uv/unix.h b/third_party/libuv/include/uv/unix.h new file mode 100644 index 000000000..ea37d7876 --- /dev/null +++ b/third_party/libuv/include/uv/unix.h @@ -0,0 +1,505 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_UNIX_H +#define UV_UNIX_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include /* MAXHOSTNAMELEN on Solaris */ + +#include +#include + +#if !defined(__MVS__) +#include +#include /* MAXHOSTNAMELEN on Linux and the BSDs */ +#endif +#include +#include + +#include "uv/threadpool.h" + +#if defined(__linux__) +# include "uv/linux.h" +#elif defined (__MVS__) +# include "uv/os390.h" +#elif defined(__PASE__) /* __PASE__ and _AIX are both defined on IBM i */ +# include "uv/posix.h" /* IBM i needs uv/posix.h, not uv/aix.h */ +#elif defined(_AIX) +# include "uv/aix.h" +#elif defined(__sun) +# include "uv/sunos.h" +#elif defined(__APPLE__) +# include "uv/darwin.h" +#elif defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# include "uv/bsd.h" +#elif defined(__CYGWIN__) || \ + defined(__MSYS__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) || \ + defined(__GNU__) +# include "uv/posix.h" +#endif + +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS +# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */ +#endif + +struct uv__io_s; +struct uv_loop_s; + +typedef void (*uv__io_cb)(struct uv_loop_s* loop, + struct uv__io_s* w, + unsigned int events); +typedef struct uv__io_s uv__io_t; + +struct uv__io_s { + uv__io_cb cb; + void* pending_queue[2]; + void* watcher_queue[2]; + unsigned int pevents; /* Pending event mask i.e. mask at next tick. */ + unsigned int events; /* Current event mask. */ + int fd; + UV_IO_PRIVATE_PLATFORM_FIELDS +}; + +#ifndef UV_PLATFORM_SEM_T +# define UV_PLATFORM_SEM_T sem_t +#endif + +#ifndef UV_PLATFORM_LOOP_FIELDS +# define UV_PLATFORM_LOOP_FIELDS /* empty */ +#endif + +#ifndef UV_PLATFORM_FS_EVENT_FIELDS +# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */ +#endif + +#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS +# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */ +#endif + +/* Note: May be cast to struct iovec. See writev(2). */ +typedef struct uv_buf_t { + char* base; + size_t len; +} uv_buf_t; + +typedef int uv_file; +typedef int uv_os_sock_t; +typedef int uv_os_fd_t; +typedef pid_t uv_pid_t; + +#define UV_ONCE_INIT PTHREAD_ONCE_INIT + +typedef pthread_once_t uv_once_t; +typedef pthread_t uv_thread_t; +typedef pthread_mutex_t uv_mutex_t; +typedef pthread_rwlock_t uv_rwlock_t; +typedef UV_PLATFORM_SEM_T uv_sem_t; +typedef pthread_cond_t uv_cond_t; +typedef pthread_key_t uv_key_t; + +/* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */ +#if defined(_AIX) || \ + defined(__OpenBSD__) || \ + !defined(PTHREAD_BARRIER_SERIAL_THREAD) +/* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */ +struct _uv_barrier { + uv_mutex_t mutex; + uv_cond_t cond; + unsigned threshold; + unsigned in; + unsigned out; +}; + +typedef struct { + struct _uv_barrier* b; +# if defined(PTHREAD_BARRIER_SERIAL_THREAD) + /* TODO(bnoordhuis) Remove padding in v2. */ + char pad[sizeof(pthread_barrier_t) - sizeof(struct _uv_barrier*)]; +# endif +} uv_barrier_t; +#else +typedef pthread_barrier_t uv_barrier_t; +#endif + +/* Platform-specific definitions for uv_spawn support. */ +typedef gid_t uv_gid_t; +typedef uid_t uv_uid_t; + +typedef struct dirent uv__dirent_t; + +#define UV_DIR_PRIVATE_FIELDS \ + DIR* dir; + +#if defined(DT_UNKNOWN) +# define HAVE_DIRENT_TYPES +# if defined(DT_REG) +# define UV__DT_FILE DT_REG +# else +# define UV__DT_FILE -1 +# endif +# if defined(DT_DIR) +# define UV__DT_DIR DT_DIR +# else +# define UV__DT_DIR -2 +# endif +# if defined(DT_LNK) +# define UV__DT_LINK DT_LNK +# else +# define UV__DT_LINK -3 +# endif +# if defined(DT_FIFO) +# define UV__DT_FIFO DT_FIFO +# else +# define UV__DT_FIFO -4 +# endif +# if defined(DT_SOCK) +# define UV__DT_SOCKET DT_SOCK +# else +# define UV__DT_SOCKET -5 +# endif +# if defined(DT_CHR) +# define UV__DT_CHAR DT_CHR +# else +# define UV__DT_CHAR -6 +# endif +# if defined(DT_BLK) +# define UV__DT_BLOCK DT_BLK +# else +# define UV__DT_BLOCK -7 +# endif +#endif + +/* Platform-specific definitions for uv_dlopen support. */ +#define UV_DYNAMIC /* empty */ + +typedef struct { + void* handle; + char* errmsg; +} uv_lib_t; + +#define UV_LOOP_PRIVATE_FIELDS \ + unsigned long flags; \ + int backend_fd; \ + void* pending_queue[2]; \ + void* watcher_queue[2]; \ + uv__io_t** watchers; \ + unsigned int nwatchers; \ + unsigned int nfds; \ + void* wq[2]; \ + uv_mutex_t wq_mutex; \ + uv_async_t wq_async; \ + uv_rwlock_t cloexec_lock; \ + uv_handle_t* closing_handles; \ + void* process_handles[2]; \ + void* prepare_handles[2]; \ + void* check_handles[2]; \ + void* idle_handles[2]; \ + void* async_handles[2]; \ + void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ + uv__io_t async_io_watcher; \ + int async_wfd; \ + struct { \ + void* min; \ + unsigned int nelts; \ + } timer_heap; \ + uint64_t timer_counter; \ + uint64_t time; \ + int signal_pipefd[2]; \ + uv__io_t signal_io_watcher; \ + uv_signal_t child_watcher; \ + int emfile_fd; \ + UV_PLATFORM_LOOP_FIELDS \ + +#define UV_REQ_TYPE_PRIVATE /* empty */ + +#define UV_REQ_PRIVATE_FIELDS /* empty */ + +#define UV_PRIVATE_REQ_TYPES /* empty */ + +#define UV_WRITE_PRIVATE_FIELDS \ + void* queue[2]; \ + unsigned int write_index; \ + uv_buf_t* bufs; \ + unsigned int nbufs; \ + int error; \ + uv_buf_t bufsml[4]; \ + +#define UV_CONNECT_PRIVATE_FIELDS \ + void* queue[2]; \ + +#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */ + +#define UV_UDP_SEND_PRIVATE_FIELDS \ + void* queue[2]; \ + struct sockaddr_storage addr; \ + unsigned int nbufs; \ + uv_buf_t* bufs; \ + ssize_t status; \ + uv_udp_send_cb send_cb; \ + uv_buf_t bufsml[4]; \ + +#define UV_HANDLE_PRIVATE_FIELDS \ + uv_handle_t* next_closing; \ + unsigned int flags; \ + +#define UV_STREAM_PRIVATE_FIELDS \ + uv_connect_t *connect_req; \ + uv_shutdown_t *shutdown_req; \ + uv__io_t io_watcher; \ + void* write_queue[2]; \ + void* write_completed_queue[2]; \ + uv_connection_cb connection_cb; \ + int delayed_error; \ + int accepted_fd; \ + void* queued_fds; \ + UV_STREAM_PRIVATE_PLATFORM_FIELDS \ + +#define UV_TCP_PRIVATE_FIELDS /* empty */ + +#define UV_UDP_PRIVATE_FIELDS \ + uv_alloc_cb alloc_cb; \ + uv_udp_recv_cb recv_cb; \ + uv__io_t io_watcher; \ + void* write_queue[2]; \ + void* write_completed_queue[2]; \ + +#define UV_PIPE_PRIVATE_FIELDS \ + const char* pipe_fname; /* strdup'ed */ + +#define UV_POLL_PRIVATE_FIELDS \ + uv__io_t io_watcher; + +#define UV_PREPARE_PRIVATE_FIELDS \ + uv_prepare_cb prepare_cb; \ + void* queue[2]; \ + +#define UV_CHECK_PRIVATE_FIELDS \ + uv_check_cb check_cb; \ + void* queue[2]; \ + +#define UV_IDLE_PRIVATE_FIELDS \ + uv_idle_cb idle_cb; \ + void* queue[2]; \ + +#define UV_ASYNC_PRIVATE_FIELDS \ + uv_async_cb async_cb; \ + void* queue[2]; \ + int pending; \ + +#define UV_TIMER_PRIVATE_FIELDS \ + uv_timer_cb timer_cb; \ + void* heap_node[3]; \ + uint64_t timeout; \ + uint64_t repeat; \ + uint64_t start_id; + +#define UV_GETADDRINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getaddrinfo_cb cb; \ + struct addrinfo* hints; \ + char* hostname; \ + char* service; \ + struct addrinfo* addrinfo; \ + int retcode; + +#define UV_GETNAMEINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getnameinfo_cb getnameinfo_cb; \ + struct sockaddr_storage storage; \ + int flags; \ + char host[NI_MAXHOST]; \ + char service[NI_MAXSERV]; \ + int retcode; + +#define UV_PROCESS_PRIVATE_FIELDS \ + void* queue[2]; \ + int status; \ + +#define UV_FS_PRIVATE_FIELDS \ + const char *new_path; \ + uv_file file; \ + int flags; \ + mode_t mode; \ + unsigned int nbufs; \ + uv_buf_t* bufs; \ + off_t off; \ + uv_uid_t uid; \ + uv_gid_t gid; \ + double atime; \ + double mtime; \ + struct uv__work work_req; \ + uv_buf_t bufsml[4]; \ + +#define UV_WORK_PRIVATE_FIELDS \ + struct uv__work work_req; + +#define UV_TTY_PRIVATE_FIELDS \ + struct termios orig_termios; \ + int mode; + +#define UV_SIGNAL_PRIVATE_FIELDS \ + /* RB_ENTRY(uv_signal_s) tree_entry; */ \ + struct { \ + struct uv_signal_s* rbe_left; \ + struct uv_signal_s* rbe_right; \ + struct uv_signal_s* rbe_parent; \ + int rbe_color; \ + } tree_entry; \ + /* Use two counters here so we don have to fiddle with atomics. */ \ + unsigned int caught_signals; \ + unsigned int dispatched_signals; + +#define UV_FS_EVENT_PRIVATE_FIELDS \ + uv_fs_event_cb cb; \ + UV_PLATFORM_FS_EVENT_FIELDS \ + +/* fs open() flags supported on this platform: */ +#if defined(O_APPEND) +# define UV_FS_O_APPEND O_APPEND +#else +# define UV_FS_O_APPEND 0 +#endif +#if defined(O_CREAT) +# define UV_FS_O_CREAT O_CREAT +#else +# define UV_FS_O_CREAT 0 +#endif + +#if defined(__linux__) && defined(__arm__) +# define UV_FS_O_DIRECT 0x10000 +#elif defined(__linux__) && defined(__m68k__) +# define UV_FS_O_DIRECT 0x10000 +#elif defined(__linux__) && defined(__mips__) +# define UV_FS_O_DIRECT 0x08000 +#elif defined(__linux__) && defined(__powerpc__) +# define UV_FS_O_DIRECT 0x20000 +#elif defined(__linux__) && defined(__s390x__) +# define UV_FS_O_DIRECT 0x04000 +#elif defined(__linux__) && defined(__x86_64__) +# define UV_FS_O_DIRECT 0x04000 +#elif defined(O_DIRECT) +# define UV_FS_O_DIRECT O_DIRECT +#else +# define UV_FS_O_DIRECT 0 +#endif + +#if defined(O_DIRECTORY) +# define UV_FS_O_DIRECTORY O_DIRECTORY +#else +# define UV_FS_O_DIRECTORY 0 +#endif +#if defined(O_DSYNC) +# define UV_FS_O_DSYNC O_DSYNC +#else +# define UV_FS_O_DSYNC 0 +#endif +#if defined(O_EXCL) +# define UV_FS_O_EXCL O_EXCL +#else +# define UV_FS_O_EXCL 0 +#endif +#if defined(O_EXLOCK) +# define UV_FS_O_EXLOCK O_EXLOCK +#else +# define UV_FS_O_EXLOCK 0 +#endif +#if defined(O_NOATIME) +# define UV_FS_O_NOATIME O_NOATIME +#else +# define UV_FS_O_NOATIME 0 +#endif +#if defined(O_NOCTTY) +# define UV_FS_O_NOCTTY O_NOCTTY +#else +# define UV_FS_O_NOCTTY 0 +#endif +#if defined(O_NOFOLLOW) +# define UV_FS_O_NOFOLLOW O_NOFOLLOW +#else +# define UV_FS_O_NOFOLLOW 0 +#endif +#if defined(O_NONBLOCK) +# define UV_FS_O_NONBLOCK O_NONBLOCK +#else +# define UV_FS_O_NONBLOCK 0 +#endif +#if defined(O_RDONLY) +# define UV_FS_O_RDONLY O_RDONLY +#else +# define UV_FS_O_RDONLY 0 +#endif +#if defined(O_RDWR) +# define UV_FS_O_RDWR O_RDWR +#else +# define UV_FS_O_RDWR 0 +#endif +#if defined(O_SYMLINK) +# define UV_FS_O_SYMLINK O_SYMLINK +#else +# define UV_FS_O_SYMLINK 0 +#endif +#if defined(O_SYNC) +# define UV_FS_O_SYNC O_SYNC +#else +# define UV_FS_O_SYNC 0 +#endif +#if defined(O_TRUNC) +# define UV_FS_O_TRUNC O_TRUNC +#else +# define UV_FS_O_TRUNC 0 +#endif +#if defined(O_WRONLY) +# define UV_FS_O_WRONLY O_WRONLY +#else +# define UV_FS_O_WRONLY 0 +#endif + +/* fs open() flags supported on other platforms: */ +#define UV_FS_O_FILEMAP 0 +#define UV_FS_O_RANDOM 0 +#define UV_FS_O_SHORT_LIVED 0 +#define UV_FS_O_SEQUENTIAL 0 +#define UV_FS_O_TEMPORARY 0 + +#endif /* UV_UNIX_H */ diff --git a/third_party/libuv/include/uv/version.h b/third_party/libuv/include/uv/version.h new file mode 100644 index 000000000..56ac1bf41 --- /dev/null +++ b/third_party/libuv/include/uv/version.h @@ -0,0 +1,43 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_VERSION_H +#define UV_VERSION_H + + /* + * Versions with the same major number are ABI stable. API is allowed to + * evolve between minor releases, but only in a backwards compatible way. + * Make sure you update the -soname directives in configure.ac + * whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but + * not UV_VERSION_PATCH.) + */ + +#define UV_VERSION_MAJOR 1 +#define UV_VERSION_MINOR 44 +#define UV_VERSION_PATCH 1 +#define UV_VERSION_IS_RELEASE 1 +#define UV_VERSION_SUFFIX "" + +#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \ + (UV_VERSION_MINOR << 8) | \ + (UV_VERSION_PATCH)) + +#endif /* UV_VERSION_H */ diff --git a/third_party/libuv/include/uv/win.h b/third_party/libuv/include/uv/win.h new file mode 100644 index 000000000..62be4b04e --- /dev/null +++ b/third_party/libuv/include/uv/win.h @@ -0,0 +1,691 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +#endif + +#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) +typedef intptr_t ssize_t; +# define SSIZE_MAX INTPTR_MAX +# define _SSIZE_T_ +# define _SSIZE_T_DEFINED +#endif + +#include + +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) +typedef struct pollfd { + SOCKET fd; + short events; + short revents; +} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD; +#endif + +#ifndef LOCALE_INVARIANT +# define LOCALE_INVARIANT 0x007f +#endif + +#include +// Disable the typedef in mstcpip.h of MinGW. +#define _TCP_INITIAL_RTO_PARAMETERS _TCP_INITIAL_RTO_PARAMETERS__AVOID +#define TCP_INITIAL_RTO_PARAMETERS TCP_INITIAL_RTO_PARAMETERS__AVOID +#define PTCP_INITIAL_RTO_PARAMETERS PTCP_INITIAL_RTO_PARAMETERS__AVOID +#include +#undef _TCP_INITIAL_RTO_PARAMETERS +#undef TCP_INITIAL_RTO_PARAMETERS +#undef PTCP_INITIAL_RTO_PARAMETERS +#include + +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#include "uv/tree.h" +#include "uv/threadpool.h" + +#define MAX_PIPENAME_LEN 256 + +#ifndef S_IFLNK +# define S_IFLNK 0xA000 +#endif + +/* Additional signals supported by uv_signal and or uv_kill. The CRT defines + * the following signals already: + * + * #define SIGINT 2 + * #define SIGILL 4 + * #define SIGABRT_COMPAT 6 + * #define SIGFPE 8 + * #define SIGSEGV 11 + * #define SIGTERM 15 + * #define SIGBREAK 21 + * #define SIGABRT 22 + * + * The additional signals have values that are common on other Unix + * variants (Linux and Darwin) + */ +#define SIGHUP 1 +#define SIGKILL 9 +#define SIGWINCH 28 + +/* Redefine NSIG to take SIGWINCH into consideration */ +#if defined(NSIG) && NSIG <= SIGWINCH +# undef NSIG +#endif +#ifndef NSIG +# define NSIG SIGWINCH + 1 +#endif + +/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like + * platforms. However MinGW doesn't define it, so we do. */ +#ifndef SIGABRT_COMPAT +# define SIGABRT_COMPAT 6 +#endif + +/* + * Guids and typedefs for winsock extension functions + * Mingw32 doesn't have these :-( + */ +#ifndef WSAID_ACCEPTEX +# define WSAID_ACCEPTEX \ + {0xb5367df1, 0xcbac, 0x11cf, \ + {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} + +# define WSAID_CONNECTEX \ + {0x25a207b9, 0xddf3, 0x4660, \ + {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}} + +# define WSAID_GETACCEPTEXSOCKADDRS \ + {0xb5367df2, 0xcbac, 0x11cf, \ + {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} + +# define WSAID_DISCONNECTEX \ + {0x7fda2e11, 0x8630, 0x436f, \ + {0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}} + +# define WSAID_TRANSMITFILE \ + {0xb5367df0, 0xcbac, 0x11cf, \ + {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} + + typedef BOOL (PASCAL *LPFN_ACCEPTEX) + (SOCKET sListenSocket, + SOCKET sAcceptSocket, + PVOID lpOutputBuffer, + DWORD dwReceiveDataLength, + DWORD dwLocalAddressLength, + DWORD dwRemoteAddressLength, + LPDWORD lpdwBytesReceived, + LPOVERLAPPED lpOverlapped); + + typedef BOOL (PASCAL *LPFN_CONNECTEX) + (SOCKET s, + const struct sockaddr* name, + int namelen, + PVOID lpSendBuffer, + DWORD dwSendDataLength, + LPDWORD lpdwBytesSent, + LPOVERLAPPED lpOverlapped); + + typedef void (PASCAL *LPFN_GETACCEPTEXSOCKADDRS) + (PVOID lpOutputBuffer, + DWORD dwReceiveDataLength, + DWORD dwLocalAddressLength, + DWORD dwRemoteAddressLength, + LPSOCKADDR* LocalSockaddr, + LPINT LocalSockaddrLength, + LPSOCKADDR* RemoteSockaddr, + LPINT RemoteSockaddrLength); + + typedef BOOL (PASCAL *LPFN_DISCONNECTEX) + (SOCKET hSocket, + LPOVERLAPPED lpOverlapped, + DWORD dwFlags, + DWORD reserved); + + typedef BOOL (PASCAL *LPFN_TRANSMITFILE) + (SOCKET hSocket, + HANDLE hFile, + DWORD nNumberOfBytesToWrite, + DWORD nNumberOfBytesPerSend, + LPOVERLAPPED lpOverlapped, + LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, + DWORD dwFlags); + + typedef PVOID RTL_SRWLOCK; + typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; +#endif + +typedef int (WSAAPI* LPFN_WSARECV) + (SOCKET socket, + LPWSABUF buffers, + DWORD buffer_count, + LPDWORD bytes, + LPDWORD flags, + LPWSAOVERLAPPED overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); + +typedef int (WSAAPI* LPFN_WSARECVFROM) + (SOCKET socket, + LPWSABUF buffers, + DWORD buffer_count, + LPDWORD bytes, + LPDWORD flags, + struct sockaddr* addr, + LPINT addr_len, + LPWSAOVERLAPPED overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); + +#ifndef _NTDEF_ + typedef LONG NTSTATUS; + typedef NTSTATUS *PNTSTATUS; +#endif + +#ifndef RTL_CONDITION_VARIABLE_INIT + typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE; +#endif + +typedef struct _AFD_POLL_HANDLE_INFO { + HANDLE Handle; + ULONG Events; + NTSTATUS Status; +} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO; + +typedef struct _AFD_POLL_INFO { + LARGE_INTEGER Timeout; + ULONG NumberOfHandles; + ULONG Exclusive; + AFD_POLL_HANDLE_INFO Handles[1]; +} AFD_POLL_INFO, *PAFD_POLL_INFO; + +#define UV_MSAFD_PROVIDER_COUNT 4 + + +/** + * It should be possible to cast uv_buf_t[] to WSABUF[] + * see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx + */ +typedef struct uv_buf_t { + ULONG len; + char* base; +} uv_buf_t; + +typedef int uv_file; +typedef SOCKET uv_os_sock_t; +typedef HANDLE uv_os_fd_t; +typedef int uv_pid_t; + +typedef HANDLE uv_thread_t; + +typedef HANDLE uv_sem_t; + +typedef CRITICAL_SECTION uv_mutex_t; + +/* This condition variable implementation is based on the SetEvent solution + * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + * We could not use the SignalObjectAndWait solution (section 3.4) because + * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and + * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. + */ + +typedef union { + CONDITION_VARIABLE cond_var; + struct { + unsigned int waiters_count; + CRITICAL_SECTION waiters_count_lock; + HANDLE signal_event; + HANDLE broadcast_event; + } unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */ +} uv_cond_t; + +typedef struct { + SRWLOCK read_write_lock_; + /* TODO: retained for ABI compatibility; remove me in v2.x */ +#ifdef _WIN64 + unsigned char padding_[72]; +#else + unsigned char padding_[44]; +#endif +} uv_rwlock_t; + +typedef struct { + unsigned int n; + unsigned int count; + uv_mutex_t mutex; + uv_sem_t turnstile1; + uv_sem_t turnstile2; +} uv_barrier_t; + +typedef struct { + DWORD tls_index; +} uv_key_t; + +#define UV_ONCE_INIT { 0, NULL } + +typedef struct uv_once_s { + unsigned char ran; + HANDLE event; +} uv_once_t; + +/* Platform-specific definitions for uv_spawn support. */ +typedef unsigned char uv_uid_t; +typedef unsigned char uv_gid_t; + +typedef struct uv__dirent_s { + int d_type; + char d_name[1]; +} uv__dirent_t; + +#define UV_DIR_PRIVATE_FIELDS \ + HANDLE dir_handle; \ + WIN32_FIND_DATAW find_data; \ + BOOL need_find_call; + +#define HAVE_DIRENT_TYPES +#define UV__DT_DIR UV_DIRENT_DIR +#define UV__DT_FILE UV_DIRENT_FILE +#define UV__DT_LINK UV_DIRENT_LINK +#define UV__DT_FIFO UV_DIRENT_FIFO +#define UV__DT_SOCKET UV_DIRENT_SOCKET +#define UV__DT_CHAR UV_DIRENT_CHAR +#define UV__DT_BLOCK UV_DIRENT_BLOCK + +/* Platform-specific definitions for uv_dlopen support. */ +#define UV_DYNAMIC FAR WINAPI +typedef struct { + HMODULE handle; + char* errmsg; +} uv_lib_t; + +#define UV_LOOP_PRIVATE_FIELDS \ + /* The loop's I/O completion port */ \ + HANDLE iocp; \ + /* The current time according to the event loop. in msecs. */ \ + uint64_t time; \ + /* Tail of a single-linked circular queue of pending reqs. If the queue */ \ + /* is empty, tail_ is NULL. If there is only one item, */ \ + /* tail_->next_req == tail_ */ \ + uv_req_t* pending_reqs_tail; \ + /* Head of a single-linked list of closed handles */ \ + uv_handle_t* endgame_handles; \ + /* TODO(bnoordhuis) Stop heap-allocating |timer_heap| in libuv v2.x. */ \ + void* timer_heap; \ + /* Lists of active loop (prepare / check / idle) watchers */ \ + uv_prepare_t* prepare_handles; \ + uv_check_t* check_handles; \ + uv_idle_t* idle_handles; \ + /* This pointer will refer to the prepare/check/idle handle whose */ \ + /* callback is scheduled to be called next. This is needed to allow */ \ + /* safe removal from one of the lists above while that list being */ \ + /* iterated over. */ \ + uv_prepare_t* next_prepare_handle; \ + uv_check_t* next_check_handle; \ + uv_idle_t* next_idle_handle; \ + /* This handle holds the peer sockets for the fast variant of uv_poll_t */ \ + SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \ + /* Counter to keep track of active tcp streams */ \ + unsigned int active_tcp_streams; \ + /* Counter to keep track of active udp streams */ \ + unsigned int active_udp_streams; \ + /* Counter to started timer */ \ + uint64_t timer_counter; \ + /* Threadpool */ \ + void* wq[2]; \ + uv_mutex_t wq_mutex; \ + uv_async_t wq_async; + +#define UV_REQ_TYPE_PRIVATE \ + /* TODO: remove the req suffix */ \ + UV_ACCEPT, \ + UV_FS_EVENT_REQ, \ + UV_POLL_REQ, \ + UV_PROCESS_EXIT, \ + UV_READ, \ + UV_UDP_RECV, \ + UV_WAKEUP, \ + UV_SIGNAL_REQ, + +#define UV_REQ_PRIVATE_FIELDS \ + union { \ + /* Used by I/O operations */ \ + struct { \ + OVERLAPPED overlapped; \ + size_t queued_bytes; \ + } io; \ + } u; \ + struct uv_req_s* next_req; + +#define UV_WRITE_PRIVATE_FIELDS \ + int coalesced; \ + uv_buf_t write_buffer; \ + HANDLE event_handle; \ + HANDLE wait_handle; + +#define UV_CONNECT_PRIVATE_FIELDS \ + /* empty */ + +#define UV_SHUTDOWN_PRIVATE_FIELDS \ + /* empty */ + +#define UV_UDP_SEND_PRIVATE_FIELDS \ + /* empty */ + +#define UV_PRIVATE_REQ_TYPES \ + typedef struct uv_pipe_accept_s { \ + UV_REQ_FIELDS \ + HANDLE pipeHandle; \ + struct uv_pipe_accept_s* next_pending; \ + } uv_pipe_accept_t; \ + \ + typedef struct uv_tcp_accept_s { \ + UV_REQ_FIELDS \ + SOCKET accept_socket; \ + char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \ + HANDLE event_handle; \ + HANDLE wait_handle; \ + struct uv_tcp_accept_s* next_pending; \ + } uv_tcp_accept_t; \ + \ + typedef struct uv_read_s { \ + UV_REQ_FIELDS \ + HANDLE event_handle; \ + HANDLE wait_handle; \ + } uv_read_t; + +#define uv_stream_connection_fields \ + unsigned int write_reqs_pending; \ + uv_shutdown_t* shutdown_req; + +#define uv_stream_server_fields \ + uv_connection_cb connection_cb; + +#define UV_STREAM_PRIVATE_FIELDS \ + unsigned int reqs_pending; \ + int activecnt; \ + uv_read_t read_req; \ + union { \ + struct { uv_stream_connection_fields } conn; \ + struct { uv_stream_server_fields } serv; \ + } stream; + +#define uv_tcp_server_fields \ + uv_tcp_accept_t* accept_reqs; \ + unsigned int processed_accepts; \ + uv_tcp_accept_t* pending_accepts; \ + LPFN_ACCEPTEX func_acceptex; + +#define uv_tcp_connection_fields \ + uv_buf_t read_buffer; \ + LPFN_CONNECTEX func_connectex; + +#define UV_TCP_PRIVATE_FIELDS \ + SOCKET socket; \ + int delayed_error; \ + union { \ + struct { uv_tcp_server_fields } serv; \ + struct { uv_tcp_connection_fields } conn; \ + } tcp; + +#define UV_UDP_PRIVATE_FIELDS \ + SOCKET socket; \ + unsigned int reqs_pending; \ + int activecnt; \ + uv_req_t recv_req; \ + uv_buf_t recv_buffer; \ + struct sockaddr_storage recv_from; \ + int recv_from_len; \ + uv_udp_recv_cb recv_cb; \ + uv_alloc_cb alloc_cb; \ + LPFN_WSARECV func_wsarecv; \ + LPFN_WSARECVFROM func_wsarecvfrom; + +#define uv_pipe_server_fields \ + int pending_instances; \ + uv_pipe_accept_t* accept_reqs; \ + uv_pipe_accept_t* pending_accepts; + +#define uv_pipe_connection_fields \ + uv_timer_t* eof_timer; \ + uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \ + DWORD ipc_remote_pid; \ + union { \ + uint32_t payload_remaining; \ + uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \ + } ipc_data_frame; \ + void* ipc_xfer_queue[2]; \ + int ipc_xfer_queue_length; \ + uv_write_t* non_overlapped_writes_tail; \ + CRITICAL_SECTION readfile_thread_lock; \ + volatile HANDLE readfile_thread_handle; + +#define UV_PIPE_PRIVATE_FIELDS \ + HANDLE handle; \ + WCHAR* name; \ + union { \ + struct { uv_pipe_server_fields } serv; \ + struct { uv_pipe_connection_fields } conn; \ + } pipe; + +/* TODO: put the parser states in an union - TTY handles are always half-duplex + * so read-state can safely overlap write-state. */ +#define UV_TTY_PRIVATE_FIELDS \ + HANDLE handle; \ + union { \ + struct { \ + /* Used for readable TTY handles */ \ + /* TODO: remove me in v2.x. */ \ + HANDLE unused_; \ + uv_buf_t read_line_buffer; \ + HANDLE read_raw_wait; \ + /* Fields used for translating win keystrokes into vt100 characters */ \ + char last_key[8]; \ + unsigned char last_key_offset; \ + unsigned char last_key_len; \ + WCHAR last_utf16_high_surrogate; \ + INPUT_RECORD last_input_record; \ + } rd; \ + struct { \ + /* Used for writable TTY handles */ \ + /* utf8-to-utf16 conversion state */ \ + unsigned int utf8_codepoint; \ + unsigned char utf8_bytes_left; \ + /* eol conversion state */ \ + unsigned char previous_eol; \ + /* ansi parser state */ \ + unsigned short ansi_parser_state; \ + unsigned char ansi_csi_argc; \ + unsigned short ansi_csi_argv[4]; \ + COORD saved_position; \ + WORD saved_attributes; \ + } wr; \ + } tty; + +#define UV_POLL_PRIVATE_FIELDS \ + SOCKET socket; \ + /* Used in fast mode */ \ + SOCKET peer_socket; \ + AFD_POLL_INFO afd_poll_info_1; \ + AFD_POLL_INFO afd_poll_info_2; \ + /* Used in fast and slow mode. */ \ + uv_req_t poll_req_1; \ + uv_req_t poll_req_2; \ + unsigned char submitted_events_1; \ + unsigned char submitted_events_2; \ + unsigned char mask_events_1; \ + unsigned char mask_events_2; \ + unsigned char events; + +#define UV_TIMER_PRIVATE_FIELDS \ + void* heap_node[3]; \ + int unused; \ + uint64_t timeout; \ + uint64_t repeat; \ + uint64_t start_id; \ + uv_timer_cb timer_cb; + +#define UV_ASYNC_PRIVATE_FIELDS \ + struct uv_req_s async_req; \ + uv_async_cb async_cb; \ + /* char to avoid alignment issues */ \ + char volatile async_sent; + +#define UV_PREPARE_PRIVATE_FIELDS \ + uv_prepare_t* prepare_prev; \ + uv_prepare_t* prepare_next; \ + uv_prepare_cb prepare_cb; + +#define UV_CHECK_PRIVATE_FIELDS \ + uv_check_t* check_prev; \ + uv_check_t* check_next; \ + uv_check_cb check_cb; + +#define UV_IDLE_PRIVATE_FIELDS \ + uv_idle_t* idle_prev; \ + uv_idle_t* idle_next; \ + uv_idle_cb idle_cb; + +#define UV_HANDLE_PRIVATE_FIELDS \ + uv_handle_t* endgame_next; \ + unsigned int flags; + +#define UV_GETADDRINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getaddrinfo_cb getaddrinfo_cb; \ + void* alloc; \ + WCHAR* node; \ + WCHAR* service; \ + /* The addrinfoW field is used to store a pointer to the hints, and */ \ + /* later on to store the result of GetAddrInfoW. The final result will */ \ + /* be converted to struct addrinfo* and stored in the addrinfo field. */ \ + struct addrinfoW* addrinfow; \ + struct addrinfo* addrinfo; \ + int retcode; + +#define UV_GETNAMEINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getnameinfo_cb getnameinfo_cb; \ + struct sockaddr_storage storage; \ + int flags; \ + char host[NI_MAXHOST]; \ + char service[NI_MAXSERV]; \ + int retcode; + +#define UV_PROCESS_PRIVATE_FIELDS \ + struct uv_process_exit_s { \ + UV_REQ_FIELDS \ + } exit_req; \ + BYTE* child_stdio_buffer; \ + int exit_signal; \ + HANDLE wait_handle; \ + HANDLE process_handle; \ + volatile char exit_cb_pending; + +#define UV_FS_PRIVATE_FIELDS \ + struct uv__work work_req; \ + int flags; \ + DWORD sys_errno_; \ + union { \ + /* TODO: remove me in 0.9. */ \ + WCHAR* pathw; \ + int fd; \ + } file; \ + union { \ + struct { \ + int mode; \ + WCHAR* new_pathw; \ + int file_flags; \ + int fd_out; \ + unsigned int nbufs; \ + uv_buf_t* bufs; \ + int64_t offset; \ + uv_buf_t bufsml[4]; \ + } info; \ + struct { \ + double atime; \ + double mtime; \ + } time; \ + } fs; + +#define UV_WORK_PRIVATE_FIELDS \ + struct uv__work work_req; + +#define UV_FS_EVENT_PRIVATE_FIELDS \ + struct uv_fs_event_req_s { \ + UV_REQ_FIELDS \ + } req; \ + HANDLE dir_handle; \ + int req_pending; \ + uv_fs_event_cb cb; \ + WCHAR* filew; \ + WCHAR* short_filew; \ + WCHAR* dirw; \ + char* buffer; + +#define UV_SIGNAL_PRIVATE_FIELDS \ + RB_ENTRY(uv_signal_s) tree_entry; \ + struct uv_req_s signal_req; \ + unsigned long pending_signum; + +#ifndef F_OK +#define F_OK 0 +#endif +#ifndef R_OK +#define R_OK 4 +#endif +#ifndef W_OK +#define W_OK 2 +#endif +#ifndef X_OK +#define X_OK 1 +#endif + +/* fs open() flags supported on this platform: */ +#define UV_FS_O_APPEND _O_APPEND +#define UV_FS_O_CREAT _O_CREAT +#define UV_FS_O_EXCL _O_EXCL +#define UV_FS_O_FILEMAP 0x20000000 +#define UV_FS_O_RANDOM _O_RANDOM +#define UV_FS_O_RDONLY _O_RDONLY +#define UV_FS_O_RDWR _O_RDWR +#define UV_FS_O_SEQUENTIAL _O_SEQUENTIAL +#define UV_FS_O_SHORT_LIVED _O_SHORT_LIVED +#define UV_FS_O_TEMPORARY _O_TEMPORARY +#define UV_FS_O_TRUNC _O_TRUNC +#define UV_FS_O_WRONLY _O_WRONLY + +/* fs open() flags supported on other platforms (or mapped on this platform): */ +#define UV_FS_O_DIRECT 0x02000000 /* FILE_FLAG_NO_BUFFERING */ +#define UV_FS_O_DIRECTORY 0 +#define UV_FS_O_DSYNC 0x04000000 /* FILE_FLAG_WRITE_THROUGH */ +#define UV_FS_O_EXLOCK 0x10000000 /* EXCLUSIVE SHARING MODE */ +#define UV_FS_O_NOATIME 0 +#define UV_FS_O_NOCTTY 0 +#define UV_FS_O_NOFOLLOW 0 +#define UV_FS_O_NONBLOCK 0 +#define UV_FS_O_SYMLINK 0 +#define UV_FS_O_SYNC 0x08000000 /* FILE_FLAG_WRITE_THROUGH */ diff --git a/third_party/libuv/include/uv_ndk/uv.h b/third_party/libuv/include/uv_ndk/uv.h new file mode 100644 index 000000000..d1b0ada67 --- /dev/null +++ b/third_party/libuv/include/uv_ndk/uv.h @@ -0,0 +1,1826 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* See https://github.com/libuv/libuv#documentation for documentation. */ + +#ifndef UV_H +#define UV_H +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED) +#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both." +#endif + +#ifdef _WIN32 + /* Windows - set up dll import/export decorators. */ +# if defined(BUILDING_UV_SHARED) + /* Building shared library. */ +# define UV_EXTERN __declspec(dllexport) +# elif defined(USING_UV_SHARED) + /* Using shared library. */ +# define UV_EXTERN __declspec(dllimport) +# else + /* Building static library. */ +# define UV_EXTERN /* nothing */ +# endif +#elif __GNUC__ >= 4 +# define UV_EXTERN __attribute__((visibility("default"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) /* Sun Studio >= 8 */ +# define UV_EXTERN __global +#else +# define UV_EXTERN /* nothing */ +#endif + +#include "uv/errno.h" +#include "uv/version.h" +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#if defined(_WIN32) +# include "uv/win.h" +#else +# include "uv/unix.h" +#endif + +/* Expand this list if necessary. */ +#define UV_ERRNO_MAP(XX) \ + XX(E2BIG, "argument list too long") \ + XX(EACCES, "permission denied") \ + XX(EADDRINUSE, "address already in use") \ + XX(EADDRNOTAVAIL, "address not available") \ + XX(EAFNOSUPPORT, "address family not supported") \ + XX(EAGAIN, "resource temporarily unavailable") \ + XX(EAI_ADDRFAMILY, "address family not supported") \ + XX(EAI_AGAIN, "temporary failure") \ + XX(EAI_BADFLAGS, "bad ai_flags value") \ + XX(EAI_BADHINTS, "invalid value for hints") \ + XX(EAI_CANCELED, "request canceled") \ + XX(EAI_FAIL, "permanent failure") \ + XX(EAI_FAMILY, "ai_family not supported") \ + XX(EAI_MEMORY, "out of memory") \ + XX(EAI_NODATA, "no address") \ + XX(EAI_NONAME, "unknown node or service") \ + XX(EAI_OVERFLOW, "argument buffer overflow") \ + XX(EAI_PROTOCOL, "resolved protocol is unknown") \ + XX(EAI_SERVICE, "service not available for socket type") \ + XX(EAI_SOCKTYPE, "socket type not supported") \ + XX(EALREADY, "connection already in progress") \ + XX(EBADF, "bad file descriptor") \ + XX(EBUSY, "resource busy or locked") \ + XX(ECANCELED, "operation canceled") \ + XX(ECHARSET, "invalid Unicode character") \ + XX(ECONNABORTED, "software caused connection abort") \ + XX(ECONNREFUSED, "connection refused") \ + XX(ECONNRESET, "connection reset by peer") \ + XX(EDESTADDRREQ, "destination address required") \ + XX(EEXIST, "file already exists") \ + XX(EFAULT, "bad address in system call argument") \ + XX(EFBIG, "file too large") \ + XX(EHOSTUNREACH, "host is unreachable") \ + XX(EINTR, "interrupted system call") \ + XX(EINVAL, "invalid argument") \ + XX(EIO, "i/o error") \ + XX(EISCONN, "socket is already connected") \ + XX(EISDIR, "illegal operation on a directory") \ + XX(ELOOP, "too many symbolic links encountered") \ + XX(EMFILE, "too many open files") \ + XX(EMSGSIZE, "message too long") \ + XX(ENAMETOOLONG, "name too long") \ + XX(ENETDOWN, "network is down") \ + XX(ENETUNREACH, "network is unreachable") \ + XX(ENFILE, "file table overflow") \ + XX(ENOBUFS, "no buffer space available") \ + XX(ENODEV, "no such device") \ + XX(ENOENT, "no such file or directory") \ + XX(ENOMEM, "not enough memory") \ + XX(ENONET, "machine is not on the network") \ + XX(ENOPROTOOPT, "protocol not available") \ + XX(ENOSPC, "no space left on device") \ + XX(ENOSYS, "function not implemented") \ + XX(ENOTCONN, "socket is not connected") \ + XX(ENOTDIR, "not a directory") \ + XX(ENOTEMPTY, "directory not empty") \ + XX(ENOTSOCK, "socket operation on non-socket") \ + XX(ENOTSUP, "operation not supported on socket") \ + XX(EOVERFLOW, "value too large for defined data type") \ + XX(EPERM, "operation not permitted") \ + XX(EPIPE, "broken pipe") \ + XX(EPROTO, "protocol error") \ + XX(EPROTONOSUPPORT, "protocol not supported") \ + XX(EPROTOTYPE, "protocol wrong type for socket") \ + XX(ERANGE, "result too large") \ + XX(EROFS, "read-only file system") \ + XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \ + XX(ESPIPE, "invalid seek") \ + XX(ESRCH, "no such process") \ + XX(ETIMEDOUT, "connection timed out") \ + XX(ETXTBSY, "text file is busy") \ + XX(EXDEV, "cross-device link not permitted") \ + XX(UNKNOWN, "unknown error") \ + XX(EOF, "end of file") \ + XX(ENXIO, "no such device or address") \ + XX(EMLINK, "too many links") \ + XX(EHOSTDOWN, "host is down") \ + XX(EREMOTEIO, "remote I/O error") \ + XX(ENOTTY, "inappropriate ioctl for device") \ + XX(EFTYPE, "inappropriate file type or format") \ + XX(EILSEQ, "illegal byte sequence") \ + XX(ESOCKTNOSUPPORT, "socket type not supported") \ + +#define UV_HANDLE_TYPE_MAP(XX) \ + XX(ASYNC, async) \ + XX(CHECK, check) \ + XX(FS_EVENT, fs_event) \ + XX(FS_POLL, fs_poll) \ + XX(HANDLE, handle) \ + XX(IDLE, idle) \ + XX(NAMED_PIPE, pipe) \ + XX(POLL, poll) \ + XX(PREPARE, prepare) \ + XX(PROCESS, process) \ + XX(STREAM, stream) \ + XX(TCP, tcp) \ + XX(TIMER, timer) \ + XX(TTY, tty) \ + XX(UDP, udp) \ + XX(SIGNAL, signal) \ + +#define UV_REQ_TYPE_MAP(XX) \ + XX(REQ, req) \ + XX(CONNECT, connect) \ + XX(WRITE, write) \ + XX(SHUTDOWN, shutdown) \ + XX(UDP_SEND, udp_send) \ + XX(FS, fs) \ + XX(WORK, work) \ + XX(GETADDRINFO, getaddrinfo) \ + XX(GETNAMEINFO, getnameinfo) \ + XX(RANDOM, random) \ + +typedef enum { +#define XX(code, _) UV_ ## code = UV__ ## code, + UV_ERRNO_MAP(XX) +#undef XX + UV_ERRNO_MAX = UV__EOF - 1 +} uv_errno_t; + +typedef enum { + UV_UNKNOWN_HANDLE = 0, +#define XX(uc, lc) UV_##uc, + UV_HANDLE_TYPE_MAP(XX) +#undef XX + UV_FILE, + UV_HANDLE_TYPE_MAX +} uv_handle_type; + +typedef enum { + UV_UNKNOWN_REQ = 0, +#define XX(uc, lc) UV_##uc, + UV_REQ_TYPE_MAP(XX) +#undef XX + UV_REQ_TYPE_PRIVATE + UV_REQ_TYPE_MAX +} uv_req_type; + + +/* Handle types. */ +typedef struct uv_loop_s uv_loop_t; +typedef struct uv_handle_s uv_handle_t; +typedef struct uv_dir_s uv_dir_t; +typedef struct uv_stream_s uv_stream_t; +typedef struct uv_tcp_s uv_tcp_t; +typedef struct uv_udp_s uv_udp_t; +typedef struct uv_pipe_s uv_pipe_t; +typedef struct uv_tty_s uv_tty_t; +typedef struct uv_poll_s uv_poll_t; +typedef struct uv_timer_s uv_timer_t; +typedef struct uv_prepare_s uv_prepare_t; +typedef struct uv_check_s uv_check_t; +typedef struct uv_idle_s uv_idle_t; +typedef struct uv_async_s uv_async_t; +typedef struct uv_process_s uv_process_t; +typedef struct uv_fs_event_s uv_fs_event_t; +typedef struct uv_fs_poll_s uv_fs_poll_t; +typedef struct uv_signal_s uv_signal_t; + +/* Request types. */ +typedef struct uv_req_s uv_req_t; +typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; +typedef struct uv_getnameinfo_s uv_getnameinfo_t; +typedef struct uv_shutdown_s uv_shutdown_t; +typedef struct uv_write_s uv_write_t; +typedef struct uv_connect_s uv_connect_t; +typedef struct uv_udp_send_s uv_udp_send_t; +typedef struct uv_fs_s uv_fs_t; +typedef struct uv_work_s uv_work_t; +typedef struct uv_random_s uv_random_t; + +/* None of the above. */ +typedef struct uv_env_item_s uv_env_item_t; +typedef struct uv_cpu_info_s uv_cpu_info_t; +typedef struct uv_interface_address_s uv_interface_address_t; +typedef struct uv_dirent_s uv_dirent_t; +typedef struct uv_passwd_s uv_passwd_t; +typedef struct uv_utsname_s uv_utsname_t; +typedef struct uv_statfs_s uv_statfs_t; + +typedef enum { + UV_LOOP_BLOCK_SIGNAL = 0, + UV_METRICS_IDLE_TIME +} uv_loop_option; + +typedef enum { + UV_RUN_DEFAULT = 0, + UV_RUN_ONCE, + UV_RUN_NOWAIT +} uv_run_mode; + + +UV_EXTERN unsigned int uv_version(void); +UV_EXTERN const char* uv_version_string(void); + +typedef void* (*uv_malloc_func)(size_t size); +typedef void* (*uv_realloc_func)(void* ptr, size_t size); +typedef void* (*uv_calloc_func)(size_t count, size_t size); +typedef void (*uv_free_func)(void* ptr); + +UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func, + uv_realloc_func realloc_func, + uv_calloc_func calloc_func, + uv_free_func free_func); + +UV_EXTERN uv_loop_t* uv_default_loop(void); +UV_EXTERN int uv_loop_init(uv_loop_t* loop); +UV_EXTERN int uv_loop_close(uv_loop_t* loop); +/* + * NOTE: + * This function is DEPRECATED (to be removed after 0.12), users should + * allocate the loop manually and use uv_loop_init instead. + */ +UV_EXTERN uv_loop_t* uv_loop_new(void); +/* + * NOTE: + * This function is DEPRECATED (to be removed after 0.12). Users should use + * uv_loop_close and free the memory manually instead. + */ +UV_EXTERN void uv_loop_delete(uv_loop_t*); +UV_EXTERN size_t uv_loop_size(void); +UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); +UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); +UV_EXTERN int uv_loop_fork(uv_loop_t* loop); + +UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); +UV_EXTERN void uv_stop(uv_loop_t*); + +UV_EXTERN void uv_ref(uv_handle_t*); +UV_EXTERN void uv_unref(uv_handle_t*); +UV_EXTERN int uv_has_ref(const uv_handle_t*); + +UV_EXTERN void uv_update_time(uv_loop_t*); +UV_EXTERN uint64_t uv_now(const uv_loop_t*); + +UV_EXTERN int uv_backend_fd(const uv_loop_t*); +UV_EXTERN int uv_backend_timeout(const uv_loop_t*); + +typedef void (*uv_alloc_cb)(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf); +typedef void (*uv_read_cb)(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf); +typedef void (*uv_write_cb)(uv_write_t* req, int status); +typedef void (*uv_connect_cb)(uv_connect_t* req, int status); +typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status); +typedef void (*uv_connection_cb)(uv_stream_t* server, int status); +typedef void (*uv_close_cb)(uv_handle_t* handle); +typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events); +typedef void (*uv_timer_cb)(uv_timer_t* handle); +typedef void (*uv_async_cb)(uv_async_t* handle); +typedef void (*uv_prepare_cb)(uv_prepare_t* handle); +typedef void (*uv_check_cb)(uv_check_t* handle); +typedef void (*uv_idle_cb)(uv_idle_t* handle); +typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal); +typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg); +typedef void (*uv_fs_cb)(uv_fs_t* req); +typedef void (*uv_work_cb)(uv_work_t* req); +typedef void (*uv_after_work_cb)(uv_work_t* req, int status); +typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, + int status, + struct addrinfo* res); +typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, + int status, + const char* hostname, + const char* service); +typedef void (*uv_random_cb)(uv_random_t* req, + int status, + void* buf, + size_t buflen); + +typedef struct { + long tv_sec; + long tv_nsec; +} uv_timespec_t; + + +typedef struct { + uint64_t st_dev; + uint64_t st_mode; + uint64_t st_nlink; + uint64_t st_uid; + uint64_t st_gid; + uint64_t st_rdev; + uint64_t st_ino; + uint64_t st_size; + uint64_t st_blksize; + uint64_t st_blocks; + uint64_t st_flags; + uint64_t st_gen; + uv_timespec_t st_atim; + uv_timespec_t st_mtim; + uv_timespec_t st_ctim; + uv_timespec_t st_birthtim; +} uv_stat_t; + + +typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, + const char* filename, + int events, + int status); + +typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); + +typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum); + + +typedef enum { + UV_LEAVE_GROUP = 0, + UV_JOIN_GROUP +} uv_membership; + + +UV_EXTERN int uv_translate_sys_error(int sys_errno); + +UV_EXTERN const char* uv_strerror(int err); +UV_EXTERN char* uv_strerror_r(int err, char* buf, size_t buflen); + +UV_EXTERN const char* uv_err_name(int err); +UV_EXTERN char* uv_err_name_r(int err, char* buf, size_t buflen); + + +#define UV_REQ_FIELDS \ + /* public */ \ + void* data; \ + /* read-only */ \ + uv_req_type type; \ + /* private */ \ + void* reserved[6]; \ + UV_REQ_PRIVATE_FIELDS \ + +/* Abstract base class of all requests. */ +struct uv_req_s { + UV_REQ_FIELDS +}; + + +/* Platform-specific request types. */ +UV_PRIVATE_REQ_TYPES + + +UV_EXTERN int uv_shutdown(uv_shutdown_t* req, + uv_stream_t* handle, + uv_shutdown_cb cb); + +struct uv_shutdown_s { + UV_REQ_FIELDS + uv_stream_t* handle; + uv_shutdown_cb cb; + UV_SHUTDOWN_PRIVATE_FIELDS +}; + + +#define UV_HANDLE_FIELDS \ + /* public */ \ + void* data; \ + /* read-only */ \ + uv_loop_t* loop; \ + uv_handle_type type; \ + /* private */ \ + uv_close_cb close_cb; \ + void* handle_queue[2]; \ + union { \ + int fd; \ + void* reserved[4]; \ + } u; \ + UV_HANDLE_PRIVATE_FIELDS \ + +/* The abstract base class of all handles. */ +struct uv_handle_s { + UV_HANDLE_FIELDS +}; + +UV_EXTERN size_t uv_handle_size(uv_handle_type type); +UV_EXTERN uv_handle_type uv_handle_get_type(const uv_handle_t* handle); +UV_EXTERN const char* uv_handle_type_name(uv_handle_type type); +UV_EXTERN void* uv_handle_get_data(const uv_handle_t* handle); +UV_EXTERN uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle); +UV_EXTERN void uv_handle_set_data(uv_handle_t* handle, void* data); + +UV_EXTERN size_t uv_req_size(uv_req_type type); +UV_EXTERN void* uv_req_get_data(const uv_req_t* req); +UV_EXTERN void uv_req_set_data(uv_req_t* req, void* data); +UV_EXTERN uv_req_type uv_req_get_type(const uv_req_t* req); +UV_EXTERN const char* uv_req_type_name(uv_req_type type); + +UV_EXTERN int uv_is_active(const uv_handle_t* handle); + +UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg); + +/* Helpers for ad hoc debugging, no API/ABI stability guaranteed. */ +UV_EXTERN void uv_print_all_handles(uv_loop_t* loop, FILE* stream); +UV_EXTERN void uv_print_active_handles(uv_loop_t* loop, FILE* stream); + +UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb); + +UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value); +UV_EXTERN int uv_recv_buffer_size(uv_handle_t* handle, int* value); + +UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd); + +UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len); + + +#define UV_STREAM_FIELDS \ + /* number of bytes queued for writing */ \ + size_t write_queue_size; \ + uv_alloc_cb alloc_cb; \ + uv_read_cb read_cb; \ + /* private */ \ + UV_STREAM_PRIVATE_FIELDS + +/* + * uv_stream_t is a subclass of uv_handle_t. + * + * uv_stream is an abstract class. + * + * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t. + */ +struct uv_stream_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS +}; + +UV_EXTERN size_t uv_stream_get_write_queue_size(const uv_stream_t* stream); + +UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb); +UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client); + +UV_EXTERN int uv_read_start(uv_stream_t*, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb); +UV_EXTERN int uv_read_stop(uv_stream_t*); + +UV_EXTERN int uv_write(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb); +UV_EXTERN int uv_write2(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb); +UV_EXTERN int uv_try_write(uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs); + +/* uv_write_t is a subclass of uv_req_t. */ +struct uv_write_s { + UV_REQ_FIELDS + uv_write_cb cb; + uv_stream_t* send_handle; /* TODO: make private and unix-only in v2.x. */ + uv_stream_t* handle; + UV_WRITE_PRIVATE_FIELDS +}; + + +UV_EXTERN int uv_is_readable(const uv_stream_t* handle); +UV_EXTERN int uv_is_writable(const uv_stream_t* handle); + +UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking); + +UV_EXTERN int uv_is_closing(const uv_handle_t* handle); + + +/* + * uv_tcp_t is a subclass of uv_stream_t. + * + * Represents a TCP stream or TCP server. + */ +struct uv_tcp_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_TCP_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle); +UV_EXTERN int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags); +UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock); +UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable); +UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, + int enable, + unsigned int delay); +UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); + +enum uv_tcp_flags { + /* Used with uv_tcp_bind, when an IPv6 address is used. */ + UV_TCP_IPV6ONLY = 1 +}; + +UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int flags); +UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb); +UV_EXTERN int uv_tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + uv_connect_cb cb); + +/* uv_connect_t is a subclass of uv_req_t. */ +struct uv_connect_s { + UV_REQ_FIELDS + uv_connect_cb cb; + uv_stream_t* handle; + UV_CONNECT_PRIVATE_FIELDS +}; + + +/* + * UDP support. + */ + +enum uv_udp_flags { + /* Disables dual stack mode. */ + UV_UDP_IPV6ONLY = 1, + /* + * Indicates message was truncated because read buffer was too small. The + * remainder was discarded by the OS. Used in uv_udp_recv_cb. + */ + UV_UDP_PARTIAL = 2, + /* + * Indicates if SO_REUSEADDR will be set when binding the handle. + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + */ + UV_UDP_REUSEADDR = 4, + /* + * Indicates that the message was received by recvmmsg, so the buffer provided + * must not be freed by the recv_cb callback. + */ + UV_UDP_MMSG_CHUNK = 8, + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UV_UDP_MMSG_FREE = 16, + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from suppressing some ICMP error + * messages and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UV_UDP_LINUX_RECVERR = 32, + /* + * Indicates that recvmmsg should be used, if available. + */ + UV_UDP_RECVMMSG = 256 +}; + +typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status); +typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags); + +/* uv_udp_t is a subclass of uv_handle_t. */ +struct uv_udp_s { + UV_HANDLE_FIELDS + /* read-only */ + /* + * Number of bytes queued for sending. This field strictly shows how much + * information is currently queued. + */ + size_t send_queue_size; + /* + * Number of send requests currently in the queue awaiting to be processed. + */ + size_t send_queue_count; + UV_UDP_PRIVATE_FIELDS +}; + +/* uv_udp_send_t is a subclass of uv_req_t. */ +struct uv_udp_send_s { + UV_REQ_FIELDS + uv_udp_t* handle; + uv_udp_send_cb cb; + UV_UDP_SEND_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle); +UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags); +UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock); +UV_EXTERN int uv_udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int flags); +UV_EXTERN int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr); + +UV_EXTERN int uv_udp_getpeername(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_udp_getsockname(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + uv_membership membership); +UV_EXTERN int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership); +UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle, + const char* interface_addr); +UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + uv_udp_send_cb send_cb); +UV_EXTERN int uv_udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr); +UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, + uv_alloc_cb alloc_cb, + uv_udp_recv_cb recv_cb); +UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_size(const uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_count(const uv_udp_t* handle); + + +/* + * uv_tty_t is a subclass of uv_stream_t. + * + * Representing a stream for the console. + */ +struct uv_tty_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_TTY_PRIVATE_FIELDS +}; + +typedef enum { + /* Initial/normal terminal mode */ + UV_TTY_MODE_NORMAL, + /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */ + UV_TTY_MODE_RAW, + /* Binary-safe I/O mode for IPC (Unix-only) */ + UV_TTY_MODE_IO +} uv_tty_mode_t; + +typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process the virtual terminal sequence. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED +} uv_tty_vtermstate_t; + + +UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); +UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode); +UV_EXTERN int uv_tty_reset_mode(void); +UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); +UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state); +UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state); + +#ifdef __cplusplus +extern "C++" { + +inline int uv_tty_set_mode(uv_tty_t* handle, int mode) { + return uv_tty_set_mode(handle, static_cast(mode)); +} + +} +#endif + +UV_EXTERN uv_handle_type uv_guess_handle(uv_file file); + +/* + * uv_pipe_t is a subclass of uv_stream_t. + * + * Representing a pipe stream or pipe server. On Windows this is a Named + * Pipe. On Unix this is a Unix domain socket. + */ +struct uv_pipe_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + int ipc; /* non-zero if this pipe is used for passing handles */ + UV_PIPE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc); +UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file); +UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name); +UV_EXTERN void uv_pipe_connect(uv_connect_t* req, + uv_pipe_t* handle, + const char* name, + uv_connect_cb cb); +UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, + char* buffer, + size_t* size); +UV_EXTERN int uv_pipe_getpeername(const uv_pipe_t* handle, + char* buffer, + size_t* size); +UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count); +UV_EXTERN int uv_pipe_pending_count(uv_pipe_t* handle); +UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle); +UV_EXTERN int uv_pipe_chmod(uv_pipe_t* handle, int flags); + + +struct uv_poll_s { + UV_HANDLE_FIELDS + uv_poll_cb poll_cb; + UV_POLL_PRIVATE_FIELDS +}; + +enum uv_poll_event { + UV_READABLE = 1, + UV_WRITABLE = 2, + UV_DISCONNECT = 4, + UV_PRIORITIZED = 8 +}; + +UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd); +UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, + uv_poll_t* handle, + uv_os_sock_t socket); +UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb); +UV_EXTERN int uv_poll_stop(uv_poll_t* handle); + + +struct uv_prepare_s { + UV_HANDLE_FIELDS + UV_PREPARE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare); +UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb); +UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare); + + +struct uv_check_s { + UV_HANDLE_FIELDS + UV_CHECK_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check); +UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb); +UV_EXTERN int uv_check_stop(uv_check_t* check); + + +struct uv_idle_s { + UV_HANDLE_FIELDS + UV_IDLE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle); +UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb); +UV_EXTERN int uv_idle_stop(uv_idle_t* idle); + + +struct uv_async_s { + UV_HANDLE_FIELDS + UV_ASYNC_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_async_init(uv_loop_t*, + uv_async_t* async, + uv_async_cb async_cb); +UV_EXTERN int uv_async_send(uv_async_t* async); + + +/* + * uv_timer_t is a subclass of uv_handle_t. + * + * Used to get woken up at a specified time in the future. + */ +struct uv_timer_s { + UV_HANDLE_FIELDS + UV_TIMER_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle); +UV_EXTERN int uv_timer_start(uv_timer_t* handle, + uv_timer_cb cb, + uint64_t timeout, + uint64_t repeat); +UV_EXTERN int uv_timer_stop(uv_timer_t* handle); +UV_EXTERN int uv_timer_again(uv_timer_t* handle); +UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat); +UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle); + + +/* + * uv_getaddrinfo_t is a subclass of uv_req_t. + * + * Request object for uv_getaddrinfo. + */ +struct uv_getaddrinfo_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* struct addrinfo* addrinfo is marked as private, but it really isn't. */ + UV_GETADDRINFO_PRIVATE_FIELDS +}; + + +UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop, + uv_getaddrinfo_t* req, + uv_getaddrinfo_cb getaddrinfo_cb, + const char* node, + const char* service, + const struct addrinfo* hints); +UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai); + + +/* +* uv_getnameinfo_t is a subclass of uv_req_t. +* +* Request object for uv_getnameinfo. +*/ +struct uv_getnameinfo_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* host and service are marked as private, but they really aren't. */ + UV_GETNAMEINFO_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_getnameinfo(uv_loop_t* loop, + uv_getnameinfo_t* req, + uv_getnameinfo_cb getnameinfo_cb, + const struct sockaddr* addr, + int flags); + + +/* uv_spawn() options. */ +typedef enum { + UV_IGNORE = 0x00, + UV_CREATE_PIPE = 0x01, + UV_INHERIT_FD = 0x02, + UV_INHERIT_STREAM = 0x04, + + /* + * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE + * determine the direction of flow, from the child process' perspective. Both + * flags may be specified to create a duplex data stream. + */ + UV_READABLE_PIPE = 0x10, + UV_WRITABLE_PIPE = 0x20, + + /* + * When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the + * handle in non-blocking mode in the child. This may cause loss of data, + * if the child is not designed to handle to encounter this mode, + * but can also be significantly more efficient. + */ + UV_NONBLOCK_PIPE = 0x40, + UV_OVERLAPPED_PIPE = 0x40 /* old name, for compatibility */ +} uv_stdio_flags; + +typedef struct uv_stdio_container_s { + uv_stdio_flags flags; + + union { + uv_stream_t* stream; + int fd; + } data; +} uv_stdio_container_t; + +typedef struct uv_process_options_s { + uv_exit_cb exit_cb; /* Called after the process exits. */ + const char* file; /* Path to program to execute. */ + /* + * Command line arguments. args[0] should be the path to the program. On + * Windows this uses CreateProcess which concatenates the arguments into a + * string this can cause some strange errors. See the note at + * windows_verbatim_arguments. + */ + char** args; + /* + * This will be set as the environ variable in the subprocess. If this is + * NULL then the parents environ will be used. + */ + char** env; + /* + * If non-null this represents a directory the subprocess should execute + * in. Stands for current working directory. + */ + const char* cwd; + /* + * Various flags that control how uv_spawn() behaves. See the definition of + * `enum uv_process_flags` below. + */ + unsigned int flags; + /* + * The `stdio` field points to an array of uv_stdio_container_t structs that + * describe the file descriptors that will be made available to the child + * process. The convention is that stdio[0] points to stdin, fd 1 is used for + * stdout, and fd 2 is stderr. + * + * Note that on windows file descriptors greater than 2 are available to the + * child process only if the child processes uses the MSVCRT runtime. + */ + int stdio_count; + uv_stdio_container_t* stdio; + /* + * Libuv can change the child process' user/group id. This happens only when + * the appropriate bits are set in the flags fields. This is not supported on + * windows; uv_spawn() will fail and set the error to UV_ENOTSUP. + */ + uv_uid_t uid; + uv_gid_t gid; +} uv_process_options_t; + +/* + * These are the flags that can be used for the uv_process_options.flags field. + */ +enum uv_process_flags { + /* + * Set the child process' user id. The user id is supplied in the `uid` field + * of the options struct. This does not work on windows; setting this flag + * will cause uv_spawn() to fail. + */ + UV_PROCESS_SETUID = (1 << 0), + /* + * Set the child process' group id. The user id is supplied in the `gid` + * field of the options struct. This does not work on windows; setting this + * flag will cause uv_spawn() to fail. + */ + UV_PROCESS_SETGID = (1 << 1), + /* + * Do not wrap any arguments in quotes, or perform any other escaping, when + * converting the argument list into a command line string. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), + /* + * Spawn the child process in a detached state - this will make it a process + * group leader, and will effectively enable the child to keep running after + * the parent exits. Note that the child process will still keep the + * parent's event loop alive unless the parent process calls uv_unref() on + * the child's process handle. + */ + UV_PROCESS_DETACHED = (1 << 3), + /* + * Hide the subprocess window that would normally be created. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_HIDE = (1 << 4), + /* + * Hide the subprocess console window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5), + /* + * Hide the subprocess GUI window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6) +}; + +/* + * uv_process_t is a subclass of uv_handle_t. + */ +struct uv_process_s { + UV_HANDLE_FIELDS + uv_exit_cb exit_cb; + int pid; + UV_PROCESS_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_spawn(uv_loop_t* loop, + uv_process_t* handle, + const uv_process_options_t* options); +UV_EXTERN int uv_process_kill(uv_process_t*, int signum); +UV_EXTERN int uv_kill(int pid, int signum); +UV_EXTERN uv_pid_t uv_process_get_pid(const uv_process_t*); + + +/* + * uv_work_t is a subclass of uv_req_t. + */ +struct uv_work_s { + UV_REQ_FIELDS + uv_loop_t* loop; + uv_work_cb work_cb; + uv_after_work_cb after_work_cb; + UV_WORK_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_queue_work(uv_loop_t* loop, + uv_work_t* req, + uv_work_cb work_cb, + uv_after_work_cb after_work_cb); + +UV_EXTERN int uv_cancel(uv_req_t* req); + + +struct uv_cpu_times_s { + uint64_t user; /* milliseconds */ + uint64_t nice; /* milliseconds */ + uint64_t sys; /* milliseconds */ + uint64_t idle; /* milliseconds */ + uint64_t irq; /* milliseconds */ +}; + +struct uv_cpu_info_s { + char* model; + int speed; + struct uv_cpu_times_s cpu_times; +}; + +struct uv_interface_address_s { + char* name; + char phys_addr[6]; + int is_internal; + union { + struct sockaddr_in address4; + struct sockaddr_in6 address6; + } address; + union { + struct sockaddr_in netmask4; + struct sockaddr_in6 netmask6; + } netmask; +}; + +struct uv_passwd_s { + char* username; + unsigned long uid; + unsigned long gid; + char* shell; + char* homedir; +}; + +struct uv_utsname_s { + char sysname[256]; + char release[256]; + char version[256]; + char machine[256]; + /* This struct does not contain the nodename and domainname fields present in + the utsname type. domainname is a GNU extension. Both fields are referred + to as meaningless in the docs. */ +}; + +struct uv_statfs_s { + uint64_t f_type; + uint64_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + uint64_t f_spare[4]; +}; + +typedef enum { + UV_DIRENT_UNKNOWN, + UV_DIRENT_FILE, + UV_DIRENT_DIR, + UV_DIRENT_LINK, + UV_DIRENT_FIFO, + UV_DIRENT_SOCKET, + UV_DIRENT_CHAR, + UV_DIRENT_BLOCK +} uv_dirent_type_t; + +struct uv_dirent_s { + const char* name; + uv_dirent_type_t type; +}; + +UV_EXTERN char** uv_setup_args(int argc, char** argv); +UV_EXTERN int uv_get_process_title(char* buffer, size_t size); +UV_EXTERN int uv_set_process_title(const char* title); +UV_EXTERN int uv_resident_set_memory(size_t* rss); +UV_EXTERN int uv_uptime(double* uptime); +UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd); +UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd); + +typedef struct { + long tv_sec; + long tv_usec; +} uv_timeval_t; + +typedef struct { + int64_t tv_sec; + int32_t tv_usec; +} uv_timeval64_t; + +typedef struct { + uv_timeval_t ru_utime; /* user CPU time used */ + uv_timeval_t ru_stime; /* system CPU time used */ + uint64_t ru_maxrss; /* maximum resident set size */ + uint64_t ru_ixrss; /* integral shared memory size */ + uint64_t ru_idrss; /* integral unshared data size */ + uint64_t ru_isrss; /* integral unshared stack size */ + uint64_t ru_minflt; /* page reclaims (soft page faults) */ + uint64_t ru_majflt; /* page faults (hard page faults) */ + uint64_t ru_nswap; /* swaps */ + uint64_t ru_inblock; /* block input operations */ + uint64_t ru_oublock; /* block output operations */ + uint64_t ru_msgsnd; /* IPC messages sent */ + uint64_t ru_msgrcv; /* IPC messages received */ + uint64_t ru_nsignals; /* signals received */ + uint64_t ru_nvcsw; /* voluntary context switches */ + uint64_t ru_nivcsw; /* involuntary context switches */ +} uv_rusage_t; + +UV_EXTERN int uv_getrusage(uv_rusage_t* rusage); + +UV_EXTERN int uv_os_homedir(char* buffer, size_t* size); +UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size); +UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd); +UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd); +UV_EXTERN uv_pid_t uv_os_getpid(void); +UV_EXTERN uv_pid_t uv_os_getppid(void); + +#if defined(__PASE__) +/* On IBM i PASE, the highest process priority is -10 */ +# define UV_PRIORITY_LOW 39 /* RUNPTY(99) */ +# define UV_PRIORITY_BELOW_NORMAL 15 /* RUNPTY(50) */ +# define UV_PRIORITY_NORMAL 0 /* RUNPTY(20) */ +# define UV_PRIORITY_ABOVE_NORMAL -4 /* RUNTY(12) */ +# define UV_PRIORITY_HIGH -7 /* RUNPTY(6) */ +# define UV_PRIORITY_HIGHEST -10 /* RUNPTY(1) */ +#else +# define UV_PRIORITY_LOW 19 +# define UV_PRIORITY_BELOW_NORMAL 10 +# define UV_PRIORITY_NORMAL 0 +# define UV_PRIORITY_ABOVE_NORMAL -7 +# define UV_PRIORITY_HIGH -14 +# define UV_PRIORITY_HIGHEST -20 +#endif + +UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority); +UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority); + +UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count); +UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count); + +UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, + int* count); +UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count); + +struct uv_env_item_s { + char* name; + char* value; +}; + +UV_EXTERN int uv_os_environ(uv_env_item_t** envitems, int* count); +UV_EXTERN void uv_os_free_environ(uv_env_item_t* envitems, int count); +UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); +UV_EXTERN int uv_os_setenv(const char* name, const char* value); +UV_EXTERN int uv_os_unsetenv(const char* name); + +#ifdef MAXHOSTNAMELEN +# define UV_MAXHOSTNAMESIZE (MAXHOSTNAMELEN + 1) +#else + /* + Fallback for the maximum hostname size, including the null terminator. The + Windows gethostname() documentation states that 256 bytes will always be + large enough to hold the null-terminated hostname. + */ +# define UV_MAXHOSTNAMESIZE 256 +#endif + +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + +UV_EXTERN int uv_os_uname(uv_utsname_t* buffer); + + +typedef enum { + UV_FS_UNKNOWN = -1, + UV_FS_CUSTOM, + UV_FS_OPEN, + UV_FS_CLOSE, + UV_FS_READ, + UV_FS_WRITE, + UV_FS_SENDFILE, + UV_FS_STAT, + UV_FS_LSTAT, + UV_FS_FSTAT, + UV_FS_FTRUNCATE, + UV_FS_UTIME, + UV_FS_FUTIME, + UV_FS_ACCESS, + UV_FS_CHMOD, + UV_FS_FCHMOD, + UV_FS_FSYNC, + UV_FS_FDATASYNC, + UV_FS_UNLINK, + UV_FS_RMDIR, + UV_FS_MKDIR, + UV_FS_MKDTEMP, + UV_FS_RENAME, + UV_FS_SCANDIR, + UV_FS_LINK, + UV_FS_SYMLINK, + UV_FS_READLINK, + UV_FS_CHOWN, + UV_FS_FCHOWN, + UV_FS_REALPATH, + UV_FS_COPYFILE, + UV_FS_LCHOWN, + UV_FS_OPENDIR, + UV_FS_READDIR, + UV_FS_CLOSEDIR, + UV_FS_STATFS, + UV_FS_MKSTEMP, + UV_FS_LUTIME +} uv_fs_type; + +struct uv_dir_s { + uv_dirent_t* dirents; + size_t nentries; + void* reserved[4]; + UV_DIR_PRIVATE_FIELDS +}; + +/* uv_fs_t is a subclass of uv_req_t. */ +struct uv_fs_s { + UV_REQ_FIELDS + uv_fs_type fs_type; + uv_loop_t* loop; + uv_fs_cb cb; + ssize_t result; + void* ptr; + const char* path; + uv_stat_t statbuf; /* Stores the result of uv_fs_stat() and uv_fs_fstat(). */ + UV_FS_PRIVATE_FIELDS +}; + +UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*); +UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*); +UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*); +UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*); +UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*); + +UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req); +UV_EXTERN int uv_fs_close(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_open(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_read(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb); +UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_write(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb); +/* + * This flag can be used with uv_fs_copyfile() to return an error if the + * destination already exists. + */ +#define UV_FS_COPYFILE_EXCL 0x0001 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, a fallback copy mechanism is used. + */ +#define UV_FS_COPYFILE_FICLONE 0x0002 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, an error is returned. + */ +#define UV_FS_COPYFILE_FICLONE_FORCE 0x0004 + +UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkstemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb); +UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_scandir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req, + uv_dirent_t* ent); +UV_EXTERN int uv_fs_opendir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb); +UV_EXTERN int uv_fs_closedir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb); +UV_EXTERN int uv_fs_stat(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_rename(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int64_t offset, + uv_fs_cb cb); +UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, + uv_fs_t* req, + uv_file out_fd, + uv_file in_fd, + int64_t in_offset, + size_t length, + uv_fs_cb cb); +UV_EXTERN int uv_fs_access(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_utime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_futime(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_link(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb); + +/* + * This flag can be used with uv_fs_symlink() on Windows to specify whether + * path argument points to a directory. + */ +#define UV_FS_SYMLINK_DIR 0x0001 + +/* + * This flag can be used with uv_fs_symlink() on Windows to specify whether + * the symlink is to be created using junction points. + */ +#define UV_FS_SYMLINK_JUNCTION 0x0002 + +UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_realpath(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_chown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lchown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_statfs(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); + + +enum uv_fs_event { + UV_RENAME = 1, + UV_CHANGE = 2 +}; + + +struct uv_fs_event_s { + UV_HANDLE_FIELDS + /* private */ + char* path; + UV_FS_EVENT_PRIVATE_FIELDS +}; + + +/* + * uv_fs_stat() based polling file watcher. + */ +struct uv_fs_poll_s { + UV_HANDLE_FIELDS + /* Private, don't touch. */ + void* poll_ctx; +}; + +UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle); +UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle, + uv_fs_poll_cb poll_cb, + const char* path, + unsigned int interval); +UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle); +UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, + char* buffer, + size_t* size); + + +struct uv_signal_s { + UV_HANDLE_FIELDS + uv_signal_cb signal_cb; + int signum; + UV_SIGNAL_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); +UV_EXTERN int uv_signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); +UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); +UV_EXTERN int uv_signal_stop(uv_signal_t* handle); + +UV_EXTERN void uv_loadavg(double avg[3]); + + +/* + * Flags to be passed to uv_fs_event_start(). + */ +enum uv_fs_event_flags { + /* + * By default, if the fs event watcher is given a directory name, we will + * watch for all events in that directory. This flags overrides this behavior + * and makes fs_event report only changes to the directory entry itself. This + * flag does not affect individual files watched. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_WATCH_ENTRY = 1, + + /* + * By default uv_fs_event will try to use a kernel interface such as inotify + * or kqueue to detect events. This may not work on remote filesystems such + * as NFS mounts. This flag makes fs_event fall back to calling stat() on a + * regular interval. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_STAT = 2, + + /* + * By default, event watcher, when watching directory, is not registering + * (is ignoring) changes in it's subdirectories. + * This flag will override this behaviour on platforms that support it. + */ + UV_FS_EVENT_RECURSIVE = 4 +}; + + +UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags); +UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle, + char* buffer, + size_t* size); + +UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr); +UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); + +UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size); +UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size); + +UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); +UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); + + +struct uv_random_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* private */ + int status; + void* buf; + size_t buflen; + uv_random_cb cb; + struct uv__work work_req; +}; + +UV_EXTERN int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, /* For future extension; must be 0. */ + uv_random_cb cb); + +#if defined(IF_NAMESIZE) +# define UV_IF_NAMESIZE (IF_NAMESIZE + 1) +#elif defined(IFNAMSIZ) +# define UV_IF_NAMESIZE (IFNAMSIZ + 1) +#else +# define UV_IF_NAMESIZE (16 + 1) +#endif + +UV_EXTERN int uv_if_indextoname(unsigned int ifindex, + char* buffer, + size_t* size); +UV_EXTERN int uv_if_indextoiid(unsigned int ifindex, + char* buffer, + size_t* size); + +UV_EXTERN int uv_exepath(char* buffer, size_t* size); + +UV_EXTERN int uv_cwd(char* buffer, size_t* size); + +UV_EXTERN int uv_chdir(const char* dir); + +UV_EXTERN uint64_t uv_get_free_memory(void); +UV_EXTERN uint64_t uv_get_total_memory(void); +UV_EXTERN uint64_t uv_get_constrained_memory(void); + +UV_EXTERN uint64_t uv_hrtime(void); +UV_EXTERN void uv_sleep(unsigned int msec); + +UV_EXTERN void uv_disable_stdio_inheritance(void); + +UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib); +UV_EXTERN void uv_dlclose(uv_lib_t* lib); +UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr); +UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib); + +UV_EXTERN int uv_mutex_init(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_init_recursive(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle); + +UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock); + +UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value); +UV_EXTERN void uv_sem_destroy(uv_sem_t* sem); +UV_EXTERN void uv_sem_post(uv_sem_t* sem); +UV_EXTERN void uv_sem_wait(uv_sem_t* sem); +UV_EXTERN int uv_sem_trywait(uv_sem_t* sem); + +UV_EXTERN int uv_cond_init(uv_cond_t* cond); +UV_EXTERN void uv_cond_destroy(uv_cond_t* cond); +UV_EXTERN void uv_cond_signal(uv_cond_t* cond); +UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond); + +UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count); +UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier); +UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier); + +UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex); +UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, + uv_mutex_t* mutex, + uint64_t timeout); + +UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void)); + +UV_EXTERN int uv_key_create(uv_key_t* key); +UV_EXTERN void uv_key_delete(uv_key_t* key); +UV_EXTERN void* uv_key_get(uv_key_t* key); +UV_EXTERN void uv_key_set(uv_key_t* key, void* value); + +UV_EXTERN int uv_gettimeofday(uv_timeval64_t* tv); + +typedef void (*uv_thread_cb)(void* arg); + +UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg); + +typedef enum { + UV_THREAD_NO_FLAGS = 0x00, + UV_THREAD_HAS_STACK_SIZE = 0x01 +} uv_thread_create_flags; + +struct uv_thread_options_s { + unsigned int flags; + size_t stack_size; + /* More fields may be added at any time. */ +}; + +typedef struct uv_thread_options_s uv_thread_options_t; + +UV_EXTERN int uv_thread_create_ex(uv_thread_t* tid, + const uv_thread_options_t* params, + uv_thread_cb entry, + void* arg); +UV_EXTERN uv_thread_t uv_thread_self(void); +UV_EXTERN int uv_thread_join(uv_thread_t *tid); +UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2); + +/* The presence of these unions force similar struct layout. */ +#define XX(_, name) uv_ ## name ## _t name; +union uv_any_handle { + UV_HANDLE_TYPE_MAP(XX) +}; + +union uv_any_req { + UV_REQ_TYPE_MAP(XX) +}; +#undef XX + + +struct uv_loop_s { + /* User data - use this for whatever. */ + void* data; + /* Loop reference counting. */ + unsigned int active_handles; + void* handle_queue[2]; + union { + void* unused; + unsigned int count; + } active_reqs; + /* Internal storage for future extensions. */ + void* internal_fields; + /* Internal flag to signal loop stop. */ + unsigned int stop_flag; + UV_LOOP_PRIVATE_FIELDS +}; + +UV_EXTERN void* uv_loop_get_data(const uv_loop_t*); +UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data); + +/* Don't export the private CPP symbols. */ +#undef UV_HANDLE_TYPE_PRIVATE +#undef UV_REQ_TYPE_PRIVATE +#undef UV_REQ_PRIVATE_FIELDS +#undef UV_STREAM_PRIVATE_FIELDS +#undef UV_TCP_PRIVATE_FIELDS +#undef UV_PREPARE_PRIVATE_FIELDS +#undef UV_CHECK_PRIVATE_FIELDS +#undef UV_IDLE_PRIVATE_FIELDS +#undef UV_ASYNC_PRIVATE_FIELDS +#undef UV_TIMER_PRIVATE_FIELDS +#undef UV_GETADDRINFO_PRIVATE_FIELDS +#undef UV_GETNAMEINFO_PRIVATE_FIELDS +#undef UV_FS_REQ_PRIVATE_FIELDS +#undef UV_WORK_PRIVATE_FIELDS +#undef UV_FS_EVENT_PRIVATE_FIELDS +#undef UV_SIGNAL_PRIVATE_FIELDS +#undef UV_LOOP_PRIVATE_FIELDS +#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS +#undef UV__ERR + +#ifdef __cplusplus +} +#endif +#endif /* UV_H */ diff --git a/third_party/libuv/libuv.ndk.json b/third_party/libuv/libuv.ndk.json new file mode 100644 index 000000000..aeff061fe --- /dev/null +++ b/third_party/libuv/libuv.ndk.json @@ -0,0 +1,284 @@ +[ + {"name":"uv_version"}, + {"name":"uv_version_string"}, + {"name":"uv_replace_allocator"}, + {"name":"uv_default_loop"}, + {"name":"uv_loop_init"}, + {"name":"uv_loop_close"}, + {"name":"uv_loop_new"}, + {"name":"uv_loop_delete"}, + {"name":"uv_loop_size"}, + {"name":"uv_loop_alive"}, + {"name":"uv_loop_configure"}, + {"name":"uv_loop_fork"}, + {"name":"uv_run"}, + {"name":"uv_stop"}, + {"name":"uv_ref"}, + {"name":"uv_unref"}, + {"name":"uv_has_ref"}, + {"name":"uv_update_time"}, + {"name":"uv_now"}, + {"name":"uv_backend_fd"}, + {"name":"uv_backend_timeout"}, + {"name":"uv_translate_sys_error"}, + {"name":"uv_strerror"}, + {"name":"uv_strerror_r"}, + {"name":"uv_err_name"}, + {"name":"uv_err_name_r"}, + {"name":"uv_shutdown"}, + {"name":"uv_handle_size"}, + {"name":"uv_handle_get_type"}, + {"name":"uv_handle_type_name"}, + {"name":"uv_handle_get_data"}, + {"name":"uv_handle_get_loop"}, + {"name":"uv_handle_set_data"}, + {"name":"uv_req_size"}, + {"name":"uv_req_get_data"}, + {"name":"uv_req_set_data"}, + {"name":"uv_req_get_type"}, + {"name":"uv_req_type_name"}, + {"name":"uv_is_active"}, + {"name":"uv_walk"}, + {"name":"uv_print_all_handles"}, + {"name":"uv_print_active_handles"}, + {"name":"uv_close"}, + {"name":"uv_send_buffer_size"}, + {"name":"uv_recv_buffer_size"}, + {"name":"uv_fileno"}, + {"name":"uv_buf_init"}, + {"name":"uv_stream_get_write_queue_size"}, + {"name":"uv_listen"}, + {"name":"uv_accept"}, + {"name":"uv_read_start"}, + {"name":"uv_read_stop"}, + {"name":"uv_write"}, + {"name":"uv_write2"}, + {"name":"uv_try_write"}, + {"name":"uv_is_readable"}, + {"name":"uv_is_writable"}, + {"name":"uv_stream_set_blocking"}, + {"name":"uv_is_closing"}, + {"name":"uv_tcp_init"}, + {"name":"uv_tcp_init_ex"}, + {"name":"uv_tcp_open"}, + {"name":"uv_tcp_nodelay"}, + {"name":"uv_tcp_keepalive"}, + {"name":"uv_tcp_simultaneous_accepts"}, + {"name":"uv_tcp_bind"}, + {"name":"uv_tcp_getsockname"}, + {"name":"uv_tcp_getpeername"}, + {"name":"uv_tcp_close_reset"}, + {"name":"uv_tcp_connect"}, + {"name":"uv_udp_init"}, + {"name":"uv_udp_init_ex"}, + {"name":"uv_udp_open"}, + {"name":"uv_udp_bind"}, + {"name":"uv_udp_connect"}, + {"name":"uv_udp_getpeername"}, + {"name":"uv_udp_getsockname"}, + {"name":"uv_udp_set_membership"}, + {"name":"uv_udp_set_source_membership"}, + {"name":"uv_udp_set_multicast_loop"}, + {"name":"uv_udp_set_multicast_ttl"}, + {"name":"uv_udp_set_multicast_interface"}, + {"name":"uv_udp_set_broadcast"}, + {"name":"uv_udp_set_ttl"}, + {"name":"uv_udp_send"}, + {"name":"uv_udp_try_send"}, + {"name":"uv_udp_recv_start"}, + {"name":"uv_udp_recv_stop"}, + {"name":"uv_udp_get_send_queue_size"}, + {"name":"uv_udp_get_send_queue_count"}, + {"name":"uv_tty_init"}, + {"name":"uv_tty_set_mode"}, + {"name":"uv_tty_reset_mode"}, + {"name":"uv_tty_get_winsize"}, + {"name":"uv_tty_set_vterm_state"}, + {"name":"uv_tty_get_vterm_state"}, + {"name":"uv_guess_handle"}, + {"name":"uv_pipe_init"}, + {"name":"uv_pipe_open"}, + {"name":"uv_pipe_bind"}, + {"name":"uv_pipe_connect"}, + {"name":"uv_pipe_getsockname"}, + {"name":"uv_pipe_getpeername"}, + {"name":"uv_pipe_pending_instances"}, + {"name":"uv_pipe_pending_count"}, + {"name":"uv_pipe_pending_type"}, + {"name":"uv_pipe_chmod"}, + {"name":"uv_poll_init"}, + {"name":"uv_poll_init_socket"}, + {"name":"uv_poll_start"}, + {"name":"uv_poll_stop"}, + {"name":"uv_prepare_init"}, + {"name":"uv_prepare_start"}, + {"name":"uv_prepare_stop"}, + {"name":"uv_check_init"}, + {"name":"uv_check_start"}, + {"name":"uv_check_stop"}, + {"name":"uv_idle_init"}, + {"name":"uv_idle_start"}, + {"name":"uv_idle_stop"}, + {"name":"uv_async_init"}, + {"name":"uv_async_send"}, + {"name":"uv_timer_init"}, + {"name":"uv_timer_start"}, + {"name":"uv_timer_stop"}, + {"name":"uv_timer_again"}, + {"name":"uv_timer_set_repeat"}, + {"name":"uv_timer_get_repeat"}, + {"name":"uv_getaddrinfo"}, + {"name":"uv_freeaddrinfo"}, + {"name":"uv_getnameinfo"}, + {"name":"uv_spawn"}, + {"name":"uv_process_kill"}, + {"name":"uv_kill"}, + {"name":"uv_process_get_pid"}, + {"name":"uv_queue_work"}, + {"name":"uv_cancel"}, + {"name":"uv_setup_args"}, + {"name":"uv_get_process_title"}, + {"name":"uv_set_process_title"}, + {"name":"uv_resident_set_memory"}, + {"name":"uv_uptime"}, + {"name":"uv_get_osfhandle"}, + {"name":"uv_open_osfhandle"}, + {"name":"uv_getrusage"}, + {"name":"uv_os_homedir"}, + {"name":"uv_os_tmpdir"}, + {"name":"uv_os_get_passwd"}, + {"name":"uv_os_free_passwd"}, + {"name":"uv_os_getpid"}, + {"name":"uv_os_getppid"}, + {"name":"uv_os_getpriority"}, + {"name":"uv_os_setpriority"}, + {"name":"uv_cpu_info"}, + {"name":"uv_free_cpu_info"}, + {"name":"uv_interface_addresses"}, + {"name":"uv_free_interface_addresses"}, + {"name":"uv_os_environ"}, + {"name":"uv_os_free_environ"}, + {"name":"uv_os_getenv"}, + {"name":"uv_os_setenv"}, + {"name":"uv_os_unsetenv"}, + {"name":"uv_os_gethostname"}, + {"name":"uv_os_uname"}, + {"name":"uv_fs_get_type"}, + {"name":"uv_fs_get_result"}, + {"name":"uv_fs_get_ptr"}, + {"name":"uv_fs_get_path"}, + {"name":"uv_fs_get_statbuf"}, + {"name":"uv_fs_req_cleanup"}, + {"name":"uv_fs_close"}, + {"name":"uv_fs_open"}, + {"name":"uv_fs_read"}, + {"name":"uv_fs_unlink"}, + {"name":"uv_fs_write"}, + {"name":"uv_fs_copyfile"}, + {"name":"uv_fs_mkdir"}, + {"name":"uv_fs_mkdtemp"}, + {"name":"uv_fs_mkstemp"}, + {"name":"uv_fs_rmdir"}, + {"name":"uv_fs_scandir"}, + {"name":"uv_fs_scandir_next"}, + {"name":"uv_fs_opendir"}, + {"name":"uv_fs_readdir"}, + {"name":"uv_fs_closedir"}, + {"name":"uv_fs_stat"}, + {"name":"uv_fs_fstat"}, + {"name":"uv_fs_rename"}, + {"name":"uv_fs_fsync"}, + {"name":"uv_fs_fdatasync"}, + {"name":"uv_fs_ftruncate"}, + {"name":"uv_fs_sendfile"}, + {"name":"uv_fs_access"}, + {"name":"uv_fs_chmod"}, + {"name":"uv_fs_utime"}, + {"name":"uv_fs_futime"}, + {"name":"uv_fs_lstat"}, + {"name":"uv_fs_link"}, + {"name":"uv_fs_symlink"}, + {"name":"uv_fs_readlink"}, + {"name":"uv_fs_realpath"}, + {"name":"uv_fs_fchmod"}, + {"name":"uv_fs_chown"}, + {"name":"uv_fs_fchown"}, + {"name":"uv_fs_lchown"}, + {"name":"uv_fs_statfs"}, + {"name":"uv_fs_poll_init"}, + {"name":"uv_fs_poll_start"}, + {"name":"uv_fs_poll_stop"}, + {"name":"uv_fs_poll_getpath"}, + {"name":"uv_signal_init"}, + {"name":"uv_signal_start"}, + {"name":"uv_signal_start_oneshot"}, + {"name":"uv_signal_stop"}, + {"name":"uv_loadavg"}, + {"name":"uv_fs_event_init"}, + {"name":"uv_fs_event_start"}, + {"name":"uv_fs_event_stop"}, + {"name":"uv_fs_event_getpath"}, + {"name":"uv_ip4_addr"}, + {"name":"uv_ip6_addr"}, + {"name":"uv_ip4_name"}, + {"name":"uv_ip6_name"}, + {"name":"uv_inet_ntop"}, + {"name":"uv_inet_pton"}, + {"name":"uv_random"}, + {"name":"uv_if_indextoname"}, + {"name":"uv_if_indextoiid"}, + {"name":"uv_exepath"}, + {"name":"uv_cwd"}, + {"name":"uv_chdir"}, + {"name":"uv_get_free_memory"}, + {"name":"uv_get_total_memory"}, + {"name":"uv_get_constrained_memory"}, + {"name":"uv_hrtime"}, + {"name":"uv_sleep"}, + {"name":"uv_disable_stdio_inheritance"}, + {"name":"uv_dlopen"}, + {"name":"uv_dlclose"}, + {"name":"uv_dlsym"}, + {"name":"uv_dlerror"}, + {"name":"uv_mutex_init"}, + {"name":"uv_mutex_init_recursive"}, + {"name":"uv_mutex_destroy"}, + {"name":"uv_mutex_lock"}, + {"name":"uv_mutex_trylock"}, + {"name":"uv_mutex_unlock"}, + {"name":"uv_rwlock_init"}, + {"name":"uv_rwlock_destroy"}, + {"name":"uv_rwlock_rdlock"}, + {"name":"uv_rwlock_tryrdlock"}, + {"name":"uv_rwlock_rdunlock"}, + {"name":"uv_rwlock_wrlock"}, + {"name":"uv_rwlock_trywrlock"}, + {"name":"uv_rwlock_wrunlock"}, + {"name":"uv_sem_init"}, + {"name":"uv_sem_destroy"}, + {"name":"uv_sem_post"}, + {"name":"uv_sem_wait"}, + {"name":"uv_sem_trywait"}, + {"name":"uv_cond_init"}, + {"name":"uv_cond_destroy"}, + {"name":"uv_cond_signal"}, + {"name":"uv_cond_broadcast"}, + {"name":"uv_barrier_init"}, + {"name":"uv_barrier_destroy"}, + {"name":"uv_barrier_wait"}, + {"name":"uv_cond_wait"}, + {"name":"uv_cond_timedwait"}, + {"name":"uv_once"}, + {"name":"uv_key_create"}, + {"name":"uv_key_delete"}, + {"name":"uv_key_get"}, + {"name":"uv_key_set"}, + {"name":"uv_gettimeofday"}, + {"name":"uv_thread_create"}, + {"name":"uv_thread_create_ex"}, + {"name":"uv_thread_self"}, + {"name":"uv_thread_join"}, + {"name":"uv_thread_equal"}, + {"name":"uv_loop_get_data"}, + {"name":"uv_loop_set_data"} +] diff --git a/third_party/mindspore/BUILD.gn b/third_party/mindspore/BUILD.gn new file mode 100644 index 000000000..de586fbb6 --- /dev/null +++ b/third_party/mindspore/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright 2022 Huawei Technologies Co., Ltd +# +# 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. +# ============================================================================ + +import("//build/ohos.gni") + +ohos_ndk_headers("mindspore_header") { + dest_dir = "$ndk_headers_out_dir/mindspore" + sources = [ + "context.h", + "data_type.h", + "format.h", + "model.h", + "status.h", + "tensor.h", + "types.h", + ] +} + +ohos_ndk_library("mindspore_lib") { + output_name = "mindspore_lite_ndk" + output_extension = "so" + ndk_description_file = "./mindspore_lib.ndk.json" + system_capability = "SystemCapability.Ai.MindSpore" + min_compact_version = "9" +} diff --git a/third_party/mindspore/context.h b/third_party/mindspore/context.h new file mode 100644 index 000000000..0e5ff0231 --- /dev/null +++ b/third_party/mindspore/context.h @@ -0,0 +1,338 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_CONTEXT_C_H +#define MINDSPORE_INCLUDE_C_API_CONTEXT_C_H + +#include +#include +#include +#include "mindspore/types.h" +#include "mindspore/status.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *OH_AI_ContextHandle; +typedef void *OH_AI_DeviceInfoHandle; + +/** + * @brief Create a context object. + * @return Context object handle. + * @since 9 + */ +OH_AI_API OH_AI_ContextHandle OH_AI_ContextCreate(); + +/** + * @brief Destroy the context object. + * @param context Context object handle address. + * @since 9 + */ +OH_AI_API void OH_AI_ContextDestroy(OH_AI_ContextHandle *context); + +/** + * @brief Set the number of threads at runtime. + * @param context Context object handle. + * @param thread_num the number of threads at runtime. + * @since 9 + */ +OH_AI_API void OH_AI_ContextSetThreadNum(OH_AI_ContextHandle context, int32_t thread_num); + +/** + * @brief Obtain the current thread number setting. + * @param context Context object handle. + * @return The current thread number setting. + * @since 9 + */ +OH_AI_API int32_t OH_AI_ContextGetThreadNum(const OH_AI_ContextHandle context); + +/** + * @brief Set the thread affinity to CPU cores. + * @param context Context object handle. + * @param mode: 0: no affinities, 1: big cores first, 2: little cores first + * @since 9 + */ +OH_AI_API void OH_AI_ContextSetThreadAffinityMode(OH_AI_ContextHandle context, int mode); + +/** + * @brief Obtain the thread affinity of CPU cores. + * @param context Context object handle. + * @return Thread affinity to CPU cores. 0: no affinities, 1: big cores first, 2: little cores first + * @since 9 + */ +OH_AI_API int OH_AI_ContextGetThreadAffinityMode(const OH_AI_ContextHandle context); + +/** + * @brief Set the thread lists to CPU cores. + * + * If core_list and mode are set by OH_AI_ContextSetThreadAffinityMode at the same time, + * the core_list is effective, but the mode is not effective. \n + * + * @param context Context object handle. + * @param core_list: a array of thread core lists. + * @param core_num The number of core. + * @since 9 + */ +OH_AI_API void OH_AI_ContextSetThreadAffinityCoreList(OH_AI_ContextHandle context, const int32_t *core_list, + size_t core_num); + +/** + * @brief Obtain the thread lists of CPU cores. + * @param context Context object handle. + * @param core_num The number of core. + * @return a array of thread core lists. + * @since 9 + */ +OH_AI_API const int32_t *OH_AI_ContextGetThreadAffinityCoreList(const OH_AI_ContextHandle context, size_t *core_num); + +/** + * @brief Set the status whether to perform model inference or training in parallel. + * @param context Context object handle. + * @param is_parallel: true, parallel; false, not in parallel. + * @since 9 + */ +OH_AI_API void OH_AI_ContextSetEnableParallel(OH_AI_ContextHandle context, bool is_parallel); + +/** + * @brief Obtain the status whether to perform model inference or training in parallel. + * @param context Context object handle. + * @return Bool value that indicates whether in parallel. + * @since 9 + */ + OH_AI_API bool OH_AI_ContextGetEnableParallel(const OH_AI_ContextHandle context); + +/** + * @brief Add device info to context object. + * @param context Context object handle. + * @param device_info Device info object handle. + * @since 9 + */ +OH_AI_API void OH_AI_ContextAddDeviceInfo(OH_AI_ContextHandle context, OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Create a device info object. + * @param device_info Device info object handle. + * @return Device info object handle. + * @since 9 + */ +OH_AI_API OH_AI_DeviceInfoHandle OH_AI_DeviceInfoCreate(OH_AI_DeviceType device_type); + +/** + * @brief Destroy the device info object. + * @param device_info Device info object handle address. + * @since 9 + */ +OH_AI_API void OH_AI_DeviceInfoDestroy(OH_AI_DeviceInfoHandle *device_info); + +/** + * @brief Set provider's name. + * @param device_info Device info object handle. + * @param provider define the provider's name. + * @since 9 + */ +OH_AI_API void OH_AI_DeviceInfoSetProvider(OH_AI_DeviceInfoHandle device_info, const char *provider); + +/** + * @brief Obtain provider's name + * @param device_info Device info object handle. + * @return provider's name. + * @since 9 + */ +OH_AI_API const char *OH_AI_DeviceInfoGetProvider(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Set provider's device type. + * @param device_info Device info object handle. + * @param device define the provider's device type. EG: CPU. + * @since 9 + */ +OH_AI_API void OH_AI_DeviceInfoSetProviderDevice(OH_AI_DeviceInfoHandle device_info, const char *device); + +/** + * @brief Obtain provider's device type. + * @param device_info Device info object handle. + * @return provider's device type. + * @since 9 + */ +OH_AI_API const char *OH_AI_DeviceInfoGetProviderDevice(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Obtain the device type of the device info. + * @param device_info Device info object handle. + * @return Device Type of the device info. + * @since 9 + */ +OH_AI_API OH_AI_DeviceType OH_AI_DeviceInfoGetDeviceType(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Set enables to perform the float16 inference, Only valid for CPU/GPU. + * @param device_info Device info object handle. + * @param is_fp16 Enable float16 inference or not. + * @since 9 + */ +OH_AI_API void OH_AI_DeviceInfoSetEnableFP16(OH_AI_DeviceInfoHandle device_info, bool is_fp16); + +/** + * @brief Obtain enables to perform the float16 inference, Only valid for CPU/GPU. + * @param device_info Device info object handle. + * @return Whether enable float16 inference. + * @since 9 + */ +OH_AI_API bool OH_AI_DeviceInfoGetEnableFP16(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Set the NPU frequency, Only valid for NPU. + * @param device_info Device info object handle. + * @param frequency Can be set to 1 (low power consumption), 2 (balanced), 3 (high performance), 4 (extreme + * performance), default as 3. + * @since 9 + */ +OH_AI_API void OH_AI_DeviceInfoSetFrequency(OH_AI_DeviceInfoHandle device_info, int frequency); + +/** + * @brief Obtain the NPU frequency, Only valid for NPU. + * @param device_info Device info object handle. + * @return NPU frequency + * @since 9 + */ +OH_AI_API int OH_AI_DeviceInfoGetFrequency(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Obtain the all device descriptions in NNRT. + * @param num Number of NNRT device description. + * @return NNRT device description array. + * @since 10 + */ +OH_AI_API NNRTDeviceDesc *OH_AI_GetAllNNRTDeviceDescs(size_t *num); + +/** + * @brief Obtain the specified element in NNRt device description array. + * @param descs NNRT device description array. + * @param index Element index. + * @return NNRT device description. + * @since 10 + */ +OH_AI_API NNRTDeviceDesc *OH_AI_GetElementOfNNRTDeviceDescs(NNRTDeviceDesc *descs, size_t index); + +/** + * @brief Destroy the NNRT device descriptions returned by OH_AI_NNRTGetAllDeviceDescs(). + * @param desc NNRT device description array. + * @since 10 + */ +OH_AI_API void OH_AI_DestroyAllNNRTDeviceDescs(NNRTDeviceDesc **desc); + +/** + * @brief Obtain the device id in NNRT device description. + * @param desc pointer to the NNRT device description instance. + * @return NNRT device id. + * @since 10 + */ +OH_AI_API size_t OH_AI_GetDeviceIdFromNNRTDeviceDesc(const NNRTDeviceDesc *desc); + +/** + * @brief Obtain the device name in NNRT device description. + * @param desc pointer to the NNRT device description instance. + * @return NNRT device name. + * @since 10 + */ +OH_AI_API const char *OH_AI_GetNameFromNNRTDeviceDesc(const NNRTDeviceDesc *desc); + +/** + * @brief Obtain the device type in NNRT device description. + * @param desc pointer to the NNRT device description instance. + * @return NNRT device type. + * @since 10 + */ +OH_AI_API OH_AI_NNRTDeviceType OH_AI_GetTypeFromNNRTDeviceDesc(const NNRTDeviceDesc *desc); + +/** + * @brief Create the NNRT device info by exactly matching the specific device name. + * @param name NNRt device name. + * @return Device info object handle. + * @since 10 + */ +OH_AI_API OH_AI_DeviceInfoHandle OH_AI_CreateNNRTDeviceInfoByName(const char *name); + +/** + * @brief Create the NNRT device info by finding the first device with the specific device type. + * @param name NNRt device type. + * @return Device info object handle. + * @since 10 + */ +OH_AI_API OH_AI_DeviceInfoHandle OH_AI_CreateNNRTDeviceInfoByType(OH_AI_NNRTDeviceType type); + +/** + * @brief Set the NNRT device id, Only valid for NNRT. + * @param device_info Device info object handle. + * @param device_id NNRT device id. + * @since 10 + */ +OH_AI_API void OH_AI_DeviceInfoSetDeviceId(OH_AI_DeviceInfoHandle device_info, size_t device_id); + +/** + * @brief Obtain the NNRT device id, Only valid for NNRT. + * @param device_info Device info object handle. + * @return NNRT device id. + * @since 10 + */ +OH_AI_API size_t OH_AI_DeviceInfoGetDeviceId(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Set the NNRT performance mode, Only valid for NNRT. + * @param device_info Device info object handle. + * @param device_id NNRT performance mode. + * @since 10 + */ +OH_AI_API void OH_AI_DeviceInfoSetPerformanceMode(OH_AI_DeviceInfoHandle device_info, OH_AI_PerformanceMode mode); + +/** + * @brief Obtain the NNRT performance mode, Only valid for NNRT. + * @param device_info Device info object handle. + * @return NNRT performance mode. + * @since 10 + */ +OH_AI_API OH_AI_PerformanceMode OH_AI_DeviceInfoGetPerformanceMode(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Set the NNRT priority, Only valid for NNRT. + * @param device_info Device info object handle. + * @param device_id NNRT priority. + * @since 10 + */ +OH_AI_API void OH_AI_DeviceInfoSetPriority(OH_AI_DeviceInfoHandle device_info, OH_AI_Priority priority); + +/** + * @brief Obtain the NNRT priority, Only valid for NNRT. + * @param device_info Device info object handle. + * @return NNRT priority. + * @since 10 + */ +OH_AI_API OH_AI_Priority OH_AI_DeviceInfoGetPriority(const OH_AI_DeviceInfoHandle device_info); + +/** + * @brief Add extension of key/value format to device info, Only valid for NNRT. + * @param device_info Device info object handle. + * @param name The content of key as a C string. + * @param value The pointer to the value, which is a byte array. + * @param value_size The size of the value, which is a byte array. + * @return OH_AI_STATUS_SUCCESS if success, or detail error code if failed. + * @since 10 + */ +OH_AI_API OH_AI_Status OH_AI_DeviceInfoAddExtension(OH_AI_DeviceInfoHandle device_info, const char *name, const char *value, size_t value_size); +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_CONTEXT_C_H diff --git a/third_party/mindspore/data_type.h b/third_party/mindspore/data_type.h new file mode 100644 index 000000000..124ed17b3 --- /dev/null +++ b/third_party/mindspore/data_type.h @@ -0,0 +1,52 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_DATA_TYPE_C_H +#define MINDSPORE_INCLUDE_C_API_DATA_TYPE_C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum OH_AI_DataType { + OH_AI_DATATYPE_UNKNOWN = 0, + OH_AI_DATATYPE_OBJECTTYPE_STRING = 12, + OH_AI_DATATYPE_OBJECTTYPE_LIST = 13, + OH_AI_DATATYPE_OBJECTTYPE_TUPLE = 14, + OH_AI_DATATYPE_OBJECTTYPE_TENSOR = 17, + OH_AI_DATATYPE_NUMBERTYPE_BEGIN = 29, + OH_AI_DATATYPE_NUMBERTYPE_BOOL = 30, + OH_AI_DATATYPE_NUMBERTYPE_INT8 = 32, + OH_AI_DATATYPE_NUMBERTYPE_INT16 = 33, + OH_AI_DATATYPE_NUMBERTYPE_INT32 = 34, + OH_AI_DATATYPE_NUMBERTYPE_INT64 = 35, + OH_AI_DATATYPE_NUMBERTYPE_UINT8 = 37, + OH_AI_DATATYPE_NUMBERTYPE_UINT16 = 38, + OH_AI_DATATYPE_NUMBERTYPE_UINT32 = 39, + OH_AI_DATATYPE_NUMBERTYPE_UINT64 = 40, + OH_AI_DATATYPE_NUMBERTYPE_FLOAT16 = 42, + OH_AI_DATATYPE_NUMBERTYPE_FLOAT32 = 43, + OH_AI_DATATYPE_NUMBERTYPE_FLOAT64 = 44, + OH_AI_DATATYPE_NUMBERTYPE_END = 46, + // add new enum here + OH_AI_DataTypeInvalid = INT32_MAX, +} OH_AI_DataType; + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_DATA_TYPE_C_H diff --git a/third_party/mindspore/format.h b/third_party/mindspore/format.h new file mode 100644 index 000000000..36b355fe6 --- /dev/null +++ b/third_party/mindspore/format.h @@ -0,0 +1,46 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_FORMAT_C_H +#define MINDSPORE_INCLUDE_C_API_FORMAT_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum OH_AI_Format { + OH_AI_FORMAT_NCHW = 0, + OH_AI_FORMAT_NHWC = 1, + OH_AI_FORMAT_NHWC4 = 2, + OH_AI_FORMAT_HWKC = 3, + OH_AI_FORMAT_HWCK = 4, + OH_AI_FORMAT_KCHW = 5, + OH_AI_FORMAT_CKHW = 6, + OH_AI_FORMAT_KHWC = 7, + OH_AI_FORMAT_CHWK = 8, + OH_AI_FORMAT_HW = 9, + OH_AI_FORMAT_HW4 = 10, + OH_AI_FORMAT_NC = 11, + OH_AI_FORMAT_NC4 = 12, + OH_AI_FORMAT_NC4HW4 = 13, + OH_AI_FORMAT_NCDHW = 15, + OH_AI_FORMAT_NWC = 16, + OH_AI_FORMAT_NCW = 17 +} OH_AI_Format; + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_FORMAT_C_H diff --git a/third_party/mindspore/mindspore_lib.ndk.json b/third_party/mindspore/mindspore_lib.ndk.json new file mode 100644 index 000000000..c4c8193e9 --- /dev/null +++ b/third_party/mindspore/mindspore_lib.ndk.json @@ -0,0 +1,254 @@ +[ + { + "first_introduced": "9", + "name": "OH_AI_ContextCreate" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextDestroy" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextSetThreadNum" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextGetThreadNum" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextSetThreadAffinityMode" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextGetThreadAffinityMode" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextSetThreadAffinityCoreList" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextGetThreadAffinityCoreList" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextSetEnableParallel" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextGetEnableParallel" + }, + { + "first_introduced": "9", + "name": "OH_AI_ContextAddDeviceInfo" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoCreate" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoDestroy" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoSetProvider" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoGetProvider" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoSetProviderDevice" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoGetProviderDevice" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoGetDeviceType" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoSetEnableFP16" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoGetEnableFP16" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoSetFrequency" + }, + { + "first_introduced": "9", + "name": "OH_AI_DeviceInfoGetFrequency" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelCreate" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelDestroy" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelBuild" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelBuildFromFile" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelResize" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelPredict" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelGetInputs" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelGetOutputs" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelGetInputByTensorName" + }, + { + "first_introduced": "9", + "name": "OH_AI_ModelGetOutputByTensorName" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorCreate" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorDestroy" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorClone" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorSetName" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetName" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorSetDataType" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetDataType" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorSetShape" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetShape" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorSetFormat" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetFormat" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorSetData" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetData" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetMutableData" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetElementNum" + }, + { + "first_introduced": "9", + "name": "OH_AI_TensorGetDataSize" + }, + { + "first_introduced": "10", + "name": "OH_AI_GetAllNNRTDeviceDescs" + }, + { + "first_introduced": "10", + "name": "OH_AI_DestroyAllNNRTDeviceDescs" + }, + { + "first_introduced": "10", + "name": "OH_AI_GetDeviceIdFromNNRTDeviceDesc" + }, + { + "first_introduced": "10", + "name": "OH_AI_GetNameFromNNRTDeviceDesc" + }, + { + "first_introduced": "10", + "name": "OH_AI_GetTypeFromNNRTDeviceDesc" + }, + { + "first_introduced": "10", + "name": "OH_AI_CreateNNRTDeviceInfoByName" + }, + { + "first_introduced": "10", + "name": "OH_AI_CreateNNRTDeviceInfoByType" + }, + { + "first_introduced": "10", + "name": "OH_AI_DeviceInfoSetDeviceId" + }, + { + "first_introduced": "10", + "name": "OH_AI_DeviceInfoGetDeviceId" + }, + { + "first_introduced": "10", + "name": "OH_AI_DeviceInfoSetPerformanceMode" + }, + { + "first_introduced": "10", + "name": "OH_AI_DeviceInfoGetPerformanceMode" + }, + { + "first_introduced": "10", + "name": "OH_AI_DeviceInfoSetPriority" + }, + { + "first_introduced": "10", + "name": "OH_AI_GetElementOfNNRTDeviceDescs" + }, + { + "first_introduced": "10", + "name": "OH_AI_DeviceInfoAddExtension" + }, + { + "first_introduced": "10", + "name": "OH_AI_TensorSetUserData" + } +] diff --git a/third_party/mindspore/model.h b/third_party/mindspore/model.h new file mode 100644 index 000000000..870b9be3a --- /dev/null +++ b/third_party/mindspore/model.h @@ -0,0 +1,150 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_MODEL_C_H +#define MINDSPORE_INCLUDE_C_API_MODEL_C_H + +#include "mindspore/tensor.h" +#include "mindspore/context.h" +#include "mindspore/status.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *OH_AI_ModelHandle; + +typedef struct OH_AI_TensorHandleArray { + size_t handle_num; + OH_AI_TensorHandle *handle_list; +} OH_AI_TensorHandleArray; + +#define OH_AI_MAX_SHAPE_NUM 32 +typedef struct OH_AI_ShapeInfo { + size_t shape_num; + int64_t shape[OH_AI_MAX_SHAPE_NUM]; +} OH_AI_ShapeInfo; + +typedef struct OH_AI_CallBackParam { + char *node_name; + char *node_type; +} OH_AI_CallBackParam; + +typedef bool (*OH_AI_KernelCallBack)(const OH_AI_TensorHandleArray inputs, const OH_AI_TensorHandleArray outputs, + const OH_AI_CallBackParam kernel_Info); + +/** + * @brief Create a model object. + * @return Model object handle. + * @since 9 + */ +OH_AI_API OH_AI_ModelHandle OH_AI_ModelCreate(); + +/** + * @brief Destroy the model object. + * @param model Model object handle address. + * @since 9 + */ +OH_AI_API void OH_AI_ModelDestroy(OH_AI_ModelHandle *model); + +/** + * @brief Build the model from model file buffer so that it can run on a device. + * @param model Model object handle. + * @param model_data Define the buffer read from a model file. + * @param data_size Define bytes number of model file buffer. + * @param model_type Define The type of model file. + * @param model_context Define the context used to store options during execution. + * @return OH_AI_Status. + * @since 9 + */ +OH_AI_API OH_AI_Status OH_AI_ModelBuild(OH_AI_ModelHandle model, const void *model_data, size_t data_size, + OH_AI_ModelType model_type, const OH_AI_ContextHandle model_context); + +/** + * @brief Load and build the model from model path so that it can run on a device. + * @param model Model object handle. + * @param model_path Define the model file path. + * @param model_type Define The type of model file. + * @param model_context Define the context used to store options during execution. + * @return OH_AI_Status. + * @since 9 + */ +OH_AI_API OH_AI_Status OH_AI_ModelBuildFromFile(OH_AI_ModelHandle model, const char *model_path, + OH_AI_ModelType model_type, const OH_AI_ContextHandle model_context); + +/** + * @brief Resizes the shapes of inputs. + * @param model Model object handle. + * @param inputs The array that includes all input tensor handles. + * @param shape_infos Defines the new shapes of inputs, should be consistent with inputs. + * @param shape_info_num The num of shape_infos. + * @return OH_AI_Status. + * @since 9 + */ +OH_AI_API OH_AI_Status OH_AI_ModelResize(OH_AI_ModelHandle model, const OH_AI_TensorHandleArray inputs, + OH_AI_ShapeInfo *shape_infos, size_t shape_info_num); + +/** + * @brief Inference model. + * @param model Model object handle. + * @param inputs The array that includes all input tensor handles. + * @param outputs The array that includes all output tensor handles. + * @param before CallBack before predict. + * @param after CallBack after predict. + * @return OH_AI_Status. + * @since 9 + */ +OH_AI_API OH_AI_Status OH_AI_ModelPredict(OH_AI_ModelHandle model, const OH_AI_TensorHandleArray inputs, + OH_AI_TensorHandleArray *outputs, const OH_AI_KernelCallBack before, + const OH_AI_KernelCallBack after); + +/** + * @brief Obtains all input tensor handles of the model. + * @param model Model object handle. + * @return The array that includes all input tensor handles. + * @since 9 + */ +OH_AI_API OH_AI_TensorHandleArray OH_AI_ModelGetInputs(const OH_AI_ModelHandle model); + +/** + * @brief Obtains all output tensor handles of the model. + * @param model Model object handle. + * @return The array that includes all output tensor handles. + * @since 9 + */ +OH_AI_API OH_AI_TensorHandleArray OH_AI_ModelGetOutputs(const OH_AI_ModelHandle model); + +/** + * @brief Obtains the input tensor handle of the model by name. + * @param model Model object handle. + * @param tensor_name The name of tensor. + * @return The input tensor handle with the given name, if the name is not found, an NULL is returned. + * @since 9 + */ +OH_AI_API OH_AI_TensorHandle OH_AI_ModelGetInputByTensorName(const OH_AI_ModelHandle model, const char *tensor_name); + +/** + * @brief Obtains the output tensor handle of the model by name. + * @param model Model object handle. + * @param tensor_name The name of tensor. + * @return The output tensor handle with the given name, if the name is not found, an NULL is returned. + * @since 9 + */ +OH_AI_API OH_AI_TensorHandle OH_AI_ModelGetOutputByTensorName(const OH_AI_ModelHandle model, const char *tensor_name); + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_MODEL_C_H diff --git a/third_party/mindspore/status.h b/third_party/mindspore/status.h new file mode 100644 index 000000000..102c7962a --- /dev/null +++ b/third_party/mindspore/status.h @@ -0,0 +1,80 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_STATUS_C_H +#define MINDSPORE_INCLUDE_C_API_STATUS_C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum OH_AI_CompCode { + OH_AI_COMPCODE_CORE = 0x00000000u, + OH_AI_COMPCODE_MD = 0x10000000u, + OH_AI_COMPCODE_ME = 0x20000000u, + OH_AI_COMPCODE_MC = 0x30000000u, + OH_AI_COMPCODE_LITE = 0xF0000000u, +}; + +typedef enum OH_AI_Status { + OH_AI_STATUS_SUCCESS = 0, + // Core + OH_AI_STATUS_CORE_FAILED = OH_AI_COMPCODE_CORE | 0x1, + + // Lite // Common error code, range: [-1, -100) + OH_AI_STATUS_LITE_ERROR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -1), /**< Common error code. */ + OH_AI_STATUS_LITE_NULLPTR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -2), /**< NULL pointer returned.*/ + OH_AI_STATUS_LITE_PARAM_INVALID = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -3), /**< Invalid parameter.*/ + OH_AI_STATUS_LITE_NO_CHANGE = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -4), /**< No change. */ + OH_AI_STATUS_LITE_SUCCESS_EXIT = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -5), /**< No error but exit. */ + OH_AI_STATUS_LITE_MEMORY_FAILED = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -6), /**< Fail to create memory. */ + OH_AI_STATUS_LITE_NOT_SUPPORT = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -7), /**< Fail to support. */ + OH_AI_STATUS_LITE_THREADPOOL_ERROR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -8), /**< Error occur in thread pool. */ + OH_AI_STATUS_LITE_UNINITIALIZED_OBJ = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -9), /**< Object is not initialized. */ + + // Executor error code, range: [-100,-200) + OH_AI_STATUS_LITE_OUT_OF_TENSOR_RANGE = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -100), /**< Failed to check range. */ + OH_AI_STATUS_LITE_INPUT_TENSOR_ERROR = + OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -101), /**< Failed to check input tensor. */ + OH_AI_STATUS_LITE_REENTRANT_ERROR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -102), /**< Exist executor running. */ + + // Graph error code, range: [-200,-300) + OH_AI_STATUS_LITE_GRAPH_FILE_ERROR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -200), /**< Failed to verify graph file. */ + + // Node error code, range: [-300,-400) + OH_AI_STATUS_LITE_NOT_FIND_OP = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -300), /**< Failed to find operator. */ + OH_AI_STATUS_LITE_INVALID_OP_NAME = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -301), /**< Invalid operator name. */ + OH_AI_STATUS_LITE_INVALID_OP_ATTR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -302), /**< Invalid operator attr. */ + OH_AI_STATUS_LITE_OP_EXECUTE_FAILURE = + OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -303), /**< Failed to execution operator. */ + + // Tensor error code, range: [-400,-500) + OH_AI_STATUS_LITE_FORMAT_ERROR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -400), /**< Failed to checking tensor format. */ + + // InferShape error code, range: [-500,-600) + OH_AI_STATUS_LITE_INFER_ERROR = OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -500), /**< Failed to infer shape. */ + OH_AI_STATUS_LITE_INFER_INVALID = + OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -501), /**< Invalid infer shape before runtime. */ + + // User input param error code, range: [-600, 700) + OH_AI_STATUS_LITE_INPUT_PARAM_INVALID = + OH_AI_COMPCODE_LITE | (0x0FFFFFFF & -600), /**< Invalid input param by user. */ +} OH_AI_Status; +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_STATUS_C_H diff --git a/third_party/mindspore/tensor.h b/third_party/mindspore/tensor.h new file mode 100644 index 000000000..ab936299f --- /dev/null +++ b/third_party/mindspore/tensor.h @@ -0,0 +1,185 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_TENSOE_C_H +#define MINDSPORE_INCLUDE_C_API_TENSOE_C_H + +#include +#include "mindspore/status.h" +#include "mindspore/types.h" +#include "mindspore/data_type.h" +#include "mindspore/format.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *OH_AI_TensorHandle; + +/** + * @brief Create a tensor object. + * @param name The name of the tensor. + * @param type The data type of the tensor. + * @param shape The shape of the tensor. + * @param shape_num The num of the shape. + * @param data The data pointer that points to allocated memory. + * @param data_len The length of the memory, in bytes. + * @return Tensor object handle. + * @since 9 + */ +OH_AI_API OH_AI_TensorHandle OH_AI_TensorCreate(const char *name, OH_AI_DataType type, const int64_t *shape, + size_t shape_num, const void *data, size_t data_len); + +/** + * @brief Destroy the tensor object. + * @param tensor Tensor object handle address. + * @since 9 + */ +OH_AI_API void OH_AI_TensorDestroy(OH_AI_TensorHandle *tensor); + +/** + * @brief Obtain a deep copy of the tensor. + * @param tensor Tensor object handle. + * @return Tensor object handle. + * @since 9 + */ +OH_AI_API OH_AI_TensorHandle OH_AI_TensorClone(OH_AI_TensorHandle tensor); + +/** + * @brief Set the name for the tensor. + * @param tensor Tensor object handle. + * @param name The name of the tensor. + * @since 9 + */ +OH_AI_API void OH_AI_TensorSetName(OH_AI_TensorHandle tensor, const char *name); + +/** + * @brief Obtain the name of the tensor. + * @param tensor Tensor object handle. + * @return The name of the tensor. + * @since 9 + */ +OH_AI_API const char *OH_AI_TensorGetName(const OH_AI_TensorHandle tensor); + +/** + * @brief Set the data type for the tensor. + * @param tensor Tensor object handle. + * @param type The data type of the tensor. + * @since 9 + */ +OH_AI_API void OH_AI_TensorSetDataType(OH_AI_TensorHandle tensor, OH_AI_DataType type); + +/** + * @brief Obtain the data type of the tensor. + * @param tensor Tensor object handle. + * @return The date type of the tensor. + * @since 9 + */ +OH_AI_API OH_AI_DataType OH_AI_TensorGetDataType(const OH_AI_TensorHandle tensor); + +/** + * @brief Set the shape for the tensor. + * @param tensor Tensor object handle. + * @param shape The shape array. + * @param shape_num Dimension of shape. + * @since 9 + */ +OH_AI_API void OH_AI_TensorSetShape(OH_AI_TensorHandle tensor, const int64_t *shape, size_t shape_num); + +/** + * @brief Obtain the shape of the tensor. + * @param tensor Tensor object handle. + * @param shape_num Dimension of shape. + * @return The shape array of the tensor. + * @since 9 + */ +OH_AI_API const int64_t *OH_AI_TensorGetShape(const OH_AI_TensorHandle tensor, size_t *shape_num); + +/** + * @brief Set the format for the tensor. + * @param tensor Tensor object handle. + * @param format The format of the tensor. + * @since 9 + */ +OH_AI_API void OH_AI_TensorSetFormat(OH_AI_TensorHandle tensor, OH_AI_Format format); + +/** + * @brief Obtain the format of the tensor. + * @param tensor Tensor object handle. + * @return The format of the tensor. + * @since 9 + */ +OH_AI_API OH_AI_Format OH_AI_TensorGetFormat(const OH_AI_TensorHandle tensor); + +/** + * @brief Obtain the data for the tensor. + * @param tensor Tensor object handle. + * @param data A pointer to the data of the tensor. + * @since 9 + */ +OH_AI_API void OH_AI_TensorSetData(OH_AI_TensorHandle tensor, void *data); + +/** + * @brief Obtain the data pointer of the tensor. + * @param tensor Tensor object handle. + * @return The data pointer of the tensor. + * @since 9 + */ +OH_AI_API const void *OH_AI_TensorGetData(const OH_AI_TensorHandle tensor); + +/** + * @brief Obtain the mutable data pointer of the tensor. If the internal data is empty, it will allocate memory. + * @param tensor Tensor object handle. + * @return The data pointer of the tensor. + * @since 9 + */ +OH_AI_API void *OH_AI_TensorGetMutableData(const OH_AI_TensorHandle tensor); + +/** + * @brief Obtain the element number of the tensor. + * @param tensor Tensor object handle. + * @return The element number of the tensor. + * @since 9 + */ +OH_AI_API int64_t OH_AI_TensorGetElementNum(const OH_AI_TensorHandle tensor); + +/** + * @brief Obtain the data size fo the tensor. + * @param tensor Tensor object handle. + * @return The data size of the tensor. + * @since 9 + */ +OH_AI_API size_t OH_AI_TensorGetDataSize(const OH_AI_TensorHandle tensor); + +/** + * @brief Set the data for the tensor with user-allocated data buffer. + * + * The main purpose of this interface is providing a way of using memory already allocated by user as the Model's + * input, but not which allocated inside the Model object. It can reduce one copy. \n + * Note: The tensor won't free the data provided by invoker. Invoker has the responsibility to free it. And this + * free action should not be preformed before destruction of the tensor. \n + * + * @param tensor Tensor object handle. + * @param data A pointer to the user data buffer. + * @param data the byte size of the user data buffer. + * @return OH_AI_STATUS_SUCCESS if success, or detail error code if failed. + * @since 10 + */ +OH_AI_API OH_AI_Status OH_AI_TensorSetUserData(OH_AI_TensorHandle tensor, void *data, size_t data_size); + +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_TENSOE_C_H diff --git a/third_party/mindspore/types.h b/third_party/mindspore/types.h new file mode 100644 index 000000000..d38660b0d --- /dev/null +++ b/third_party/mindspore/types.h @@ -0,0 +1,86 @@ +/** + * Copyright 2021 Huawei Technologies Co., Ltd + * + * 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. + */ +#ifndef MINDSPORE_INCLUDE_C_API_TYPES_C_H +#define MINDSPORE_INCLUDE_C_API_TYPES_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef OH_AI_API +#ifdef _WIN32 +#define OH_AI_API __declspec(dllexport) +#else +#define OH_AI_API __attribute__((visibility("default"))) +#endif +#endif + +typedef enum OH_AI_ModelType { + OH_AI_MODELTYPE_MINDIR = 0, + // insert new data type here + OH_AI_MODELTYPE_INVALID = 0xFFFFFFFF +} OH_AI_ModelType; + +typedef enum OH_AI_DeviceType { + OH_AI_DEVICETYPE_CPU = 0, + OH_AI_DEVICETYPE_GPU, + OH_AI_DEVICETYPE_KIRIN_NPU, + // add new type here + // ohos-only device range: [60, 80) + OH_AI_DEVICETYPE_NNRT = 60, + OH_AI_DEVICETYPE_INVALID = 100, +} OH_AI_DeviceType; + +typedef enum OH_AI_NNRTDeviceType { + /** Devices that are not CPU, GPU, or dedicated accelerator */ + OH_AI_NNRTDEVICE_OTHERS = 0, + /** CPU device */ + OH_AI_NNRTDEVICE_CPU = 1, + /** GPU device */ + OH_AI_NNRTDEVICE_GPU = 2, + /** Dedicated hardware accelerator */ + OH_AI_NNRTDEVICE_ACCELERATOR = 3, +} OH_AI_NNRTDeviceType; + +typedef enum OH_AI_PerformanceMode { + /** No performance mode preference */ + OH_AI_PERFORMANCE_NONE = 0, + /** Low power consumption mode*/ + OH_AI_PERFORMANCE_LOW = 1, + /** Medium performance mode */ + OH_AI_PERFORMANCE_MEDIUM = 2, + /** High performance mode */ + OH_AI_PERFORMANCE_HIGH = 3, + /** Ultimate performance mode */ + OH_AI_PERFORMANCE_EXTREME = 4 +} OH_AI_PerformanceMode; + +typedef enum OH_AI_Priority { + /** No priority preference */ + OH_AI_PRIORITY_NONE = 0, + /** Low priority */ + OH_AI_PRIORITY_LOW = 1, + /** Medium priority */ + OH_AI_PRIORITY_MEDIUM = 2, + /** High priority */ + OH_AI_PRIORITY_HIGH = 3 +} OH_AI_Priority; + +typedef struct NNRTDeviceDesc NNRTDeviceDesc; +#ifdef __cplusplus +} +#endif +#endif // MINDSPORE_INCLUDE_C_API_TYPES_C_H diff --git a/third_party/node/BUILD.gn b/third_party/node/BUILD.gn new file mode 100644 index 000000000..254f38555 --- /dev/null +++ b/third_party/node/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_ndk_headers("node_header") { + dest_dir = "$ndk_headers_out_dir" + sources = [ + "//third_party/node/src/js_native_api.h", + "//third_party/node/src/js_native_api_types.h", + "//third_party/node/src/node_api.h", + "//third_party/node/src/node_api_types.h", + ] +} diff --git a/third_party/node/src/README.md b/third_party/node/src/README.md new file mode 100644 index 000000000..91b9f3817 --- /dev/null +++ b/third_party/node/src/README.md @@ -0,0 +1,1042 @@ +# Node.js C++ codebase + +Hi! 👋 You’ve found the C++ code backing Node.js. This README aims to help you +get started working on it and document some idioms you may encounter while +doing so. + +## Coding style + +Node.js has a document detailing its [C++ coding style][] +that can be helpful as a reference for stylistic issues. + +## V8 API documentation + +A lot of the Node.js codebase is around what the underlying JavaScript engine, +V8, provides through its API for embedders. Knowledge of this API can also be +useful when working with native addons for Node.js written in C++, although for +new projects [N-API][] is typically the better alternative. + +V8 does not provide much public API documentation beyond what is +available in its C++ header files, most importantly `v8.h`, which can be +accessed online in the following locations: + +* On GitHub: [`v8.h` in Node.js master][] +* On GitHub: [`v8.h` in V8 master][] +* On the Chromium project’s Code Search application: [`v8.h` in Code Search][] + +V8 also provides an [introduction for V8 embedders][], +which can be useful for understanding some of the concepts it uses in its +embedder API. + +Important concepts when using V8 are the ones of [`Isolate`][]s and +[JavaScript value handles][]. + +## libuv API documentation + +The other major dependency of Node.js is [libuv][], providing +the [event loop][] and other operation system abstractions to Node.js. + +There is a [reference documentation for the libuv API][]. + +## File structure + +The Node.js C++ files follow this structure: + +The `.h` header files contain declarations, and sometimes definitions that don’t +require including other headers (e.g. getters, setters, etc.). They should only +include other `.h` header files and nothing else. + +The `-inl.h` header files contain definitions of inline functions from the +corresponding `.h` header file (e.g. functions marked `inline` in the +declaration or `template` functions). They always include the corresponding +`.h` header file, and can include other `.h` and `-inl.h` header files as +needed. It is not mandatory to split out the definitions from the `.h` file +into an `-inl.h` file, but it becomes necessary when there are multiple +definitions and contents of other `-inl.h` files start being used. Therefore, it +is recommended to split a `-inl.h` file when inline functions become longer than +a few lines to keep the corresponding `.h` file readable and clean. All visible +definitions from the `-inl.h` file should be declared in the corresponding `.h` +header file. + +The `.cc` files contain definitions of non-inline functions from the +corresponding `.h` header file. They always include the corresponding `.h` +header file, and can include other `.h` and `-inl.h` header files as needed. + +## Helpful concepts + +A number of concepts are involved in putting together Node.js on top of V8 and +libuv. This section aims to explain some of them and how they work together. + + +### `Isolate` + +The `v8::Isolate` class represents a single JavaScript engine instance, in +particular a set of JavaScript objects that can refer to each other +(the “heap”). + +The `v8::Isolate` is often passed to other V8 API functions, and provides some +APIs for managing the behaviour of the JavaScript engine or querying about its +current state or statistics such as memory usage. + +V8 APIs are not thread-safe unless explicitly specified. In a typical Node.js +application, the main thread and any `Worker` threads each have one `Isolate`, +and JavaScript objects from one `Isolate` cannot refer to objects from +another `Isolate`. + +Garbage collection, as well as other operations that affect the entire heap, +happen on a per-`Isolate` basis. + +Typical ways of accessing the current `Isolate` in the Node.js code are: + +* Given a `FunctionCallbackInfo` for a [binding function][], + using `args.GetIsolate()`. +* Given a [`Context`][], using `context->GetIsolate()`. +* Given a [`Environment`][], using `env->isolate()`. + +### V8 JavaScript values + +V8 provides classes that mostly correspond to JavaScript types; for example, +`v8::Value` is a class representing any kind of JavaScript type, with +subclasses such as `v8::Number` (which in turn has subclasses like `v8::Int32`), +`v8::Boolean` or `v8::Object`. Most types are represented by subclasses +of `v8::Object`, e.g. `v8::Uint8Array` or `v8::Date`. + + +### Internal fields + +V8 provides the ability to store data in so-called “internal fields” inside +`v8::Object`s that were created as instances of C++-backed classes. The number +of fields needs to be defined when creating that class. + +Both JavaScript values and `void*` pointers may be stored in such fields. +In most native Node.js objects, the first internal field is used to store a +pointer to a [`BaseObject`][] subclass, which then contains all relevant +information associated with the JavaScript object. + +Typical ways of working with internal fields are: + +* `obj->InternalFieldCount()` to look up the number of internal fields for an + object (`0` for regular JavaScript objects). +* `obj->GetInternalField(i)` to get a JavaScript value from an internal field. +* `obj->SetInternalField(i, v)` to store a JavaScript value in an + internal field. +* `obj->GetAlignedPointerFromInternalField(i)` to get a `void*` pointer from an + internal field. +* `obj->SetAlignedPointerInInternalField(i, p)` to store a `void*` pointer in an + internal field. + +[`Context`][]s provide the same feature under the name “embedder data”. + + +### JavaScript value handles + +All JavaScript values are accessed through the V8 API through so-called handles, +of which there are two types: [`Local`][]s and [`Global`][]s. + + +#### `Local` handles + +A `v8::Local` handle is a temporary pointer to a JavaScript object, where +“temporary” usually means that is no longer needed after the current function +is done executing. `Local` handles can only be allocated on the C++ stack. + +Most of the V8 API uses `Local` handles to work with JavaScript values or return +them from functions. + +Whenever a `Local` handle is created, a `v8::HandleScope` or +`v8::EscapableHandleScope` object must exist on the stack. The `Local` is then +added to that scope and deleted along with it. + +When inside a [binding function][], a `HandleScope` already exists outside of +it, so there is no need to explicitly create one. + +`EscapableHandleScope`s can be used to allow a single `Local` handle to be +passed to the outer scope. This is useful when a function returns a `Local`. + +The following JavaScript and C++ functions are mostly equivalent: + +```js +function getFoo(obj) { + return obj.foo; +} +``` + +```cpp +v8::Local GetFoo(v8::Local context, + v8::Local obj) { + v8::Isolate* isolate = context->GetIsolate(); + v8::EscapableHandleScope handle_scope(isolate); + + // The 'foo_string' handle cannot be returned from this function because + // it is not “escaped” with `.Escape()`. + v8::Local foo_string = + v8::String::NewFromUtf8(isolate, "foo").ToLocalChecked(); + + v8::Local return_value; + if (obj->Get(context, foo_string).ToLocal(&return_value)) { + return handle_scope.Escape(return_value); + } else { + // There was a JS exception! Handle it somehow. + return v8::Local(); + } +} +``` + +See [exception handling][] for more information about the usage of `.To()`, +`.ToLocalChecked()`, `v8::Maybe` and `v8::MaybeLocal` usage. + +##### Casting local handles + +If it is known that a `Local` refers to a more specific type, it can +be cast to that type using `.As<...>()`: + +```cpp +v8::Local some_value; +// CHECK() is a Node.js utilitity that works similar to assert(). +CHECK(some_value->IsUint8Array()); +v8::Local as_uint8 = some_value.As(); +``` + +Generally, using `val.As()` is only valid if `val->IsX()` is true, and +failing to follow that rule may lead to crashes. + +##### Detecting handle leaks + +If it is expected that no `Local` handles should be created within a given +scope unless explicitly within a `HandleScope`, a `SealHandleScope` can be used. + +For example, there is a `SealHandleScope` around the event loop, forcing +any functions that are called from the event loop and want to run or access +JavaScript code to create `HandleScope`s. + + +#### `Global` handles + +A `v8::Global` handle (sometimes also referred to by the name of its parent +class `Persistent`, although use of that is discouraged in Node.js) is a +reference to a JavaScript object that can remain active as long as the engine +instance is active. + +Global handles can be either strong or weak. Strong global handles are so-called +“GC roots”, meaning that they will keep the JavaScript object they refer to +alive even if no other objects refer to them. Weak global handles do not do +that, and instead optionally call a callback when the object they refer to +is garbage-collected. + +```cpp +v8::Global reference; + +void StoreReference(v8::Isolate* isolate, v8::Local obj) { + // Create a strong reference to `obj`. + reference.Reset(isolate, obj); +} + +// Must be called with a HandleScope around it. +v8::Local LoadReference(v8::Isolate* isolate) { + return reference.Get(isolate); +} +``` + +##### `Eternal` handles + +`v8::Eternal` handles are a special kind of handles similar to `v8::Global` +handles, with the exception that the values they point to are never +garbage-collected while the JavaScript Engine instance is alive, even if +the `v8::Eternal` itself is destroyed at some point. This type of handle +is rarely used. + + +### `Context` + +JavaScript allows multiple global objects and sets of built-in JavaScript +objects (like the `Object` or `Array` functions) to coexist inside the same +heap. Node.js exposes this ability through the [`vm` module][]. + +V8 refers to each of these global objects and their associated builtins as a +`Context`. + +Currently, in Node.js there is one main `Context` associated with an +[`Environment`][] instance, and most Node.js features will only work inside +that context. (The only exception at the time of writing are +[`MessagePort`][] objects.) This restriction is not inherent to the design of +Node.js, and a sufficiently committed person could restructure Node.js to +provide built-in modules inside of `vm.Context`s. + +Often, the `Context` is passed around for [exception handling][]. +Typical ways of accessing the current `Context` in the Node.js code are: + +* Given an [`Isolate`][], using `isolate->GetCurrentContext()`. +* Given an [`Environment`][], using `env->context()` to get the `Environment`’s + main context. + + +### Event loop + +The main abstraction for an event loop inside Node.js is the `uv_loop_t` struct. +Typically, there is one event loop per thread. This includes not only the main +thread and Workers, but also helper threads that may occasionally be spawned +in the course of running a Node.js program. + +The current event loop can be accessed using `env->event_loop()` given an +[`Environment`][] instance. The restriction of using a single event loop +is not inherent to the design of Node.js, and a sufficiently committed person +could restructure Node.js to provide e.g. the ability to run parts of Node.js +inside an event loop separate from the active thread’s event loop. + + +### `Environment` + +Node.js instances are represented by the `Environment` class. + +Currently, every `Environment` class is associated with: + +* One [event loop][] +* One [`Isolate`][] +* One main [`Context`][] + +The `Environment` class contains a large number of different fields for +different Node.js modules, for example a libuv timer for `setTimeout()` or +the memory for a `Float64Array` that the `fs` module uses for storing data +returned from a `fs.stat()` call. + +It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][] +instances. + +Typical ways of accessing the current `Environment` in the Node.js code are: + +* Given a `FunctionCallbackInfo` for a [binding function][], + using `Environment::GetCurrent(args)`. +* Given a [`BaseObject`][], using `env()` or `self->env()`. +* Given a [`Context`][], using `Environment::GetCurrent(context)`. + This requires that `context` has been associated with the `Environment` + instance, e.g. is the main `Context` for the `Environment` or one of its + `vm.Context`s. +* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks + up the current [`Context`][] and then uses that. + + +### `IsolateData` + +Every Node.js instance ([`Environment`][]) is associated with one `IsolateData` +instance that contains information about or associated with a given +[`Isolate`][]. + +#### String table + +`IsolateData` contains a list of strings that can be quickly accessed +inside Node.js code, e.g. given an `Environment` instance `env` the JavaScript +string “name” can be accessed through `env->name_string()` without actually +creating a new JavaScript string. + +### Platform + +Every process that uses V8 has a `v8::Platform` instance that provides some +functionalities to V8, most importantly the ability to schedule work on +background threads. + +Node.js provides a `NodePlatform` class that implements the `v8::Platform` +interface and uses libuv for providing background threading abilities. + +The platform can be accessed through `isolate_data->platform()` given an +[`IsolateData`][] instance, although that only works when: + +* The current Node.js instance was not started by an embedder; or +* The current Node.js instance was started by an embedder whose `v8::Platform` + implementation also implement’s the `node::MultiIsolatePlatform` interface + and who passed this to Node.js. + + +### Binding functions + +C++ functions exposed to JS follow a specific signature. The following example +is from `node_util.cc`: + +```cpp +void ArrayBufferViewHasBuffer(const FunctionCallbackInfo& args) { + CHECK(args[0]->IsArrayBufferView()); + args.GetReturnValue().Set(args[0].As()->HasBuffer()); +} +``` + +(Namespaces are usually omitted through the use of `using` statements in the +Node.js source code.) + +`args[n]` is a `Local` that represents the n-th argument passed to the +function. `args.This()` is the `this` value inside this function call. +`args.Holder()` is equivalent to `args.This()` in all use cases inside of +Node.js. + +`args.GetReturnValue()` is a placeholder for the return value of the function, +and provides a `.Set()` method that can be called with a boolean, integer, +floating-point number or a `Local` to set the return value. + +Node.js provides various helpers for building JS classes in C++ and/or attaching +C++ functions to the exports of a built-in module: + +```cpp +void Initialize(Local target, + Local unused, + Local context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + + env->SetMethod(target, "getaddrinfo", GetAddrInfo); + env->SetMethod(target, "getnameinfo", GetNameInfo); + + // 'SetMethodNoSideEffect' means that debuggers can safely execute this + // function for e.g. previews. + env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP); + + // ... more code ... + + // Building the `ChannelWrap` class for JS: + Local channel_wrap = + env->NewFunctionTemplate(ChannelWrap::New); + // Allow for 1 internal field, see `BaseObject` for details on this: + channel_wrap->InstanceTemplate()->SetInternalFieldCount(1); + channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env)); + + // Set various methods on the class (i.e. on the prototype): + env->SetProtoMethod(channel_wrap, "queryAny", Query); + env->SetProtoMethod(channel_wrap, "queryA", Query); + // ... + env->SetProtoMethod(channel_wrap, "querySoa", Query); + env->SetProtoMethod(channel_wrap, "getHostByAddr", Query); + + env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers); + + env->SetConstructorFunction(target, "ChannelWrap", channel_wrap); +} + +// Run the `Initialize` function when loading this module through +// `internalBinding('cares_wrap')` in Node.js’s built-in JavaScript code: +NODE_MODULE_CONTEXT_AWARE_INTERNAL(cares_wrap, Initialize) +``` + +If the C++ binding is loaded during bootstrap, it needs to be registered +with the utilities in `node_external_reference.h`, like this: + +```cpp +namespace node { +namespace utils { +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(GetHiddenValue); + registry->Register(SetHiddenValue); + // ... register all C++ functions used to create FunctionTemplates. +} +} // namespace util +} // namespace node + +// The first argument passed to `NODE_MODULE_EXTERNAL_REFERENCE`, +// which is `util` here, needs to be added to the +// `EXTERNAL_REFERENCE_BINDING_LIST_BASE` list in node_external_reference.h +NODE_MODULE_EXTERNAL_REFERENCE(util, node::util::RegisterExternalReferences) +``` + +Otherwise, you might see an error message like this when building the +executables: + +```console +FAILED: gen/node_snapshot.cc +cd ../../; out/Release/node_mksnapshot out/Release/gen/node_snapshot.cc +Unknown external reference 0x107769200. + +/bin/sh: line 1: 6963 Illegal instruction: 4 out/Release/node_mksnapshot out/Release/gen/node_snapshot.cc +``` + +You can try using a debugger to symbolicate the external reference. For example, +with lldb's `image lookup --address` command (with gdb it's `info symbol`): + +```console +$ lldb -- out/Release/node_mksnapshot out/Release/gen/node_snapshot.cc +(lldb) run +Process 7012 launched: '/Users/joyee/projects/node/out/Release/node_mksnapshot' (x86_64) +Unknown external reference 0x1004c8200. + +Process 7012 stopped +(lldb) image lookup --address 0x1004c8200 + Address: node_mksnapshot[0x00000001004c8200] (node_mksnapshot.__TEXT.__text + 5009920) + Summary: node_mksnapshot`node::util::GetHiddenValue(v8::FunctionCallbackInfo const&) at node_util.cc:159 +``` + +Which explains that the unregistered external reference is +`node::util::GetHiddenValue` defined in `node_util.cc`. + + +#### Per-binding state + +Some internal bindings, such as the HTTP parser, maintain internal state that +only affects that particular binding. In that case, one common way to store +that state is through the use of `Environment::AddBindingData`, which gives +binding functions access to an object for storing such state. +That object is always a [`BaseObject`][]. + +Its class needs to have a static `type_name` field based on a +constant string, in order to disambiguate it from other classes of this type, +and which could e.g. match the binding’s name (in the example above, that would +be `cares_wrap`). + +```cpp +// In the HTTP parser source code file: +class BindingData : public BaseObject { + public: + BindingData(Environment* env, Local obj) : BaseObject(env, obj) {} + + static constexpr FastStringKey type_name { "http_parser" }; + + std::vector parser_buffer; + bool parser_buffer_in_use = false; + + // ... +}; + +// Available for binding functions, e.g. the HTTP Parser constructor: +static void New(const FunctionCallbackInfo& args) { + BindingData* binding_data = Environment::GetBindingData(args); + new Parser(binding_data, args.This()); +} + +// ... because the initialization function told the Environment to store the +// BindingData object: +void InitializeHttpParser(Local target, + Local unused, + Local context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + BindingData* const binding_data = + env->AddBindingData(context, target); + if (binding_data == nullptr) return; + + Local t = env->NewFunctionTemplate(Parser::New); + ... +} +``` + +If the binding is loaded during bootstrap, add it to the +`SERIALIZABLE_OBJECT_TYPES` list in `src/node_snapshotable.h` and +inherit from the `SnapshotableObject` class instead. See the comments +of `SnapshotableObject` on how to implement its serialization and +deserialization. + + +### Exception handling + +The V8 engine provides multiple features to work with JavaScript exceptions, +as C++ exceptions are disabled inside of Node.js: + +#### Maybe types + +V8 provides the `v8::Maybe` and `v8::MaybeLocal` types, typically used +as return values from API functions that can run JavaScript code and therefore +can throw exceptions. + +Conceptually, the idea is that every `v8::Maybe` is either empty (checked +through `.IsNothing()`) or holds a value of type `T` (checked through +`.IsJust()`). If the `Maybe` is empty, then a JavaScript exception is pending. +A typical way of accessing the value is using the `.To()` function, which +returns a boolean indicating success of the operation (i.e. the `Maybe` not +being empty) and taking a pointer to a `T` to store the value if there is one. + +##### Checked conversion + +`maybe.Check()` can be used to assert that the maybe is not empty, i.e. crash +the process otherwise. `maybe.FromJust()` (aka `maybe.ToChecked()`) can be used +to access the value and crash the process if it is not set. + +This should only be performed if it is actually sure that the operation has +not failed. A lot of Node.js’s source code does **not** follow this rule, and +can be brought to crash through this. + +In particular, it is often not safe to assume that an operation does not throw +an exception, even if it seems like it would not do that. +The most common reasons for this are: + +* Calls to functions like `object->Get(...)` or `object->Set(...)` may fail on + most objects, if the `Object.prototype` object has been modified from userland + code that added getters or setters. +* Calls that invoke *any* JavaScript code, including JavaScript code that is + provided from Node.js internals or V8 internals, will fail when JavaScript + execution is being terminated. This typically happens inside Workers when + `worker.terminate()` is called, but it can also affect the main thread when + e.g. Node.js is used as an embedded library. These exceptions can happen at + any point. + It is not always obvious whether a V8 call will enter JavaScript. In addition + to unexpected getters and setters, accessing some types of built-in objects + like `Map`s and `Set`s can also run V8-internal JavaScript code. + +##### MaybeLocal + +`v8::MaybeLocal` is a variant of `v8::Maybe` that is either empty or +holds a value of type `Local`. It has methods that perform the same +operations as the methods of `v8::Maybe`, but with different names: + +| `Maybe` | `MaybeLocal` | +| -------------------- | ------------------------------ | +| `maybe.IsNothing()` | `maybe_local.IsEmpty()` | +| `maybe.IsJust()` | `!maybe_local.IsEmpty()` | +| `maybe.To(&value)` | `maybe_local.ToLocal(&local)` | +| `maybe.ToChecked()` | `maybe_local.ToLocalChecked()` | +| `maybe.FromJust()` | `maybe_local.ToLocalChecked()` | +| `maybe.Check()` | – | +| `v8::Nothing()` | `v8::MaybeLocal()` | +| `v8::Just(value)` | `v8::MaybeLocal(value)` | + +##### Handling empty `Maybe`s + +Usually, the best approach to encountering an empty `Maybe` is to just return +from the current function as soon as possible, and let execution in JavaScript +land resume. If the empty `Maybe` is encountered inside a nested function, +is may be a good idea to use a `Maybe` or `MaybeLocal` for the return type +of that function and pass information about pending JavaScript exceptions along +that way. + +Generally, when an empty `Maybe` is encountered, it is not valid to attempt +to perform further calls to APIs that return `Maybe`s. + +A typical pattern for dealing with APIs that return `Maybe` and `MaybeLocal` is +using `.ToLocal()` and `.To()` and returning early in case there is an error: + +```cpp +// This could also return a v8::MaybeLocal, for example. +v8::Maybe SumNumbers(v8::Local context, + v8::Local array_of_integers) { + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + double sum = 0; + + for (uint32_t i = 0; i < array_of_integers->Length(); i++) { + v8::Local entry; + if (array_of_integers->Get(context, i).ToLocal(&entry)) { + // Oops, we might have hit a getter that throws an exception! + // It’s better to not continue return an empty (“nothing”) Maybe. + return v8::Nothing(); + } + + if (!entry->IsNumber()) { + // Let’s just skip any non-numbers. It would also be reasonable to throw + // an exception here, e.g. using the error system in src/node_errors.h, + // and then to return an empty Maybe again. + continue; + } + + // This cast is valid, because we’ve made sure it’s really a number. + v8::Local entry_as_number = entry.As(); + + sum += entry_as_number->Value(); + } + + return v8::Just(sum); +} + +// Function that is exposed to JS: +void SumNumbers(const v8::FunctionCallbackInfo& args) { + // This will crash if the first argument is not an array. Let’s assume we + // have performed type checking in a JavaScript wrapper function. + CHECK(args[0]->IsArray()); + + double sum; + if (!SumNumbers(args.GetIsolate()->GetCurrentContext(), + args[0].As()).To(&sum)) { + // Nothing to do, we can just return directly to JavaScript. + return; + } + + args.GetReturnValue().Set(sum); +} +``` + +#### TryCatch + +If there is a need to catch JavaScript exceptions in C++, V8 provides the +`v8::TryCatch` type for doing so, which we wrap into our own +`node::errors::TryCatchScope` in Node.js. The latter has the additional feature +of providing the ability to shut down the program in the typical Node.js way +(printing the exception + stack trace) if an exception is caught. + +A `TryCatch` will catch regular JavaScript exceptions, as well as termination +exceptions such as the ones thrown by `worker.terminate()` calls. +In the latter case, the `try_catch.HasTerminated()` function will return `true`, +and the exception object will not be a meaningful JavaScript value. +`try_catch.ReThrow()` should not be used in this case. + + +### libuv handles and requests + +Two central concepts when working with libuv are handles and requests. + +Handles are subclasses of the `uv_handle_t` “class”, and generally refer to +long-lived objects that can emit events multiple times, such as network sockets +or file system watchers. + +In Node.js, handles are often managed through a [`HandleWrap`][] subclass. + +Requests are one-time asynchronous function calls on the event loop, such as +file system requests or network write operations, that either succeed or fail. + +In Node.js, requests are often managed through a [`ReqWrap`][] subclass. + +### Environment cleanup + +When a Node.js [`Environment`][] is destroyed, it generally needs to clean up +any resources owned by it, e.g. memory or libuv requests/handles. + + +#### Cleanup hooks + +Cleanup hooks are provided that run before the [`Environment`][] +is destroyed. They can be added and removed through by using +`env->AddCleanupHook(callback, hint);` and +`env->RemoveCleanupHook(callback, hint);`, where callback takes a `void* hint` +argument. + +Inside these cleanup hooks, new asynchronous operations *may* be started on the +event loop, although ideally that is avoided as much as possible. + +Every [`BaseObject`][] has its own cleanup hook that deletes it. For +[`ReqWrap`][] and [`HandleWrap`][] instances, cleanup of the associated libuv +objects is performed automatically, i.e. handles are closed and requests +are cancelled if possible. + +#### Closing libuv handles + +If a libuv handle is not managed through a [`HandleWrap`][] instance, +it needs to be closed explicitly. Do not use `uv_close()` for that, but rather +`env->CloseHandle()`, which works the same way but keeps track of the number +of handles that are still closing. + +#### Closing libuv requests + +There is no way to abort libuv requests in general. If a libuv request is not +managed through a [`ReqWrap`][] instance, the +`env->IncreaseWaitingRequestCounter()` and +`env->DecreaseWaitingRequestCounter()` functions need to be used to keep track +of the number of active libuv requests. + +#### Calling into JavaScript + +Calling into JavaScript is not allowed during cleanup. Worker threads explicitly +forbid this during their shutdown sequence, but the main thread does not for +backwards compatibility reasons. + +When calling into JavaScript without using [`MakeCallback()`][], check the +`env->can_call_into_js()` flag and do not proceed if it is set to `false`. + +## Classes associated with JavaScript objects + +### `MemoryRetainer` + +A large number of classes in the Node.js C++ codebase refer to other objects. +The `MemoryRetainer` class is a helper for annotating C++ classes with +information that can be used by the heap snapshot builder in V8, so that +memory retained by C++ can be tracked in V8 heap snapshots captured in +Node.js applications. + +Inheriting from the `MemoryRetainer` class enables objects (both from JavaScript +and C++) to refer to instances of that class, and in turn enables that class +to point to other objects as well, including native C++ types +such as `std::string` and track their memory usage. + +This can be useful for debugging memory leaks. + +The [`memory_tracker.h`][] header file explains how to use this class. + + +### `BaseObject` + +A frequently recurring situation is that a JavaScript object and a C++ object +need to be tied together. `BaseObject` is the main abstraction for that in +Node.js, and most classes that are associated with JavaScript objects are +subclasses of it. It is defined in [`base_object.h`][]. + +Every `BaseObject` is associated with one [`Environment`][] and one +`v8::Object`. The `v8::Object` needs to have at least one [internal field][] +that is used for storing the pointer to the C++ object. In order to ensure this, +the V8 `SetInternalFieldCount()` function is usually used when setting up the +class from C++. + +The JavaScript object can be accessed as a `v8::Local` by using +`self->object()`, given a `BaseObject` named `self`. + +Accessing a `BaseObject` from a `v8::Local` (frequently that is +`args.This()` or `args.Holder()` in a [binding function][]) can be done using +the `Unwrap(obj)` function, where `T` is a subclass of `BaseObject`. +A helper for this is the `ASSIGN_OR_RETURN_UNWRAP` macro that returns from the +current function if unwrapping fails (typically that means that the `BaseObject` +has been deleted earlier). + +```cpp +void Http2Session::Request(const FunctionCallbackInfo& args) { + Http2Session* session; + ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder()); + Environment* env = session->env(); + Local context = env->context(); + Isolate* isolate = env->isolate(); + + // ... + // The actual function body, which can now use the `session` object. + // ... +} +``` + +#### Lifetime management + +The `BaseObject` class comes with a set of features that allow managing the +lifetime of its instances, either associating it with the lifetime of the +corresponding JavaScript object or untying the two. + +The `BaseObject::MakeWeak()` method turns the underlying [`Global`][] handle +into a weak one, and makes it so that the `BaseObject::OnGCCollect()` virtual +method is called when the JavaScript object is garbage collected. By default, +that methods deletes the `BaseObject` instance. + +`BaseObject::ClearWeak()` undoes this effect. + +It generally makes sense to call `MakeWeak()` in the constructor of a +`BaseObject` subclass, unless that subclass is referred to by e.g. the event +loop, as is the case for the [`HandleWrap`][] and [`ReqWrap`][] classes. + +In addition, there are two kinds of smart pointers that can be used to refer +to `BaseObject`s. + +`BaseObjectWeakPtr` is similar to `std::weak_ptr`, but holds on to +an object of a `BaseObject` subclass `T` and integrates with the lifetime +management of the former. When the `BaseObject` no longer exists, e.g. when +it was garbage collected, accessing it through `weak_ptr.get()` will return +`nullptr`. + +`BaseObjectPtr` is similar to `std::shared_ptr`, but also holds on to +objects of a `BaseObject` subclass `T`. While there are `BaseObjectPtr`s +pointing to a given object, the `BaseObject` will always maintain a strong +reference to its associated JavaScript object. This can be useful when one +`BaseObject` refers to another `BaseObject` and wants to make sure it stays +alive during the lifetime of that reference. + +A `BaseObject` can be “detached” through the `BaseObject::Detach()` method. +In this case, it will be deleted once the last `BaseObjectPtr` referring to +it is destroyed. There must be at least one such pointer when `Detach()` is +called. This can be useful when one `BaseObject` fully owns another +`BaseObject`. + + +### `AsyncWrap` + +`AsyncWrap` is a subclass of `BaseObject` that additionally provides tracking +functions for asynchronous calls. It is commonly used for classes whose methods +make calls into JavaScript without any JavaScript stack below, i.e. more or less +directly from the event loop. It is defined in [`async_wrap.h`][]. + +Every `AsyncWrap` subclass has a “provider type”. A list of provider types is +maintained in `src/async_wrap.h`. + +Every `AsyncWrap` instance is associated with two numbers, the “async id” +and the “async trigger id”. The “async id” is generally unique per `AsyncWrap` +instance, and only changes when the object is re-used in some way. + +See the [`async_hooks` module][] documentation for more information about how +this information is provided to async tracking tools. + + +#### `MakeCallback` + +The `AsyncWrap` class has a set of methods called `MakeCallback()`, with the +intention of the naming being that it is used to “make calls back into +JavaScript” from the event loop, rather than making callbacks in some way. +(As the naming has made its way into Node.js’s public API, it’s not worth +the breakage of fixing it). + +`MakeCallback()` generally calls a method on the JavaScript object associated +with the current `AsyncWrap`, and informs async tracking code about these calls +as well as takes care of running the `process.nextTick()` and `Promise` task +queues once it returns. + +Before calling `MakeCallback()`, it is typically necessary to enter both a +`HandleScope` and a `Context::Scope`. + +```cpp +void StatWatcher::Callback(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr) { + // Get the StatWatcher instance associated with this call from libuv, + // StatWatcher is a subclass of AsyncWrap. + StatWatcher* wrap = ContainerOf(&StatWatcher::watcher_, handle); + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + // Transform 'prev' and 'curr' into an array: + Local arr = ...; + + Local argv[] = { Integer::New(env->isolate(), status), arr }; + wrap->MakeCallback(env->onchange_string(), arraysize(argv), argv); +} +``` + +See [Callback scopes][] for more information. + + +### `HandleWrap` + +`HandleWrap` is a subclass of `AsyncWrap` specifically designed to make working +with [libuv handles][] easier. It provides the `.ref()`, `.unref()` and +`.hasRef()` methods as well as `.close()` to enable easier lifetime management +from JavaScript. It is defined in [`handle_wrap.h`][]. + +`HandleWrap` instances are [cleaned up][cleanup hooks] automatically when the +current Node.js [`Environment`][] is destroyed, e.g. when a Worker thread stops. + +`HandleWrap` also provides facilities for diagnostic tooling to get an +overview over libuv handles managed by Node.js. + + +### `ReqWrap` + +`ReqWrap` is a subclass of `AsyncWrap` specifically designed to make working +with [libuv requests][] easier. It is defined in [`req_wrap.h`][]. + +In particular, its `Dispatch()` method is designed to avoid the need to keep +track of the current count of active libuv requests. + +`ReqWrap` also provides facilities for diagnostic tooling to get an +overview over libuv handles managed by Node.js. + + +### Callback scopes + +The public `CallbackScope` and the internally used `InternalCallbackScope` +classes provide the same facilities as [`MakeCallback()`][], namely: + +* Emitting the `'before'` event for async tracking when entering the scope +* Setting the current async IDs to the ones passed to the constructor +* Emitting the `'after'` event for async tracking when leaving the scope +* Running the `process.nextTick()` queue +* Running microtasks, in particular `Promise` callbacks and async/await + functions + +Usually, using `AsyncWrap::MakeCallback()` or using the constructor taking +an `AsyncWrap*` argument (i.e. used as +`InternalCallbackScope callback_scope(this);`) suffices inside of Node.js’s +C++ codebase. + +## C++ utilities + +Node.js uses a few custom C++ utilities, mostly defined in [`util.h`][]. + +### Memory allocation + +Node.js provides `Malloc()`, `Realloc()` and `Calloc()` functions that work +like their C stdlib counterparts, but crash if memory cannot be allocated. +(As V8 does not handle out-of-memory situations gracefully, it does not make +sense for Node.js to attempt to do so in all cases.) + +The `UncheckedMalloc()`, `UncheckedRealloc()` and `UncheckedCalloc()` functions +return `nullptr` in these cases (or when `size == 0`). + +#### Optional stack-based memory allocation + +The `MaybeStackBuffer` class provides a way to allocate memory on the stack +if it is smaller than a given limit, and falls back to allocating it on the +heap if it is larger. This can be useful for performantly allocating temporary +data if it is typically expected to be small (e.g. file paths). + +The `Utf8Value`, `TwoByteValue` (i.e. UTF-16 value) and `BufferValue` +(`Utf8Value` but copy data from a `Buffer` if one is passed) helpers +inherit from this class and allow accessing the characters in a JavaScript +string this way. + +```cpp +static void Chdir(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + // ... + CHECK(args[0]->IsString()); + Utf8Value path(env->isolate(), args[0]); + int err = uv_chdir(*path); + if (err) { + // ... error handling ... + } +} +``` + +### Assertions + +Node.js provides a few macros that behave similar to `assert()`: + +* `CHECK(expression)` aborts the process with a stack trace + if `expression` is false. +* `CHECK_EQ(a, b)` checks for `a == b` +* `CHECK_GE(a, b)` checks for `a >= b` +* `CHECK_GT(a, b)` checks for `a > b` +* `CHECK_LE(a, b)` checks for `a <= b` +* `CHECK_LT(a, b)` checks for `a < b` +* `CHECK_NE(a, b)` checks for `a != b` +* `CHECK_NULL(val)` checks for `a == nullptr` +* `CHECK_NOT_NULL(val)` checks for `a != nullptr` +* `CHECK_IMPLIES(a, b)` checks that `b` is true if `a` is true. +* `UNREACHABLE([message])` aborts the process if it is reached. + +`CHECK`s are always enabled. For checks that should only run in debug mode, use +`DCHECK()`, `DCHECK_EQ()`, etc. + +### Scope-based cleanup + +The `OnScopeLeave()` function can be used to run a piece of code when leaving +the current C++ scope. + +```cpp +static void GetUserInfo(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + uv_passwd_t pwd; + // ... + + const int err = uv_os_get_passwd(&pwd); + + if (err) { + // ... error handling, return early ... + } + + auto free_passwd = OnScopeLeave([&]() { uv_os_free_passwd(&pwd); }); + + // ... + // Turn `pwd` into a JavaScript object now; whenever we return from this + // function, `uv_os_free_passwd()` will be called. + // ... +} +``` + +[C++ coding style]: ../doc/guides/cpp-style-guide.md +[Callback scopes]: #callback-scopes +[JavaScript value handles]: #js-handles +[N-API]: https://nodejs.org/api/n-api.html +[`BaseObject`]: #baseobject +[`Context`]: #context +[`Environment`]: #environment +[`Global`]: #global-handles +[`HandleWrap`]: #handlewrap +[`IsolateData`]: #isolate-data +[`Isolate`]: #isolate +[`Local`]: #local-handles +[`MakeCallback()`]: #makecallback +[`MessagePort`]: https://nodejs.org/api/worker_threads.html#worker_threads_class_messageport +[`ReqWrap`]: #reqwrap +[`async_hooks` module]: https://nodejs.org/api/async_hooks.html +[`async_wrap.h`]: async_wrap.h +[`base_object.h`]: base_object.h +[`handle_wrap.h`]: handle_wrap.h +[`memory_tracker.h`]: memory_tracker.h +[`req_wrap.h`]: req_wrap.h +[`util.h`]: util.h +[`v8.h` in Code Search]: https://cs.chromium.org/chromium/src/v8/include/v8.h +[`v8.h` in Node.js master]: https://github.com/nodejs/node/blob/master/deps/v8/include/v8.h +[`v8.h` in V8 master]: https://github.com/v8/v8/blob/master/include/v8.h +[`vm` module]: https://nodejs.org/api/vm.html +[binding function]: #binding-functions +[cleanup hooks]: #cleanup-hooks +[event loop]: #event-loop +[exception handling]: #exception-handling +[internal field]: #internal-fields +[introduction for V8 embedders]: https://v8.dev/docs/embed +[libuv]: https://libuv.org/ +[libuv handles]: #libuv-handles-and-requests +[libuv requests]: #libuv-handles-and-requests +[reference documentation for the libuv API]: http://docs.libuv.org/en/v1.x/ diff --git a/third_party/node/src/aliased_buffer.h b/third_party/node/src/aliased_buffer.h new file mode 100644 index 000000000..e762e8ede --- /dev/null +++ b/third_party/node/src/aliased_buffer.h @@ -0,0 +1,263 @@ +#ifndef SRC_ALIASED_BUFFER_H_ +#define SRC_ALIASED_BUFFER_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include +#include "util-inl.h" +#include "v8.h" + +namespace node { + +/** + * Do not use this class directly when creating instances of it - use the + * Aliased*Array defined at the end of this file instead. + * + * This class encapsulates the technique of having a native buffer mapped to + * a JS object. Writes to the native buffer can happen efficiently without + * going through JS, and the data is then available to user's via the exposed + * JS object. + * + * While this technique is computationally efficient, it is effectively a + * write to JS program state w/out going through the standard + * (monitored) API. Thus any VM capabilities to detect the modification are + * circumvented. + * + * The encapsulation herein provides a placeholder where such writes can be + * observed. Any notification APIs will be left as a future exercise. + */ +template ::value>> +class AliasedBufferBase { + public: + AliasedBufferBase(v8::Isolate* isolate, const size_t count) + : isolate_(isolate), count_(count), byte_offset_(0) { + CHECK_GT(count, 0); + const v8::HandleScope handle_scope(isolate_); + const size_t size_in_bytes = + MultiplyWithOverflowCheck(sizeof(NativeT), count); + + // allocate v8 ArrayBuffer + v8::Local ab = v8::ArrayBuffer::New( + isolate_, size_in_bytes); + buffer_ = static_cast(ab->GetBackingStore()->Data()); + + // allocate v8 TypedArray + v8::Local js_array = V8T::New(ab, byte_offset_, count); + js_array_ = v8::Global(isolate, js_array); + } + + /** + * Create an AliasedBufferBase over a sub-region of another aliased buffer. + * The two will share a v8::ArrayBuffer instance & + * a native buffer, but will each read/write to different sections of the + * native buffer. + * + * Note that byte_offset must by aligned by sizeof(NativeT). + */ + // TODO(refack): refactor into a non-owning `AliasedBufferBaseView` + AliasedBufferBase( + v8::Isolate* isolate, + const size_t byte_offset, + const size_t count, + const AliasedBufferBase& backing_buffer) + : isolate_(isolate), count_(count), byte_offset_(byte_offset) { + const v8::HandleScope handle_scope(isolate_); + + v8::Local ab = backing_buffer.GetArrayBuffer(); + + // validate that the byte_offset is aligned with sizeof(NativeT) + CHECK_EQ(byte_offset & (sizeof(NativeT) - 1), 0); + // validate this fits inside the backing buffer + CHECK_LE(MultiplyWithOverflowCheck(sizeof(NativeT), count), + ab->ByteLength() - byte_offset); + + buffer_ = reinterpret_cast( + const_cast(backing_buffer.GetNativeBuffer() + byte_offset)); + + v8::Local js_array = V8T::New(ab, byte_offset, count); + js_array_ = v8::Global(isolate, js_array); + } + + AliasedBufferBase(const AliasedBufferBase& that) + : isolate_(that.isolate_), + count_(that.count_), + byte_offset_(that.byte_offset_), + buffer_(that.buffer_) { + js_array_ = v8::Global(that.isolate_, that.GetJSArray()); + } + + AliasedBufferBase& operator=(AliasedBufferBase&& that) noexcept { + this->~AliasedBufferBase(); + isolate_ = that.isolate_; + count_ = that.count_; + byte_offset_ = that.byte_offset_; + buffer_ = that.buffer_; + + js_array_.Reset(isolate_, that.js_array_.Get(isolate_)); + + that.buffer_ = nullptr; + that.js_array_.Reset(); + return *this; + } + + /** + * Helper class that is returned from operator[] to support assignment into + * a specified location. + */ + class Reference { + public: + Reference(AliasedBufferBase* aliased_buffer, size_t index) + : aliased_buffer_(aliased_buffer), index_(index) {} + + Reference(const Reference& that) + : aliased_buffer_(that.aliased_buffer_), + index_(that.index_) { + } + + inline Reference& operator=(const NativeT& val) { + aliased_buffer_->SetValue(index_, val); + return *this; + } + + inline Reference& operator=(const Reference& val) { + return *this = static_cast(val); + } + + operator NativeT() const { + return aliased_buffer_->GetValue(index_); + } + + inline Reference& operator+=(const NativeT& val) { + const NativeT current = aliased_buffer_->GetValue(index_); + aliased_buffer_->SetValue(index_, current + val); + return *this; + } + + inline Reference& operator+=(const Reference& val) { + return this->operator+=(static_cast(val)); + } + + inline Reference& operator-=(const NativeT& val) { + const NativeT current = aliased_buffer_->GetValue(index_); + aliased_buffer_->SetValue(index_, current - val); + return *this; + } + + private: + AliasedBufferBase* aliased_buffer_; + size_t index_; + }; + + /** + * Get the underlying v8 TypedArray overlayed on top of the native buffer + */ + v8::Local GetJSArray() const { + return js_array_.Get(isolate_); + } + + /** + * Get the underlying v8::ArrayBuffer underlying the TypedArray and + * overlaying the native buffer + */ + v8::Local GetArrayBuffer() const { + return GetJSArray()->Buffer(); + } + + /** + * Get the underlying native buffer. Note that all reads/writes should occur + * through the GetValue/SetValue/operator[] methods + */ + inline const NativeT* GetNativeBuffer() const { + return buffer_; + } + + /** + * Synonym for GetBuffer() + */ + inline const NativeT* operator * () const { + return GetNativeBuffer(); + } + + /** + * Set position index to given value. + */ + inline void SetValue(const size_t index, NativeT value) { + DCHECK_LT(index, count_); + buffer_[index] = value; + } + + /** + * Get value at position index + */ + inline const NativeT GetValue(const size_t index) const { + DCHECK_LT(index, count_); + return buffer_[index]; + } + + /** + * Effectively, a synonym for GetValue/SetValue + */ + Reference operator[](size_t index) { + return Reference(this, index); + } + + NativeT operator[](size_t index) const { + return GetValue(index); + } + + size_t Length() const { + return count_; + } + + // Should only be used to extend the array. + // Should only be used on an owning array, not one created as a sub array of + // an owning `AliasedBufferBase`. + void reserve(size_t new_capacity) { + DCHECK_GE(new_capacity, count_); + DCHECK_EQ(byte_offset_, 0); + const v8::HandleScope handle_scope(isolate_); + + const size_t old_size_in_bytes = sizeof(NativeT) * count_; + const size_t new_size_in_bytes = MultiplyWithOverflowCheck(sizeof(NativeT), + new_capacity); + + // allocate v8 new ArrayBuffer + v8::Local ab = v8::ArrayBuffer::New( + isolate_, new_size_in_bytes); + + // allocate new native buffer + NativeT* new_buffer = static_cast(ab->GetBackingStore()->Data()); + // copy old content + memcpy(new_buffer, buffer_, old_size_in_bytes); + + // allocate v8 TypedArray + v8::Local js_array = V8T::New(ab, byte_offset_, new_capacity); + + // move over old v8 TypedArray + js_array_ = std::move(v8::Global(isolate_, js_array)); + + buffer_ = new_buffer; + count_ = new_capacity; + } + + private: + v8::Isolate* isolate_; + size_t count_; + size_t byte_offset_; + NativeT* buffer_; + v8::Global js_array_; +}; + +typedef AliasedBufferBase AliasedInt32Array; +typedef AliasedBufferBase AliasedUint8Array; +typedef AliasedBufferBase AliasedUint32Array; +typedef AliasedBufferBase AliasedFloat64Array; +typedef AliasedBufferBase AliasedBigUint64Array; +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_ALIASED_BUFFER_H_ diff --git a/third_party/node/src/aliased_struct-inl.h b/third_party/node/src/aliased_struct-inl.h new file mode 100644 index 000000000..17d5ff580 --- /dev/null +++ b/third_party/node/src/aliased_struct-inl.h @@ -0,0 +1,54 @@ +#ifndef SRC_ALIASED_STRUCT_INL_H_ +#define SRC_ALIASED_STRUCT_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "aliased_struct.h" +#include "v8.h" +#include + +namespace node { + +template +template +AliasedStruct::AliasedStruct(v8::Isolate* isolate, Args&&... args) + : isolate_(isolate) { + const v8::HandleScope handle_scope(isolate); + + store_ = v8::ArrayBuffer::NewBackingStore(isolate, sizeof(T)); + ptr_ = new (store_->Data()) T(std::forward(args)...); + DCHECK_NOT_NULL(ptr_); + + v8::Local buffer = v8::ArrayBuffer::New(isolate, store_); + buffer_ = v8::Global(isolate, buffer); +} + +template +AliasedStruct::AliasedStruct(const AliasedStruct& that) + : AliasedStruct(that.isolate_, *that) {} + +template +AliasedStruct& AliasedStruct::operator=( + AliasedStruct&& that) noexcept { + this->~AliasedStruct(); + isolate_ = that.isolate_; + store_ = that.store_; + ptr_ = that.ptr_; + + buffer_ = std::move(that.buffer_); + + that.ptr_ = nullptr; + that.store_.reset(); + return *this; +} + +template +AliasedStruct::~AliasedStruct() { + if (ptr_ != nullptr) ptr_->~T(); +} + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_ALIASED_STRUCT_INL_H_ diff --git a/third_party/node/src/aliased_struct.h b/third_party/node/src/aliased_struct.h new file mode 100644 index 000000000..e4df393f4 --- /dev/null +++ b/third_party/node/src/aliased_struct.h @@ -0,0 +1,63 @@ +#ifndef SRC_ALIASED_STRUCT_H_ +#define SRC_ALIASED_STRUCT_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "node_internals.h" +#include "v8.h" +#include + +namespace node { + +// AliasedStruct is a utility that allows uses a V8 Backing Store +// to be exposed to the C++/C side as a struct and to the +// JavaScript side as an ArrayBuffer to efficiently share +// data without marshalling. It is similar in nature to +// AliasedBuffer. +// +// struct Foo { int x; } +// +// AliasedStruct foo; +// foo->x = 1; +// +// Local ab = foo.GetArrayBuffer(); +template +class AliasedStruct final { + public: + template + explicit AliasedStruct(v8::Isolate* isolate, Args&&... args); + + inline AliasedStruct(const AliasedStruct& that); + + inline ~AliasedStruct(); + + inline AliasedStruct& operator=(AliasedStruct&& that) noexcept; + + v8::Local GetArrayBuffer() const { + return buffer_.Get(isolate_); + } + + const T* Data() const { return ptr_; } + + T* Data() { return ptr_; } + + const T& operator*() const { return *ptr_; } + + T& operator*() { return *ptr_; } + + const T* operator->() const { return ptr_; } + + T* operator->() { return ptr_; } + + private: + v8::Isolate* isolate_; + std::shared_ptr store_; + T* ptr_; + v8::Global buffer_; +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_ALIASED_STRUCT_H_ diff --git a/third_party/node/src/allocated_buffer-inl.h b/third_party/node/src/allocated_buffer-inl.h new file mode 100644 index 000000000..2dee6f09a --- /dev/null +++ b/third_party/node/src/allocated_buffer-inl.h @@ -0,0 +1,110 @@ +#ifndef SRC_ALLOCATED_BUFFER_INL_H_ +#define SRC_ALLOCATED_BUFFER_INL_H_ + +#include "allocated_buffer.h" +#include "base_object-inl.h" +#include "node_buffer.h" +#include "env-inl.h" +#include "uv.h" +#include "v8.h" +#include "util-inl.h" +#include "node_internals.h" + +namespace node { + +// It's a bit awkward to define this Buffer::New() overload here, but it +// avoids a circular dependency with node_internals.h. +namespace Buffer { +v8::MaybeLocal New(Environment* env, + v8::Local ab, + size_t byte_offset, + size_t length); +} + +NoArrayBufferZeroFillScope::NoArrayBufferZeroFillScope( + IsolateData* isolate_data) + : node_allocator_(isolate_data->node_allocator()) { + if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 0; +} + +NoArrayBufferZeroFillScope::~NoArrayBufferZeroFillScope() { + if (node_allocator_ != nullptr) node_allocator_->zero_fill_field()[0] = 1; +} + +AllocatedBuffer AllocatedBuffer::AllocateManaged( + Environment* env, + size_t size) { + NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); + std::unique_ptr bs = + v8::ArrayBuffer::NewBackingStore(env->isolate(), size); + return AllocatedBuffer(env, std::move(bs)); +} + +AllocatedBuffer::AllocatedBuffer( + Environment* env, std::unique_ptr bs) + : env_(env), backing_store_(std::move(bs)) {} + +AllocatedBuffer::AllocatedBuffer( + Environment* env, uv_buf_t buffer) + : env_(env) { + if (buffer.base == nullptr) return; + auto map = env->released_allocated_buffers(); + auto it = map->find(buffer.base); + CHECK_NE(it, map->end()); + backing_store_ = std::move(it->second); + map->erase(it); +} + +void AllocatedBuffer::Resize(size_t len) { + if (len == 0) { + backing_store_ = v8::ArrayBuffer::NewBackingStore(env_->isolate(), 0); + return; + } + NoArrayBufferZeroFillScope no_zero_fill_scope(env_->isolate_data()); + backing_store_ = v8::BackingStore::Reallocate( + env_->isolate(), std::move(backing_store_), len); +} + +uv_buf_t AllocatedBuffer::release() { + if (data() == nullptr) return uv_buf_init(nullptr, 0); + + CHECK_NOT_NULL(env_); + uv_buf_t ret = uv_buf_init(data(), size()); + env_->released_allocated_buffers()->emplace( + ret.base, std::move(backing_store_)); + return ret; +} + +char* AllocatedBuffer::data() { + if (!backing_store_) return nullptr; + return static_cast(backing_store_->Data()); +} + +const char* AllocatedBuffer::data() const { + if (!backing_store_) return nullptr; + return static_cast(backing_store_->Data()); +} + + +size_t AllocatedBuffer::size() const { + if (!backing_store_) return 0; + return backing_store_->ByteLength(); +} + +void AllocatedBuffer::clear() { + backing_store_.reset(); +} + +v8::MaybeLocal AllocatedBuffer::ToBuffer() { + v8::Local ab = ToArrayBuffer(); + return Buffer::New(env_, ab, 0, ab->ByteLength()) + .FromMaybe(v8::Local()); +} + +v8::Local AllocatedBuffer::ToArrayBuffer() { + return v8::ArrayBuffer::New(env_->isolate(), std::move(backing_store_)); +} + +} // namespace node + +#endif // SRC_ALLOCATED_BUFFER_INL_H_ diff --git a/third_party/node/src/allocated_buffer.h b/third_party/node/src/allocated_buffer.h new file mode 100644 index 000000000..c984a342a --- /dev/null +++ b/third_party/node/src/allocated_buffer.h @@ -0,0 +1,73 @@ +#ifndef SRC_ALLOCATED_BUFFER_H_ +#define SRC_ALLOCATED_BUFFER_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "base_object.h" +#include "uv.h" +#include "v8.h" +#include "env.h" + +namespace node { + +class Environment; + +// Disables zero-filling for ArrayBuffer allocations in this scope. This is +// similar to how we implement Buffer.allocUnsafe() in JS land. +class NoArrayBufferZeroFillScope{ + public: + inline explicit NoArrayBufferZeroFillScope(IsolateData* isolate_data); + inline ~NoArrayBufferZeroFillScope(); + + private: + NodeArrayBufferAllocator* node_allocator_; + + friend class Environment; +}; + +// A unique-pointer-ish object that is compatible with the JS engine's +// ArrayBuffer::Allocator. +// TODO(addaleax): We may want to start phasing this out as it's only a +// thin wrapper around v8::BackingStore at this point +struct AllocatedBuffer { + public: + // Utilities that allocate memory using the Isolate's ArrayBuffer::Allocator. + // In particular, using AllocateManaged() will provide a RAII-style object + // with easy conversion to `Buffer` and `ArrayBuffer` objects. + inline static AllocatedBuffer AllocateManaged(Environment* env, size_t size); + + AllocatedBuffer() = default; + inline AllocatedBuffer( + Environment* env, std::unique_ptr bs); + // For this constructor variant, `buffer` *must* come from an earlier call + // to .release + inline AllocatedBuffer(Environment* env, uv_buf_t buffer); + + inline void Resize(size_t len); + + inline uv_buf_t release(); + inline char* data(); + inline const char* data() const; + inline size_t size() const; + inline void clear(); + + inline v8::MaybeLocal ToBuffer(); + inline v8::Local ToArrayBuffer(); + + AllocatedBuffer(AllocatedBuffer&& other) = default; + AllocatedBuffer& operator=(AllocatedBuffer&& other) = default; + AllocatedBuffer(const AllocatedBuffer& other) = delete; + AllocatedBuffer& operator=(const AllocatedBuffer& other) = delete; + + private: + Environment* env_ = nullptr; + std::unique_ptr backing_store_; + + friend class Environment; +}; + +} // namespace node + +#endif // NODE_WANT_INTERNALS + +#endif // SRC_ALLOCATED_BUFFER_H_ diff --git a/third_party/node/src/api/async_resource.cc b/third_party/node/src/api/async_resource.cc new file mode 100644 index 000000000..3c4fbdadb --- /dev/null +++ b/third_party/node/src/api/async_resource.cc @@ -0,0 +1,70 @@ +#include "node.h" +#include "env-inl.h" + +namespace node { + +using v8::Function; +using v8::Isolate; +using v8::Local; +using v8::MaybeLocal; +using v8::Object; +using v8::String; +using v8::Value; + +AsyncResource::AsyncResource(Isolate* isolate, + Local resource, + const char* name, + async_id trigger_async_id) + : env_(Environment::GetCurrent(isolate)), + resource_(isolate, resource) { + CHECK_NOT_NULL(env_); + async_context_ = EmitAsyncInit(isolate, resource, name, + trigger_async_id); +} + +AsyncResource::~AsyncResource() { + EmitAsyncDestroy(env_, async_context_); +} + +MaybeLocal AsyncResource::MakeCallback(Local callback, + int argc, + Local* argv) { + return node::MakeCallback(env_->isolate(), get_resource(), + callback, argc, argv, + async_context_); +} + +MaybeLocal AsyncResource::MakeCallback(const char* method, + int argc, + Local* argv) { + return node::MakeCallback(env_->isolate(), get_resource(), + method, argc, argv, + async_context_); +} + +MaybeLocal AsyncResource::MakeCallback(Local symbol, + int argc, + Local* argv) { + return node::MakeCallback(env_->isolate(), get_resource(), + symbol, argc, argv, + async_context_); +} + +Local AsyncResource::get_resource() { + return resource_.Get(env_->isolate()); +} + +async_id AsyncResource::get_async_id() const { + return async_context_.async_id; +} + +async_id AsyncResource::get_trigger_async_id() const { + return async_context_.trigger_async_id; +} + +AsyncResource::CallbackScope::CallbackScope(AsyncResource* res) + : node::CallbackScope(res->env_, + res->resource_.Get(res->env_->isolate()), + res->async_context_) {} + +} // namespace node diff --git a/third_party/node/src/api/callback.cc b/third_party/node/src/api/callback.cc new file mode 100644 index 000000000..798a28662 --- /dev/null +++ b/third_party/node/src/api/callback.cc @@ -0,0 +1,313 @@ +#include "node.h" +#include "async_wrap-inl.h" +#include "env-inl.h" +#include "v8.h" + +namespace node { + +using v8::Context; +using v8::EscapableHandleScope; +using v8::Function; +using v8::HandleScope; +using v8::Isolate; +using v8::Local; +using v8::MaybeLocal; +using v8::MicrotasksScope; +using v8::Object; +using v8::String; +using v8::Value; + +CallbackScope::CallbackScope(Isolate* isolate, + Local object, + async_context async_context) + : CallbackScope(Environment::GetCurrent(isolate), object, async_context) {} + +CallbackScope::CallbackScope(Environment* env, + Local object, + async_context asyncContext) + : private_(new InternalCallbackScope(env, + object, + asyncContext)), + try_catch_(env->isolate()) { + try_catch_.SetVerbose(true); +} + +CallbackScope::~CallbackScope() { + if (try_catch_.HasCaught()) + private_->MarkAsFailed(); + delete private_; +} + +InternalCallbackScope::InternalCallbackScope(AsyncWrap* async_wrap, int flags) + : InternalCallbackScope(async_wrap->env(), + async_wrap->object(), + { async_wrap->get_async_id(), + async_wrap->get_trigger_async_id() }, + flags) {} + +InternalCallbackScope::InternalCallbackScope(Environment* env, + Local object, + const async_context& asyncContext, + int flags) + : env_(env), + async_context_(asyncContext), + object_(object), + skip_hooks_(flags & kSkipAsyncHooks), + skip_task_queues_(flags & kSkipTaskQueues) { + CHECK_NOT_NULL(env); + env->PushAsyncCallbackScope(); + + if (!env->can_call_into_js()) { + failed_ = true; + return; + } + + HandleScope handle_scope(env->isolate()); + // If you hit this assertion, you forgot to enter the v8::Context first. + CHECK_EQ(Environment::GetCurrent(env->isolate()), env); + + env->isolate()->SetIdle(false); + + env->async_hooks()->push_async_context( + async_context_.async_id, async_context_.trigger_async_id, object); + + pushed_ids_ = true; + + if (asyncContext.async_id != 0 && !skip_hooks_) { + // No need to check a return value because the application will exit if + // an exception occurs. + AsyncWrap::EmitBefore(env, asyncContext.async_id); + } +} + +InternalCallbackScope::~InternalCallbackScope() { + Close(); + env_->PopAsyncCallbackScope(); +} + +void InternalCallbackScope::Close() { + if (closed_) return; + closed_ = true; + + auto idle = OnScopeLeave([&]() { env_->isolate()->SetIdle(true); }); + + if (!env_->can_call_into_js()) return; + auto perform_stopping_check = [&]() { + if (env_->is_stopping()) { + MarkAsFailed(); + env_->async_hooks()->clear_async_id_stack(); + } + }; + perform_stopping_check(); + + if (!failed_ && async_context_.async_id != 0 && !skip_hooks_) { + AsyncWrap::EmitAfter(env_, async_context_.async_id); + } + + if (pushed_ids_) + env_->async_hooks()->pop_async_context(async_context_.async_id); + + if (failed_) return; + + if (env_->async_callback_scope_depth() > 1 || skip_task_queues_) { + return; + } + + TickInfo* tick_info = env_->tick_info(); + + if (!env_->can_call_into_js()) return; + + auto weakref_cleanup = OnScopeLeave([&]() { env_->RunWeakRefCleanup(); }); + + if (!tick_info->has_tick_scheduled()) { + MicrotasksScope::PerformCheckpoint(env_->isolate()); + + perform_stopping_check(); + } + + // Make sure the stack unwound properly. If there are nested MakeCallback's + // then it should return early and not reach this code. + if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) { + CHECK_EQ(env_->execution_async_id(), 0); + CHECK_EQ(env_->trigger_async_id(), 0); + } + + if (!tick_info->has_tick_scheduled() && !tick_info->has_rejection_to_warn()) { + return; + } + + HandleScope handle_scope(env_->isolate()); + Local process = env_->process_object(); + + if (!env_->can_call_into_js()) return; + + Local tick_callback = env_->tick_callback_function(); + + // The tick is triggered before JS land calls SetTickCallback + // to initializes the tick callback during bootstrap. + CHECK(!tick_callback.IsEmpty()); + + if (tick_callback->Call(env_->context(), process, 0, nullptr).IsEmpty()) { + failed_ = true; + } + perform_stopping_check(); +} + +MaybeLocal InternalMakeCallback(Environment* env, + Local resource, + Local recv, + const Local callback, + int argc, + Local argv[], + async_context asyncContext) { + CHECK(!recv.IsEmpty()); +#ifdef DEBUG + for (int i = 0; i < argc; i++) + CHECK(!argv[i].IsEmpty()); +#endif + + Local hook_cb = env->async_hooks_callback_trampoline(); + int flags = InternalCallbackScope::kNoFlags; + bool use_async_hooks_trampoline = false; + AsyncHooks* async_hooks = env->async_hooks(); + if (!hook_cb.IsEmpty()) { + // Use the callback trampoline if there are any before or after hooks, or + // we can expect some kind of usage of async_hooks.executionAsyncResource(). + flags = InternalCallbackScope::kSkipAsyncHooks; + use_async_hooks_trampoline = + async_hooks->fields()[AsyncHooks::kBefore] + + async_hooks->fields()[AsyncHooks::kAfter] + + async_hooks->fields()[AsyncHooks::kUsesExecutionAsyncResource] > 0; + } + + InternalCallbackScope scope(env, resource, asyncContext, flags); + if (scope.Failed()) { + return MaybeLocal(); + } + + MaybeLocal ret; + + if (use_async_hooks_trampoline) { + MaybeStackBuffer, 16> args(3 + argc); + args[0] = v8::Number::New(env->isolate(), asyncContext.async_id); + args[1] = resource; + args[2] = callback; + for (int i = 0; i < argc; i++) { + args[i + 3] = argv[i]; + } + ret = hook_cb->Call(env->context(), recv, args.length(), &args[0]); + } else { + ret = callback->Call(env->context(), recv, argc, argv); + } + + if (ret.IsEmpty()) { + scope.MarkAsFailed(); + return MaybeLocal(); + } + + scope.Close(); + if (scope.Failed()) { + return MaybeLocal(); + } + + return ret; +} + +// Public MakeCallback()s + +MaybeLocal MakeCallback(Isolate* isolate, + Local recv, + const char* method, + int argc, + Local argv[], + async_context asyncContext) { + Local method_string = + String::NewFromUtf8(isolate, method).ToLocalChecked(); + return MakeCallback(isolate, recv, method_string, argc, argv, asyncContext); +} + +MaybeLocal MakeCallback(Isolate* isolate, + Local recv, + Local symbol, + int argc, + Local argv[], + async_context asyncContext) { + // Check can_call_into_js() first because calling Get() might do so. + Environment* env = Environment::GetCurrent(recv->CreationContext()); + CHECK_NOT_NULL(env); + if (!env->can_call_into_js()) return Local(); + + Local callback_v; + if (!recv->Get(isolate->GetCurrentContext(), symbol).ToLocal(&callback_v)) + return Local(); + if (!callback_v->IsFunction()) { + // This used to return an empty value, but Undefined() makes more sense + // since no exception is pending here. + return Undefined(isolate); + } + Local callback = callback_v.As(); + return MakeCallback(isolate, recv, callback, argc, argv, asyncContext); +} + +MaybeLocal MakeCallback(Isolate* isolate, + Local recv, + Local callback, + int argc, + Local argv[], + async_context asyncContext) { + // Observe the following two subtleties: + // + // 1. The environment is retrieved from the callback function's context. + // 2. The context to enter is retrieved from the environment. + // + // Because of the AssignToContext() call in src/node_contextify.cc, + // the two contexts need not be the same. + Environment* env = Environment::GetCurrent(callback->CreationContext()); + CHECK_NOT_NULL(env); + Context::Scope context_scope(env->context()); + MaybeLocal ret = + InternalMakeCallback(env, recv, recv, callback, argc, argv, asyncContext); + if (ret.IsEmpty() && env->async_callback_scope_depth() == 0) { + // This is only for legacy compatibility and we may want to look into + // removing/adjusting it. + return Undefined(env->isolate()); + } + return ret; +} + +// Legacy MakeCallback()s + +Local MakeCallback(Isolate* isolate, + Local recv, + const char* method, + int argc, + Local* argv) { + EscapableHandleScope handle_scope(isolate); + return handle_scope.Escape( + MakeCallback(isolate, recv, method, argc, argv, {0, 0}) + .FromMaybe(Local())); +} + +Local MakeCallback(Isolate* isolate, + Local recv, + Local symbol, + int argc, + Local* argv) { + EscapableHandleScope handle_scope(isolate); + return handle_scope.Escape( + MakeCallback(isolate, recv, symbol, argc, argv, {0, 0}) + .FromMaybe(Local())); +} + +Local MakeCallback(Isolate* isolate, + Local recv, + Local callback, + int argc, + Local* argv) { + EscapableHandleScope handle_scope(isolate); + return handle_scope.Escape( + MakeCallback(isolate, recv, callback, argc, argv, {0, 0}) + .FromMaybe(Local())); +} + +} // namespace node diff --git a/third_party/node/src/api/encoding.cc b/third_party/node/src/api/encoding.cc new file mode 100644 index 000000000..f64aeee15 --- /dev/null +++ b/third_party/node/src/api/encoding.cc @@ -0,0 +1,156 @@ +#include "node.h" +#include "string_bytes.h" +#include "util-inl.h" +#include "v8.h" + +namespace node { + +using v8::HandleScope; +using v8::Isolate; +using v8::Local; +using v8::Value; + +enum encoding ParseEncoding(const char* encoding, + enum encoding default_encoding) { + switch (encoding[0]) { + case 'u': + case 'U': + // utf8, utf16le + if (encoding[1] == 't' && encoding[2] == 'f') { + // Skip `-` + const size_t skip = encoding[3] == '-' ? 4 : 3; + if (encoding[skip] == '8' && encoding[skip + 1] == '\0') + return UTF8; + if (strncmp(encoding + skip, "16le", 5) == 0) + return UCS2; + // ucs2 + } else if (encoding[1] == 'c' && encoding[2] == 's') { + const size_t skip = encoding[3] == '-' ? 4 : 3; + if (encoding[skip] == '2' && encoding[skip + 1] == '\0') + return UCS2; + } + if (StringEqualNoCase(encoding, "utf8")) + return UTF8; + if (StringEqualNoCase(encoding, "utf-8")) + return UTF8; + if (StringEqualNoCase(encoding, "ucs2")) + return UCS2; + if (StringEqualNoCase(encoding, "ucs-2")) + return UCS2; + if (StringEqualNoCase(encoding, "utf16le")) + return UCS2; + if (StringEqualNoCase(encoding, "utf-16le")) + return UCS2; + break; + + case 'l': + case 'L': + // latin1 + if (encoding[1] == 'a') { + if (strncmp(encoding + 2, "tin1", 5) == 0) + return LATIN1; + } + if (StringEqualNoCase(encoding, "latin1")) + return LATIN1; + break; + + case 'b': + case 'B': + // binary is a deprecated alias of latin1 + if (encoding[1] == 'i') { + if (strncmp(encoding + 2, "nary", 5) == 0) + return LATIN1; + // buffer + } else if (encoding[1] == 'u') { + if (strncmp(encoding + 2, "ffer", 5) == 0) + return BUFFER; + // base64 + } else if (encoding[1] == 'a') { + if (strncmp(encoding + 2, "se64", 5) == 0) + return BASE64; + if (strncmp(encoding + 2, "se64url", 8) == 0) + return BASE64URL; + } + if (StringEqualNoCase(encoding, "binary")) + return LATIN1; // BINARY is a deprecated alias of LATIN1. + if (StringEqualNoCase(encoding, "buffer")) + return BUFFER; + if (StringEqualNoCase(encoding, "base64")) + return BASE64; + if (StringEqualNoCase(encoding, "base64url")) + return BASE64URL; + break; + + case 'a': + case 'A': + // ascii + if (encoding[1] == 's') { + if (strncmp(encoding + 2, "cii", 4) == 0) + return ASCII; + } + if (StringEqualNoCase(encoding, "ascii")) + return ASCII; + break; + + case 'h': + case 'H': + // hex + if (encoding[1] == 'e') + if (encoding[2] == 'x' && encoding[3] == '\0') + return HEX; + if (StringEqualNoCase(encoding, "hex")) + return HEX; + break; + } + return default_encoding; +} + + +enum encoding ParseEncoding(Isolate* isolate, + Local encoding_v, + enum encoding default_encoding) { + CHECK(!encoding_v.IsEmpty()); + + if (!encoding_v->IsString()) + return default_encoding; + + Utf8Value encoding(isolate, encoding_v); + + return ParseEncoding(*encoding, default_encoding); +} + +Local Encode(Isolate* isolate, + const char* buf, + size_t len, + enum encoding encoding) { + CHECK_NE(encoding, UCS2); + Local error; + return StringBytes::Encode(isolate, buf, len, encoding, &error) + .ToLocalChecked(); +} + +Local Encode(Isolate* isolate, const uint16_t* buf, size_t len) { + Local error; + return StringBytes::Encode(isolate, buf, len, &error) + .ToLocalChecked(); +} + +// Returns -1 if the handle was not valid for decoding +ssize_t DecodeBytes(Isolate* isolate, + Local val, + enum encoding encoding) { + HandleScope scope(isolate); + + return StringBytes::Size(isolate, val, encoding).FromMaybe(-1); +} + +// Returns number of bytes written. +ssize_t DecodeWrite(Isolate* isolate, + char* buf, + size_t buflen, + Local val, + enum encoding encoding) { + return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr); +} + +} // namespace node diff --git a/third_party/node/src/api/environment.cc b/third_party/node/src/api/environment.cc new file mode 100644 index 000000000..52c67b91c --- /dev/null +++ b/third_party/node/src/api/environment.cc @@ -0,0 +1,732 @@ +#include "node.h" +#include "node_context_data.h" +#include "node_errors.h" +#include "node_internals.h" +#include "node_native_module_env.h" +#include "node_platform.h" +#include "node_v8_platform-inl.h" +#include "uv.h" + +#if HAVE_INSPECTOR +#include "inspector/worker_inspector.h" // ParentInspectorHandle +#endif + +namespace node { +using errors::TryCatchScope; +using v8::Array; +using v8::Context; +using v8::EscapableHandleScope; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::HandleScope; +using v8::Isolate; +using v8::Local; +using v8::MaybeLocal; +using v8::Null; +using v8::Object; +using v8::ObjectTemplate; +using v8::Private; +using v8::PropertyDescriptor; +using v8::String; +using v8::Value; + +bool AllowWasmCodeGenerationCallback(Local context, + Local) { + Local wasm_code_gen = + context->GetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration); + return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue(); +} + +bool ShouldAbortOnUncaughtException(Isolate* isolate) { + DebugSealHandleScope scope(isolate); + Environment* env = Environment::GetCurrent(isolate); + return env != nullptr && + (env->is_main_thread() || !env->is_stopping()) && + env->abort_on_uncaught_exception() && + env->should_abort_on_uncaught_toggle()[0] && + !env->inside_should_not_abort_on_uncaught_scope(); +} + +MaybeLocal PrepareStackTraceCallback(Local context, + Local exception, + Local trace) { + Environment* env = Environment::GetCurrent(context); + if (env == nullptr) { + return exception->ToString(context).FromMaybe(Local()); + } + Local prepare = env->prepare_stack_trace_callback(); + if (prepare.IsEmpty()) { + return exception->ToString(context).FromMaybe(Local()); + } + Local args[] = { + context->Global(), + exception, + trace, + }; + // This TryCatch + Rethrow is required by V8 due to details around exception + // handling there. For C++ callbacks, V8 expects a scheduled exception (which + // is what ReThrow gives us). Just returning the empty MaybeLocal would leave + // us with a pending exception. + TryCatchScope try_catch(env); + MaybeLocal result = prepare->Call( + context, Undefined(env->isolate()), arraysize(args), args); + if (try_catch.HasCaught() && !try_catch.HasTerminated()) { + try_catch.ReThrow(); + } + return result; +} + +void* NodeArrayBufferAllocator::Allocate(size_t size) { + void* ret; + if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) + ret = UncheckedCalloc(size); + else + ret = UncheckedMalloc(size); + if (LIKELY(ret != nullptr)) + total_mem_usage_.fetch_add(size, std::memory_order_relaxed); + return ret; +} + +void* NodeArrayBufferAllocator::AllocateUninitialized(size_t size) { + void* ret = node::UncheckedMalloc(size); + if (LIKELY(ret != nullptr)) + total_mem_usage_.fetch_add(size, std::memory_order_relaxed); + return ret; +} + +void* NodeArrayBufferAllocator::Reallocate( + void* data, size_t old_size, size_t size) { + void* ret = UncheckedRealloc(static_cast(data), size); + if (LIKELY(ret != nullptr) || UNLIKELY(size == 0)) + total_mem_usage_.fetch_add(size - old_size, std::memory_order_relaxed); + return ret; +} + +void NodeArrayBufferAllocator::Free(void* data, size_t size) { + total_mem_usage_.fetch_sub(size, std::memory_order_relaxed); + free(data); +} + +DebuggingArrayBufferAllocator::~DebuggingArrayBufferAllocator() { + CHECK(allocations_.empty()); +} + +void* DebuggingArrayBufferAllocator::Allocate(size_t size) { + Mutex::ScopedLock lock(mutex_); + void* data = NodeArrayBufferAllocator::Allocate(size); + RegisterPointerInternal(data, size); + return data; +} + +void* DebuggingArrayBufferAllocator::AllocateUninitialized(size_t size) { + Mutex::ScopedLock lock(mutex_); + void* data = NodeArrayBufferAllocator::AllocateUninitialized(size); + RegisterPointerInternal(data, size); + return data; +} + +void DebuggingArrayBufferAllocator::Free(void* data, size_t size) { + Mutex::ScopedLock lock(mutex_); + UnregisterPointerInternal(data, size); + NodeArrayBufferAllocator::Free(data, size); +} + +void* DebuggingArrayBufferAllocator::Reallocate(void* data, + size_t old_size, + size_t size) { + Mutex::ScopedLock lock(mutex_); + void* ret = NodeArrayBufferAllocator::Reallocate(data, old_size, size); + if (ret == nullptr) { + if (size == 0) // i.e. equivalent to free(). + UnregisterPointerInternal(data, old_size); + return nullptr; + } + + if (data != nullptr) { + auto it = allocations_.find(data); + CHECK_NE(it, allocations_.end()); + allocations_.erase(it); + } + + RegisterPointerInternal(ret, size); + return ret; +} + +void DebuggingArrayBufferAllocator::RegisterPointer(void* data, size_t size) { + Mutex::ScopedLock lock(mutex_); + NodeArrayBufferAllocator::RegisterPointer(data, size); + RegisterPointerInternal(data, size); +} + +void DebuggingArrayBufferAllocator::UnregisterPointer(void* data, size_t size) { + Mutex::ScopedLock lock(mutex_); + NodeArrayBufferAllocator::UnregisterPointer(data, size); + UnregisterPointerInternal(data, size); +} + +void DebuggingArrayBufferAllocator::UnregisterPointerInternal(void* data, + size_t size) { + if (data == nullptr) return; + auto it = allocations_.find(data); + CHECK_NE(it, allocations_.end()); + if (size > 0) { + // We allow allocations with size 1 for 0-length buffers to avoid having + // to deal with nullptr values. + CHECK_EQ(it->second, size); + } + allocations_.erase(it); +} + +void DebuggingArrayBufferAllocator::RegisterPointerInternal(void* data, + size_t size) { + if (data == nullptr) return; + CHECK_EQ(allocations_.count(data), 0); + allocations_[data] = size; +} + +std::unique_ptr ArrayBufferAllocator::Create(bool debug) { + if (debug || per_process::cli_options->debug_arraybuffer_allocations) + return std::make_unique(); + else + return std::make_unique(); +} + +ArrayBufferAllocator* CreateArrayBufferAllocator() { + return ArrayBufferAllocator::Create().release(); +} + +void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator) { + delete allocator; +} + +void SetIsolateCreateParamsForNode(Isolate::CreateParams* params) { + const uint64_t constrained_memory = uv_get_constrained_memory(); + const uint64_t total_memory = constrained_memory > 0 ? + std::min(uv_get_total_memory(), constrained_memory) : + uv_get_total_memory(); + if (total_memory > 0) { + // V8 defaults to 700MB or 1.4GB on 32 and 64 bit platforms respectively. + // This default is based on browser use-cases. Tell V8 to configure the + // heap based on the actual physical memory. + params->constraints.ConfigureDefaults(total_memory, 0); + } +} + +void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) { + if (s.flags & MESSAGE_LISTENER_WITH_ERROR_LEVEL) + isolate->AddMessageListenerWithErrorLevel( + errors::PerIsolateMessageListener, + Isolate::MessageErrorLevel::kMessageError | + Isolate::MessageErrorLevel::kMessageWarning); + + auto* abort_callback = s.should_abort_on_uncaught_exception_callback ? + s.should_abort_on_uncaught_exception_callback : + ShouldAbortOnUncaughtException; + isolate->SetAbortOnUncaughtExceptionCallback(abort_callback); + + auto* fatal_error_cb = s.fatal_error_callback ? + s.fatal_error_callback : OnFatalError; + isolate->SetFatalErrorHandler(fatal_error_cb); + + if ((s.flags & SHOULD_NOT_SET_PREPARE_STACK_TRACE_CALLBACK) == 0) { + auto* prepare_stack_trace_cb = s.prepare_stack_trace_callback ? + s.prepare_stack_trace_callback : PrepareStackTraceCallback; + isolate->SetPrepareStackTraceCallback(prepare_stack_trace_cb); + } +} + +void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) { + isolate->SetMicrotasksPolicy(s.policy); + + auto* allow_wasm_codegen_cb = s.allow_wasm_code_generation_callback ? + s.allow_wasm_code_generation_callback : AllowWasmCodeGenerationCallback; + isolate->SetAllowWasmCodeGenerationCallback(allow_wasm_codegen_cb); + + if ((s.flags & SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK) == 0) { + auto* promise_reject_cb = s.promise_reject_callback ? + s.promise_reject_callback : PromiseRejectCallback; + isolate->SetPromiseRejectCallback(promise_reject_cb); + } + + if (s.flags & DETAILED_SOURCE_POSITIONS_FOR_PROFILING) + v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(isolate); +} + +void SetIsolateUpForNode(v8::Isolate* isolate, + const IsolateSettings& settings) { + SetIsolateErrorHandlers(isolate, settings); + SetIsolateMiscHandlers(isolate, settings); +} + +void SetIsolateUpForNode(v8::Isolate* isolate) { + IsolateSettings settings; + SetIsolateUpForNode(isolate, settings); +} + +Isolate* NewIsolate(ArrayBufferAllocator* allocator, uv_loop_t* event_loop) { + return NewIsolate(allocator, event_loop, GetMainThreadMultiIsolatePlatform()); +} + +// TODO(joyeecheung): we may want to expose this, but then we need to be +// careful about what we override in the params. +Isolate* NewIsolate(Isolate::CreateParams* params, + uv_loop_t* event_loop, + MultiIsolatePlatform* platform) { + Isolate* isolate = Isolate::Allocate(); + if (isolate == nullptr) return nullptr; + + // Register the isolate on the platform before the isolate gets initialized, + // so that the isolate can access the platform during initialization. + platform->RegisterIsolate(isolate, event_loop); + + SetIsolateCreateParamsForNode(params); + Isolate::Initialize(isolate, *params); + SetIsolateUpForNode(isolate); + + return isolate; +} + +Isolate* NewIsolate(ArrayBufferAllocator* allocator, + uv_loop_t* event_loop, + MultiIsolatePlatform* platform) { + Isolate::CreateParams params; + if (allocator != nullptr) params.array_buffer_allocator = allocator; + return NewIsolate(¶ms, event_loop, platform); +} + +Isolate* NewIsolate(std::shared_ptr allocator, + uv_loop_t* event_loop, + MultiIsolatePlatform* platform) { + Isolate::CreateParams params; + if (allocator) params.array_buffer_allocator_shared = allocator; + return NewIsolate(¶ms, event_loop, platform); +} + +IsolateData* CreateIsolateData(Isolate* isolate, + uv_loop_t* loop, + MultiIsolatePlatform* platform, + ArrayBufferAllocator* allocator) { + return new IsolateData(isolate, loop, platform, allocator); +} + +void FreeIsolateData(IsolateData* isolate_data) { + delete isolate_data; +} + +InspectorParentHandle::~InspectorParentHandle() {} + +// Hide the internal handle class from the public API. +#if HAVE_INSPECTOR +struct InspectorParentHandleImpl : public InspectorParentHandle { + std::unique_ptr impl; + + explicit InspectorParentHandleImpl( + std::unique_ptr&& impl) + : impl(std::move(impl)) {} +}; +#endif + +Environment* CreateEnvironment(IsolateData* isolate_data, + Local context, + int argc, + const char* const* argv, + int exec_argc, + const char* const* exec_argv) { + return CreateEnvironment( + isolate_data, context, + std::vector(argv, argv + argc), + std::vector(exec_argv, exec_argv + exec_argc)); +} + +Environment* CreateEnvironment( + IsolateData* isolate_data, + Local context, + const std::vector& args, + const std::vector& exec_args, + EnvironmentFlags::Flags flags, + ThreadId thread_id, + std::unique_ptr inspector_parent_handle) { + Isolate* isolate = context->GetIsolate(); + HandleScope handle_scope(isolate); + Context::Scope context_scope(context); + // TODO(addaleax): This is a much better place for parsing per-Environment + // options than the global parse call. + Environment* env = new Environment( + isolate_data, + context, + args, + exec_args, + flags, + thread_id); + +#if HAVE_INSPECTOR + if (inspector_parent_handle) { + env->InitializeInspector( + std::move(static_cast( + inspector_parent_handle.get())->impl)); + } else { + env->InitializeInspector({}); + } +#endif + + if (env->RunBootstrapping().IsEmpty()) { + FreeEnvironment(env); + return nullptr; + } + + return env; +} + +void FreeEnvironment(Environment* env) { + { + // TODO(addaleax): This should maybe rather be in a SealHandleScope. + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + env->set_stopping(true); + env->stop_sub_worker_contexts(); + env->RunCleanup(); + RunAtExit(env); + } + + // This call needs to be made while the `Environment` is still alive + // because we assume that it is available for async tracking in the + // NodePlatform implementation. + MultiIsolatePlatform* platform = env->isolate_data()->platform(); + if (platform != nullptr) + platform->DrainTasks(env->isolate()); + + delete env; +} + +NODE_EXTERN std::unique_ptr GetInspectorParentHandle( + Environment* env, + ThreadId thread_id, + const char* url) { + CHECK_NOT_NULL(env); + CHECK_NE(thread_id.id, static_cast(-1)); +#if HAVE_INSPECTOR + return std::make_unique( + env->inspector_agent()->GetParentHandle(thread_id.id, url)); +#else + return {}; +#endif +} + +void LoadEnvironment(Environment* env) { + USE(LoadEnvironment(env, + StartExecutionCallback{}, + {})); +} + +MaybeLocal LoadEnvironment( + Environment* env, + StartExecutionCallback cb, + std::unique_ptr removeme) { + env->InitializeLibuv(); + env->InitializeDiagnostics(); + + return StartExecution(env, cb); +} + +MaybeLocal LoadEnvironment( + Environment* env, + const char* main_script_source_utf8, + std::unique_ptr removeme) { + CHECK_NOT_NULL(main_script_source_utf8); + return LoadEnvironment( + env, + [&](const StartExecutionCallbackInfo& info) -> MaybeLocal { + // This is a slightly hacky way to convert UTF-8 to UTF-16. + Local str = + String::NewFromUtf8(env->isolate(), + main_script_source_utf8).ToLocalChecked(); + auto main_utf16 = std::make_unique(env->isolate(), str); + + // TODO(addaleax): Avoid having a global table for all scripts. + std::string name = "embedder_main_" + std::to_string(env->thread_id()); + native_module::NativeModuleEnv::Add( + name.c_str(), + UnionBytes(**main_utf16, main_utf16->length())); + env->set_main_utf16(std::move(main_utf16)); + std::vector> params = { + env->process_string(), + env->require_string()}; + std::vector> args = { + env->process_object(), + env->native_module_require()}; + return ExecuteBootstrapper(env, name.c_str(), ¶ms, &args); + }); +} + +Environment* GetCurrentEnvironment(Local context) { + return Environment::GetCurrent(context); +} + +MultiIsolatePlatform* GetMainThreadMultiIsolatePlatform() { + return per_process::v8_platform.Platform(); +} + +IsolateData* GetEnvironmentIsolateData(Environment* env) { + return env->isolate_data(); +} + +ArrayBufferAllocator* GetArrayBufferAllocator(IsolateData* isolate_data) { + return isolate_data->node_allocator(); +} + +MultiIsolatePlatform* GetMultiIsolatePlatform(Environment* env) { + return GetMultiIsolatePlatform(env->isolate_data()); +} + +MultiIsolatePlatform* GetMultiIsolatePlatform(IsolateData* env) { + return env->platform(); +} + +MultiIsolatePlatform* CreatePlatform( + int thread_pool_size, + node::tracing::TracingController* tracing_controller) { + return CreatePlatform( + thread_pool_size, + static_cast(tracing_controller)); +} + +MultiIsolatePlatform* CreatePlatform( + int thread_pool_size, + v8::TracingController* tracing_controller) { + return MultiIsolatePlatform::Create(thread_pool_size, tracing_controller) + .release(); +} + +void FreePlatform(MultiIsolatePlatform* platform) { + delete platform; +} + +std::unique_ptr MultiIsolatePlatform::Create( + int thread_pool_size, + v8::TracingController* tracing_controller) { + return std::make_unique(thread_pool_size, tracing_controller); +} + +MaybeLocal GetPerContextExports(Local context) { + Isolate* isolate = context->GetIsolate(); + EscapableHandleScope handle_scope(isolate); + + Local global = context->Global(); + Local key = Private::ForApi(isolate, + FIXED_ONE_BYTE_STRING(isolate, "node:per_context_binding_exports")); + + Local existing_value; + if (!global->GetPrivate(context, key).ToLocal(&existing_value)) + return MaybeLocal(); + if (existing_value->IsObject()) + return handle_scope.Escape(existing_value.As()); + + Local exports = Object::New(isolate); + if (context->Global()->SetPrivate(context, key, exports).IsNothing() || + !InitializePrimordials(context)) + return MaybeLocal(); + return handle_scope.Escape(exports); +} + +// Any initialization logic should be performed in +// InitializeContext, because embedders don't necessarily +// call NewContext and so they will experience breakages. +Local NewContext(Isolate* isolate, + Local object_template) { + auto context = Context::New(isolate, nullptr, object_template); + if (context.IsEmpty()) return context; + + if (!InitializeContext(context)) { + return Local(); + } + + return context; +} + +void ProtoThrower(const FunctionCallbackInfo& info) { + THROW_ERR_PROTO_ACCESS(info.GetIsolate()); +} + +// This runs at runtime, regardless of whether the context +// is created from a snapshot. +void InitializeContextRuntime(Local context) { + Isolate* isolate = context->GetIsolate(); + HandleScope handle_scope(isolate); + + // Delete `Intl.v8BreakIterator` + // https://github.com/nodejs/node/issues/14909 + Local intl_string = FIXED_ONE_BYTE_STRING(isolate, "Intl"); + Local break_iter_string = + FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator"); + Local intl_v; + if (context->Global()->Get(context, intl_string).ToLocal(&intl_v) && + intl_v->IsObject()) { + Local intl = intl_v.As(); + intl->Delete(context, break_iter_string).Check(); + } + + // Delete `Atomics.wake` + // https://github.com/nodejs/node/issues/21219 + Local atomics_string = FIXED_ONE_BYTE_STRING(isolate, "Atomics"); + Local wake_string = FIXED_ONE_BYTE_STRING(isolate, "wake"); + Local atomics_v; + if (context->Global()->Get(context, atomics_string).ToLocal(&atomics_v) && + atomics_v->IsObject()) { + Local atomics = atomics_v.As(); + atomics->Delete(context, wake_string).Check(); + } + + // Remove __proto__ + // https://github.com/nodejs/node/issues/31951 + Local object_string = FIXED_ONE_BYTE_STRING(isolate, "Object"); + Local prototype_string = FIXED_ONE_BYTE_STRING(isolate, "prototype"); + Local prototype = context->Global() + ->Get(context, object_string) + .ToLocalChecked() + .As() + ->Get(context, prototype_string) + .ToLocalChecked() + .As(); + Local proto_string = FIXED_ONE_BYTE_STRING(isolate, "__proto__"); + if (per_process::cli_options->disable_proto == "delete") { + prototype->Delete(context, proto_string).ToChecked(); + } else if (per_process::cli_options->disable_proto == "throw") { + Local thrower = + Function::New(context, ProtoThrower).ToLocalChecked(); + PropertyDescriptor descriptor(thrower, thrower); + descriptor.set_enumerable(false); + descriptor.set_configurable(true); + prototype->DefineProperty(context, proto_string, descriptor).ToChecked(); + } else if (per_process::cli_options->disable_proto != "") { + // Validated in ProcessGlobalArgs + FatalError("InitializeContextRuntime()", "invalid --disable-proto mode"); + } +} + +bool InitializeContextForSnapshot(Local context) { + Isolate* isolate = context->GetIsolate(); + HandleScope handle_scope(isolate); + + context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration, + True(isolate)); + return InitializePrimordials(context); +} + +bool InitializePrimordials(Local context) { + // Run per-context JS files. + Isolate* isolate = context->GetIsolate(); + Context::Scope context_scope(context); + Local exports; + + Local primordials_string = + FIXED_ONE_BYTE_STRING(isolate, "primordials"); + Local global_string = FIXED_ONE_BYTE_STRING(isolate, "global"); + Local exports_string = FIXED_ONE_BYTE_STRING(isolate, "exports"); + + // Create primordials first and make it available to per-context scripts. + Local primordials = Object::New(isolate); + if (!primordials->SetPrototype(context, Null(isolate)).FromJust() || + !GetPerContextExports(context).ToLocal(&exports) || + !exports->Set(context, primordials_string, primordials).FromJust()) { + return false; + } + + static const char* context_files[] = {"internal/per_context/primordials", + "internal/per_context/domexception", + "internal/per_context/messageport", + nullptr}; + + for (const char** module = context_files; *module != nullptr; module++) { + std::vector> parameters = { + global_string, exports_string, primordials_string}; + Local arguments[] = {context->Global(), exports, primordials}; + MaybeLocal maybe_fn = + native_module::NativeModuleEnv::LookupAndCompile( + context, *module, ¶meters, nullptr); + Local fn; + if (!maybe_fn.ToLocal(&fn)) { + return false; + } + MaybeLocal result = + fn->Call(context, Undefined(isolate), arraysize(arguments), arguments); + // Execution failed during context creation. + // TODO(joyeecheung): deprecate this signature and return a MaybeLocal. + if (result.IsEmpty()) { + return false; + } + } + + return true; +} + +bool InitializeContext(Local context) { + if (!InitializeContextForSnapshot(context)) { + return false; + } + + InitializeContextRuntime(context); + return true; +} + +uv_loop_t* GetCurrentEventLoop(Isolate* isolate) { + HandleScope handle_scope(isolate); + Local context = isolate->GetCurrentContext(); + if (context.IsEmpty()) return nullptr; + Environment* env = Environment::GetCurrent(context); + if (env == nullptr) return nullptr; + return env->event_loop(); +} + +void AddLinkedBinding(Environment* env, const node_module& mod) { + CHECK_NOT_NULL(env); + Mutex::ScopedLock lock(env->extra_linked_bindings_mutex()); + + node_module* prev_tail = env->extra_linked_bindings_tail(); + env->extra_linked_bindings()->push_back(mod); + if (prev_tail != nullptr) + prev_tail->nm_link = &env->extra_linked_bindings()->back(); +} + +void AddLinkedBinding(Environment* env, const napi_module& mod) { + AddLinkedBinding(env, napi_module_to_node_module(&mod)); +} + +void AddLinkedBinding(Environment* env, + const char* name, + addon_context_register_func fn, + void* priv) { + node_module mod = { + NODE_MODULE_VERSION, + NM_F_LINKED, + nullptr, // nm_dso_handle + nullptr, // nm_filename + nullptr, // nm_register_func + fn, + name, + priv, + nullptr // nm_link + }; + AddLinkedBinding(env, mod); +} + +static std::atomic next_thread_id{0}; + +ThreadId AllocateEnvironmentThreadId() { + return ThreadId { next_thread_id++ }; +} + +void DefaultProcessExitHandler(Environment* env, int exit_code) { + env->set_can_call_into_js(false); + env->stop_sub_worker_contexts(); + DisposePlatform(); + uv_library_shutdown(); + exit(exit_code); +} + + +void SetProcessExitHandler(Environment* env, + std::function&& handler) { + env->set_process_exit_handler(std::move(handler)); +} + +} // namespace node diff --git a/third_party/node/src/api/exceptions.cc b/third_party/node/src/api/exceptions.cc new file mode 100644 index 000000000..310b2acc4 --- /dev/null +++ b/third_party/node/src/api/exceptions.cc @@ -0,0 +1,246 @@ +// This file contains implementation of error APIs exposed in node.h + +#include "env-inl.h" +#include "node.h" +#include "node_errors.h" +#include "util-inl.h" +#include "uv.h" +#include "v8.h" + +#include + +namespace node { + +using v8::Exception; +using v8::Integer; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +Local ErrnoException(Isolate* isolate, + int errorno, + const char* syscall, + const char* msg, + const char* path) { + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + + Local e; + Local estring = OneByteString(isolate, errors::errno_string(errorno)); + if (msg == nullptr || msg[0] == '\0') { + msg = strerror(errorno); + } + Local message = OneByteString(isolate, msg); + + Local cons = + String::Concat(isolate, estring, FIXED_ONE_BYTE_STRING(isolate, ", ")); + cons = String::Concat(isolate, cons, message); + + Local path_string; + if (path != nullptr) { + // FIXME(bnoordhuis) It's questionable to interpret the file path as UTF-8. + path_string = String::NewFromUtf8(isolate, path).ToLocalChecked(); + } + + if (path_string.IsEmpty() == false) { + cons = String::Concat(isolate, cons, FIXED_ONE_BYTE_STRING(isolate, " '")); + cons = String::Concat(isolate, cons, path_string); + cons = String::Concat(isolate, cons, FIXED_ONE_BYTE_STRING(isolate, "'")); + } + e = Exception::Error(cons); + + Local obj = e.As(); + obj->Set(env->context(), + env->errno_string(), + Integer::New(isolate, errorno)).Check(); + obj->Set(env->context(), env->code_string(), estring).Check(); + + if (path_string.IsEmpty() == false) { + obj->Set(env->context(), env->path_string(), path_string).Check(); + } + + if (syscall != nullptr) { + obj->Set(env->context(), + env->syscall_string(), + OneByteString(isolate, syscall)).Check(); + } + + return e; +} + +static Local StringFromPath(Isolate* isolate, const char* path) { +#ifdef _WIN32 + if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) { + return String::Concat( + isolate, + FIXED_ONE_BYTE_STRING(isolate, "\\\\"), + String::NewFromUtf8(isolate, path + 8).ToLocalChecked()); + } else if (strncmp(path, "\\\\?\\", 4) == 0) { + return String::NewFromUtf8(isolate, path + 4).ToLocalChecked(); + } +#endif + + return String::NewFromUtf8(isolate, path).ToLocalChecked(); +} + + +Local UVException(Isolate* isolate, + int errorno, + const char* syscall, + const char* msg, + const char* path, + const char* dest) { + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + + if (!msg || !msg[0]) + msg = uv_strerror(errorno); + + Local js_code = OneByteString(isolate, uv_err_name(errorno)); + Local js_syscall = OneByteString(isolate, syscall); + Local js_path; + Local js_dest; + + Local js_msg = js_code; + js_msg = + String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ": ")); + js_msg = String::Concat(isolate, js_msg, OneByteString(isolate, msg)); + js_msg = + String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ", ")); + js_msg = String::Concat(isolate, js_msg, js_syscall); + + if (path != nullptr) { + js_path = StringFromPath(isolate, path); + + js_msg = + String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, " '")); + js_msg = String::Concat(isolate, js_msg, js_path); + js_msg = + String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, "'")); + } + + if (dest != nullptr) { + js_dest = StringFromPath(isolate, dest); + + js_msg = String::Concat( + isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, " -> '")); + js_msg = String::Concat(isolate, js_msg, js_dest); + js_msg = + String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, "'")); + } + + Local e = + Exception::Error(js_msg)->ToObject(isolate->GetCurrentContext()) + .ToLocalChecked(); + + e->Set(env->context(), + env->errno_string(), + Integer::New(isolate, errorno)).Check(); + e->Set(env->context(), env->code_string(), js_code).Check(); + e->Set(env->context(), env->syscall_string(), js_syscall).Check(); + if (!js_path.IsEmpty()) + e->Set(env->context(), env->path_string(), js_path).Check(); + if (!js_dest.IsEmpty()) + e->Set(env->context(), env->dest_string(), js_dest).Check(); + + return e; +} + +#ifdef _WIN32 +// Does about the same as strerror(), +// but supports all windows error messages +static const char* winapi_strerror(const int errorno, bool* must_free) { + char* errmsg = nullptr; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + errorno, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast(&errmsg), + 0, + nullptr); + + if (errmsg) { + *must_free = true; + + // Remove trailing newlines + for (int i = strlen(errmsg) - 1; + i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); + i--) { + errmsg[i] = '\0'; + } + + return errmsg; + } else { + // FormatMessage failed + *must_free = false; + return "Unknown error"; + } +} + +Local WinapiErrnoException(Isolate* isolate, + int errorno, + const char* syscall, + const char* msg, + const char* path) { + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + Local e; + bool must_free = false; + if (!msg || !msg[0]) { + msg = winapi_strerror(errorno, &must_free); + } + Local message = OneByteString(isolate, msg); + + if (path) { + Local cons1 = + String::Concat(isolate, message, FIXED_ONE_BYTE_STRING(isolate, " '")); + Local cons2 = String::Concat( + isolate, + cons1, + String::NewFromUtf8(isolate, path).ToLocalChecked()); + Local cons3 = + String::Concat(isolate, cons2, FIXED_ONE_BYTE_STRING(isolate, "'")); + e = Exception::Error(cons3); + } else { + e = Exception::Error(message); + } + + Local obj = e.As(); + obj->Set(env->context(), env->errno_string(), Integer::New(isolate, errorno)) + .Check(); + + if (path != nullptr) { + obj->Set(env->context(), + env->path_string(), + String::NewFromUtf8(isolate, path).ToLocalChecked()) + .Check(); + } + + if (syscall != nullptr) { + obj->Set(env->context(), + env->syscall_string(), + OneByteString(isolate, syscall)) + .Check(); + } + + if (must_free) { + LocalFree(const_cast(msg)); + } + + return e; +} +#endif + +// Implement the legacy name exposed in node.h. This has not been in fact +// fatal any more, as the user can handle the exception in the +// TryCatch by listening to `uncaughtException`. +// TODO(joyeecheung): deprecate it in favor of a more accurate name. +void FatalException(Isolate* isolate, const v8::TryCatch& try_catch) { + errors::TriggerUncaughtException(isolate, try_catch); +} + +} // namespace node diff --git a/third_party/node/src/api/hooks.cc b/third_party/node/src/api/hooks.cc new file mode 100644 index 000000000..79fa896a1 --- /dev/null +++ b/third_party/node/src/api/hooks.cc @@ -0,0 +1,231 @@ +#include "env-inl.h" +#include "node_internals.h" +#include "node_process-inl.h" +#include "async_wrap.h" + +namespace node { + +using v8::Context; +using v8::HandleScope; +using v8::Integer; +using v8::Isolate; +using v8::Just; +using v8::Local; +using v8::Maybe; +using v8::NewStringType; +using v8::Nothing; +using v8::Object; +using v8::String; +using v8::Value; + +void RunAtExit(Environment* env) { + env->RunAtExitCallbacks(); +} + +void AtExit(void (*cb)(void* arg), void* arg) { + auto env = Environment::GetThreadLocalEnv(); + AtExit(env, cb, arg); +} + +void AtExit(Environment* env, void (*cb)(void* arg), void* arg) { + CHECK_NOT_NULL(env); + env->AtExit(cb, arg); +} + +void EmitBeforeExit(Environment* env) { + USE(EmitProcessBeforeExit(env)); +} + +Maybe EmitProcessBeforeExit(Environment* env) { + TraceEventScope trace_scope(TRACING_CATEGORY_NODE1(environment), + "BeforeExit", env); + if (!env->destroy_async_id_list()->empty()) + AsyncWrap::DestroyAsyncIdsCallback(env); + + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local exit_code_v; + if (!env->process_object()->Get(env->context(), env->exit_code_string()) + .ToLocal(&exit_code_v)) return Nothing(); + + Local exit_code; + if (!exit_code_v->ToInteger(env->context()).ToLocal(&exit_code)) { + return Nothing(); + } + + return ProcessEmit(env, "beforeExit", exit_code).IsEmpty() ? + Nothing() : Just(true); +} + +int EmitExit(Environment* env) { + return EmitProcessExit(env).FromMaybe(1); +} + +Maybe EmitProcessExit(Environment* env) { + // process.emit('exit') + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + Local process_object = env->process_object(); + + // TODO(addaleax): It might be nice to share process._exiting and + // process.exitCode via getter/setter pairs that pass data directly to the + // native side, so that we don't manually have to read and write JS properties + // here. These getters could use e.g. a typed array for performance. + if (process_object + ->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "_exiting"), + True(env->isolate())).IsNothing()) return Nothing(); + + Local exit_code = env->exit_code_string(); + Local code_v; + int code; + if (!process_object->Get(env->context(), exit_code).ToLocal(&code_v) || + !code_v->Int32Value(env->context()).To(&code) || + ProcessEmit(env, "exit", Integer::New(env->isolate(), code)).IsEmpty() || + // Reload exit code, it may be changed by `emit('exit')` + !process_object->Get(env->context(), exit_code).ToLocal(&code_v) || + !code_v->Int32Value(env->context()).To(&code)) { + return Nothing(); + } + + return Just(code); +} + +typedef void (*CleanupHook)(void* arg); +typedef void (*AsyncCleanupHook)(void* arg, void(*)(void*), void*); + +struct AsyncCleanupHookInfo final { + Environment* env; + AsyncCleanupHook fun; + void* arg; + bool started = false; + // Use a self-reference to make sure the storage is kept alive while the + // cleanup hook is registered but not yet finished. + std::shared_ptr self; +}; + +// Opaque type that is basically an alias for `shared_ptr` +// (but not publicly so for easier ABI/API changes). In particular, +// std::shared_ptr does not generally maintain a consistent ABI even on a +// specific platform. +struct ACHHandle final { + std::shared_ptr info; +}; +// This is implemented as an operator on a struct because otherwise you can't +// default-initialize AsyncCleanupHookHandle, because in C++ for a +// std::unique_ptr to be default-initializable the deleter type also needs +// to be default-initializable; in particular, function types don't satisfy +// this. +void DeleteACHHandle::operator ()(ACHHandle* handle) const { delete handle; } + +void AddEnvironmentCleanupHook(Isolate* isolate, + CleanupHook fun, + void* arg) { + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + env->AddCleanupHook(fun, arg); +} + +void RemoveEnvironmentCleanupHook(Isolate* isolate, + CleanupHook fun, + void* arg) { + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + env->RemoveCleanupHook(fun, arg); +} + +static void FinishAsyncCleanupHook(void* arg) { + AsyncCleanupHookInfo* info = static_cast(arg); + std::shared_ptr keep_alive = info->self; + + info->env->DecreaseWaitingRequestCounter(); + info->self.reset(); +} + +static void RunAsyncCleanupHook(void* arg) { + AsyncCleanupHookInfo* info = static_cast(arg); + info->env->IncreaseWaitingRequestCounter(); + info->started = true; + info->fun(info->arg, FinishAsyncCleanupHook, info); +} + +AsyncCleanupHookHandle AddEnvironmentCleanupHook( + Isolate* isolate, + AsyncCleanupHook fun, + void* arg) { + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + auto info = std::make_shared(); + info->env = env; + info->fun = fun; + info->arg = arg; + info->self = info; + env->AddCleanupHook(RunAsyncCleanupHook, info.get()); + return AsyncCleanupHookHandle(new ACHHandle { info }); +} + +void RemoveEnvironmentCleanupHook( + AsyncCleanupHookHandle handle) { + if (handle->info->started) return; + handle->info->self.reset(); + handle->info->env->RemoveCleanupHook(RunAsyncCleanupHook, handle->info.get()); +} + +async_id AsyncHooksGetExecutionAsyncId(Isolate* isolate) { + Environment* env = Environment::GetCurrent(isolate); + if (env == nullptr) return -1; + return env->execution_async_id(); +} + +async_id AsyncHooksGetTriggerAsyncId(Isolate* isolate) { + Environment* env = Environment::GetCurrent(isolate); + if (env == nullptr) return -1; + return env->trigger_async_id(); +} + + +async_context EmitAsyncInit(Isolate* isolate, + Local resource, + const char* name, + async_id trigger_async_id) { + HandleScope handle_scope(isolate); + Local type = + String::NewFromUtf8(isolate, name, NewStringType::kInternalized) + .ToLocalChecked(); + return EmitAsyncInit(isolate, resource, type, trigger_async_id); +} + +async_context EmitAsyncInit(Isolate* isolate, + Local resource, + Local name, + async_id trigger_async_id) { + DebugSealHandleScope handle_scope(isolate); + Environment* env = Environment::GetCurrent(isolate); + CHECK_NOT_NULL(env); + + // Initialize async context struct + if (trigger_async_id == -1) + trigger_async_id = env->get_default_trigger_async_id(); + + async_context context = { + env->new_async_id(), // async_id_ + trigger_async_id // trigger_async_id_ + }; + + // Run init hooks + AsyncWrap::EmitAsyncInit(env, resource, name, context.async_id, + context.trigger_async_id); + + return context; +} + +void EmitAsyncDestroy(Isolate* isolate, async_context asyncContext) { + EmitAsyncDestroy(Environment::GetCurrent(isolate), asyncContext); +} + +void EmitAsyncDestroy(Environment* env, async_context asyncContext) { + AsyncWrap::EmitDestroy(env, asyncContext.async_id); +} + +} // namespace node diff --git a/third_party/node/src/api/utils.cc b/third_party/node/src/api/utils.cc new file mode 100644 index 000000000..f07f9bea2 --- /dev/null +++ b/third_party/node/src/api/utils.cc @@ -0,0 +1,169 @@ +#include "node.h" + +#include + +namespace node { + +const char* signo_string(int signo) { +#define SIGNO_CASE(e) \ + case e: \ + return #e; + switch (signo) { +#ifdef SIGHUP + SIGNO_CASE(SIGHUP); +#endif + +#ifdef SIGINT + SIGNO_CASE(SIGINT); +#endif + +#ifdef SIGQUIT + SIGNO_CASE(SIGQUIT); +#endif + +#ifdef SIGILL + SIGNO_CASE(SIGILL); +#endif + +#ifdef SIGTRAP + SIGNO_CASE(SIGTRAP); +#endif + +#ifdef SIGABRT + SIGNO_CASE(SIGABRT); +#endif + +#ifdef SIGIOT +#if SIGABRT != SIGIOT + SIGNO_CASE(SIGIOT); +#endif +#endif + +#ifdef SIGBUS + SIGNO_CASE(SIGBUS); +#endif + +#ifdef SIGFPE + SIGNO_CASE(SIGFPE); +#endif + +#ifdef SIGKILL + SIGNO_CASE(SIGKILL); +#endif + +#ifdef SIGUSR1 + SIGNO_CASE(SIGUSR1); +#endif + +#ifdef SIGSEGV + SIGNO_CASE(SIGSEGV); +#endif + +#ifdef SIGUSR2 + SIGNO_CASE(SIGUSR2); +#endif + +#ifdef SIGPIPE + SIGNO_CASE(SIGPIPE); +#endif + +#ifdef SIGALRM + SIGNO_CASE(SIGALRM); +#endif + + SIGNO_CASE(SIGTERM); + +#ifdef SIGCHLD + SIGNO_CASE(SIGCHLD); +#endif + +#ifdef SIGSTKFLT + SIGNO_CASE(SIGSTKFLT); +#endif + +#ifdef SIGCONT + SIGNO_CASE(SIGCONT); +#endif + +#ifdef SIGSTOP + SIGNO_CASE(SIGSTOP); +#endif + +#ifdef SIGTSTP + SIGNO_CASE(SIGTSTP); +#endif + +#ifdef SIGBREAK + SIGNO_CASE(SIGBREAK); +#endif + +#ifdef SIGTTIN + SIGNO_CASE(SIGTTIN); +#endif + +#ifdef SIGTTOU + SIGNO_CASE(SIGTTOU); +#endif + +#ifdef SIGURG + SIGNO_CASE(SIGURG); +#endif + +#ifdef SIGXCPU + SIGNO_CASE(SIGXCPU); +#endif + +#ifdef SIGXFSZ + SIGNO_CASE(SIGXFSZ); +#endif + +#ifdef SIGVTALRM + SIGNO_CASE(SIGVTALRM); +#endif + +#ifdef SIGPROF + SIGNO_CASE(SIGPROF); +#endif + +#ifdef SIGWINCH + SIGNO_CASE(SIGWINCH); +#endif + +#ifdef SIGIO + SIGNO_CASE(SIGIO); +#endif + +#ifdef SIGPOLL +#if SIGPOLL != SIGIO + SIGNO_CASE(SIGPOLL); +#endif +#endif + +#ifdef SIGLOST +#if SIGLOST != SIGABRT + SIGNO_CASE(SIGLOST); +#endif +#endif + +#ifdef SIGPWR +#if SIGPWR != SIGLOST + SIGNO_CASE(SIGPWR); +#endif +#endif + +#ifdef SIGINFO +#if !defined(SIGPWR) || SIGINFO != SIGPWR + SIGNO_CASE(SIGINFO); +#endif +#endif + +#ifdef SIGSYS + SIGNO_CASE(SIGSYS); +#endif + + default: + return ""; + } +} + +} // namespace node diff --git a/third_party/node/src/async_wrap-inl.h b/third_party/node/src/async_wrap-inl.h new file mode 100644 index 000000000..03745081f --- /dev/null +++ b/third_party/node/src/async_wrap-inl.h @@ -0,0 +1,94 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_ASYNC_WRAP_INL_H_ +#define SRC_ASYNC_WRAP_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "async_wrap.h" +#include "base_object-inl.h" +#include "node_internals.h" + +namespace node { + +inline AsyncWrap::ProviderType AsyncWrap::provider_type() const { + return provider_type_; +} + +inline AsyncWrap::ProviderType AsyncWrap::set_provider_type( + AsyncWrap::ProviderType provider) { + provider_type_ = provider; + return provider_type_; +} + +inline double AsyncWrap::get_async_id() const { + return async_id_; +} + + +inline double AsyncWrap::get_trigger_async_id() const { + return trigger_async_id_; +} + + +inline v8::MaybeLocal AsyncWrap::MakeCallback( + const v8::Local symbol, + int argc, + v8::Local* argv) { + return MakeCallback(symbol.As(), argc, argv); +} + + +inline v8::MaybeLocal AsyncWrap::MakeCallback( + const v8::Local symbol, + int argc, + v8::Local* argv) { + return MakeCallback(symbol.As(), argc, argv); +} + + +inline v8::MaybeLocal AsyncWrap::MakeCallback( + const v8::Local symbol, + int argc, + v8::Local* argv) { + v8::Local cb_v; + if (!object()->Get(env()->context(), symbol).ToLocal(&cb_v)) + return v8::MaybeLocal(); + if (!cb_v->IsFunction()) { + v8::Isolate* isolate = env()->isolate(); + return Undefined(isolate); + } + return MakeCallback(cb_v.As(), argc, argv); +} + + +// Defined here to avoid a circular dependency with env-inl.h. +inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope( + AsyncWrap* async_wrap) + : DefaultTriggerAsyncIdScope(async_wrap->env(), + async_wrap->get_async_id()) {} + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_ASYNC_WRAP_INL_H_ diff --git a/third_party/node/src/async_wrap.cc b/third_party/node/src/async_wrap.cc new file mode 100644 index 000000000..7590ab019 --- /dev/null +++ b/third_party/node/src/async_wrap.cc @@ -0,0 +1,728 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "async_wrap.h" // NOLINT(build/include_inline) +#include "async_wrap-inl.h" +#include "env-inl.h" +#include "node_errors.h" +#include "tracing/traced_value.h" +#include "util-inl.h" + +#include "v8.h" + +using v8::Context; +using v8::DontDelete; +using v8::EscapableHandleScope; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Global; +using v8::HandleScope; +using v8::Integer; +using v8::Isolate; +using v8::Local; +using v8::MaybeLocal; +using v8::Nothing; +using v8::Number; +using v8::Object; +using v8::PropertyAttribute; +using v8::ReadOnly; +using v8::String; +using v8::Uint32; +using v8::Undefined; +using v8::Value; +using v8::WeakCallbackInfo; +using v8::WeakCallbackType; + +using TryCatchScope = node::errors::TryCatchScope; + +namespace node { + +static const char* const provider_names[] = { +#define V(PROVIDER) \ + #PROVIDER, + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V +}; + + +struct AsyncWrapObject : public AsyncWrap { + static inline void New(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + CHECK(args.IsConstructCall()); + CHECK(env->async_wrap_object_ctor_template()->HasInstance(args.This())); + CHECK(args[0]->IsUint32()); + auto type = static_cast(args[0].As()->Value()); + new AsyncWrapObject(env, args.This(), type); + } + + inline AsyncWrapObject(Environment* env, Local object, + ProviderType type) : AsyncWrap(env, object, type) {} + + static Local GetConstructorTemplate(Environment* env) { + Local tmpl = env->async_wrap_object_ctor_template(); + if (tmpl.IsEmpty()) { + tmpl = env->NewFunctionTemplate(AsyncWrapObject::New); + tmpl->SetClassName( + FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap")); + tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env)); + tmpl->InstanceTemplate()->SetInternalFieldCount( + AsyncWrapObject::kInternalFieldCount); + env->set_async_wrap_object_ctor_template(tmpl); + } + return tmpl; + } + + bool IsNotIndicativeOfMemoryLeakAtExit() const override { + // We can't really know what the underlying operation does. One of the + // signs that it's time to remove this class. :) + return true; + } + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(AsyncWrapObject) + SET_SELF_SIZE(AsyncWrapObject) +}; + +void AsyncWrap::DestroyAsyncIdsCallback(Environment* env) { + Local fn = env->async_hooks_destroy_function(); + + TryCatchScope try_catch(env, TryCatchScope::CatchMode::kFatal); + + do { + std::vector destroy_async_id_list; + destroy_async_id_list.swap(*env->destroy_async_id_list()); + if (!env->can_call_into_js()) return; + for (auto async_id : destroy_async_id_list) { + // Want each callback to be cleaned up after itself, instead of cleaning + // them all up after the while() loop completes. + HandleScope scope(env->isolate()); + Local async_id_value = Number::New(env->isolate(), async_id); + MaybeLocal ret = fn->Call( + env->context(), Undefined(env->isolate()), 1, &async_id_value); + + if (ret.IsEmpty()) + return; + } + } while (!env->destroy_async_id_list()->empty()); +} + +void Emit(Environment* env, double async_id, AsyncHooks::Fields type, + Local fn) { + AsyncHooks* async_hooks = env->async_hooks(); + + if (async_hooks->fields()[type] == 0 || !env->can_call_into_js()) + return; + + HandleScope handle_scope(env->isolate()); + Local async_id_value = Number::New(env->isolate(), async_id); + TryCatchScope try_catch(env, TryCatchScope::CatchMode::kFatal); + USE(fn->Call(env->context(), Undefined(env->isolate()), 1, &async_id_value)); +} + + +void AsyncWrap::EmitPromiseResolve(Environment* env, double async_id) { + Emit(env, async_id, AsyncHooks::kPromiseResolve, + env->async_hooks_promise_resolve_function()); +} + + +void AsyncWrap::EmitTraceEventBefore() { + switch (provider_type()) { +#define V(PROVIDER) \ + case PROVIDER_ ## PROVIDER: \ + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( \ + TRACING_CATEGORY_NODE1(async_hooks), \ + #PROVIDER "_CALLBACK", static_cast(get_async_id())); \ + break; + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V + default: + UNREACHABLE(); + } +} + + +void AsyncWrap::EmitBefore(Environment* env, double async_id) { + Emit(env, async_id, AsyncHooks::kBefore, + env->async_hooks_before_function()); +} + + +void AsyncWrap::EmitTraceEventAfter(ProviderType type, double async_id) { + switch (type) { +#define V(PROVIDER) \ + case PROVIDER_ ## PROVIDER: \ + TRACE_EVENT_NESTABLE_ASYNC_END0( \ + TRACING_CATEGORY_NODE1(async_hooks), \ + #PROVIDER "_CALLBACK", static_cast(async_id)); \ + break; + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V + default: + UNREACHABLE(); + } +} + + +void AsyncWrap::EmitAfter(Environment* env, double async_id) { + // If the user's callback failed then the after() hooks will be called at the + // end of _fatalException(). + Emit(env, async_id, AsyncHooks::kAfter, + env->async_hooks_after_function()); +} + +// TODO(addaleax): Remove once we're on C++17. +constexpr double AsyncWrap::kInvalidAsyncId; + +static void SetupHooks(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + CHECK(args[0]->IsObject()); + + // All of init, before, after, destroy, and promise_resolve are supplied by + // async_hooks internally, so this should only ever be called once. At which + // time all the functions should be set. Detect this by checking if + // init !IsEmpty(). + CHECK(env->async_hooks_init_function().IsEmpty()); + + Local fn_obj = args[0].As(); + +#define SET_HOOK_FN(name) \ + do { \ + Local v = \ + fn_obj->Get(env->context(), \ + FIXED_ONE_BYTE_STRING(env->isolate(), #name)) \ + .ToLocalChecked(); \ + CHECK(v->IsFunction()); \ + env->set_async_hooks_##name##_function(v.As()); \ + } while (0) + + SET_HOOK_FN(init); + SET_HOOK_FN(before); + SET_HOOK_FN(after); + SET_HOOK_FN(destroy); + SET_HOOK_FN(promise_resolve); +#undef SET_HOOK_FN +} + +static void SetPromiseHooks(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + env->async_hooks()->SetJSPromiseHooks( + args[0]->IsFunction() ? args[0].As() : Local(), + args[1]->IsFunction() ? args[1].As() : Local(), + args[2]->IsFunction() ? args[2].As() : Local(), + args[3]->IsFunction() ? args[3].As() : Local()); +} + +class DestroyParam { + public: + double asyncId; + Environment* env; + Global target; + Global propBag; +}; + +static void DestroyParamCleanupHook(void* ptr) { + delete static_cast(ptr); +} + +void AsyncWrap::WeakCallback(const WeakCallbackInfo& info) { + HandleScope scope(info.GetIsolate()); + + std::unique_ptr p{info.GetParameter()}; + Local prop_bag = PersistentToLocal::Default(info.GetIsolate(), + p->propBag); + Local val; + + p->env->RemoveCleanupHook(DestroyParamCleanupHook, p.get()); + + if (!prop_bag->Get(p->env->context(), p->env->destroyed_string()) + .ToLocal(&val)) { + return; + } + + if (val->IsFalse()) { + AsyncWrap::EmitDestroy(p->env, p->asyncId); + } + // unique_ptr goes out of scope here and pointer is deleted. +} + + +static void RegisterDestroyHook(const FunctionCallbackInfo& args) { + CHECK(args[0]->IsObject()); + CHECK(args[1]->IsNumber()); + CHECK(args[2]->IsObject()); + + Isolate* isolate = args.GetIsolate(); + DestroyParam* p = new DestroyParam(); + p->asyncId = args[1].As()->Value(); + p->env = Environment::GetCurrent(args); + p->target.Reset(isolate, args[0].As()); + p->propBag.Reset(isolate, args[2].As()); + p->target.SetWeak(p, AsyncWrap::WeakCallback, WeakCallbackType::kParameter); + p->env->AddCleanupHook(DestroyParamCleanupHook, p); +} + +void AsyncWrap::GetAsyncId(const FunctionCallbackInfo& args) { + AsyncWrap* wrap; + args.GetReturnValue().Set(kInvalidAsyncId); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + args.GetReturnValue().Set(wrap->get_async_id()); +} + + +void AsyncWrap::PushAsyncContext(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + // No need for CHECK(IsNumber()) on args because if FromJust() doesn't fail + // then the checks in push_async_ids() and pop_async_id() will. + double async_id = args[0]->NumberValue(env->context()).FromJust(); + double trigger_async_id = args[1]->NumberValue(env->context()).FromJust(); + env->async_hooks()->push_async_context(async_id, trigger_async_id, {}); +} + + +void AsyncWrap::PopAsyncContext(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + double async_id = args[0]->NumberValue(env->context()).FromJust(); + args.GetReturnValue().Set(env->async_hooks()->pop_async_context(async_id)); +} + + +void AsyncWrap::ExecutionAsyncResource( + const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + uint32_t index; + if (!args[0]->Uint32Value(env->context()).To(&index)) return; + args.GetReturnValue().Set( + env->async_hooks()->native_execution_async_resource(index)); +} + + +void AsyncWrap::ClearAsyncIdStack(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + env->async_hooks()->clear_async_id_stack(); +} + + +void AsyncWrap::AsyncReset(const FunctionCallbackInfo& args) { + CHECK(args[0]->IsObject()); + + AsyncWrap* wrap; + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + + Local resource = args[0].As(); + double execution_async_id = + args[1]->IsNumber() ? args[1].As()->Value() : kInvalidAsyncId; + wrap->AsyncReset(resource, execution_async_id); +} + + +void AsyncWrap::GetProviderType(const FunctionCallbackInfo& args) { + AsyncWrap* wrap; + args.GetReturnValue().Set(AsyncWrap::PROVIDER_NONE); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + args.GetReturnValue().Set(wrap->provider_type()); +} + + +void AsyncWrap::EmitDestroy(bool from_gc) { + AsyncWrap::EmitDestroy(env(), async_id_); + // Ensure no double destroy is emitted via AsyncReset(). + async_id_ = kInvalidAsyncId; + + if (!persistent().IsEmpty() && !from_gc) { + HandleScope handle_scope(env()->isolate()); + USE(object()->Set(env()->context(), env()->resource_symbol(), object())); + } +} + +void AsyncWrap::QueueDestroyAsyncId(const FunctionCallbackInfo& args) { + CHECK(args[0]->IsNumber()); + AsyncWrap::EmitDestroy( + Environment::GetCurrent(args), + args[0].As()->Value()); +} + +void AsyncWrap::SetCallbackTrampoline(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + CHECK(args[0]->IsFunction()); + + env->set_async_hooks_callback_trampoline(args[0].As()); +} + +Local AsyncWrap::GetConstructorTemplate(Environment* env) { + Local tmpl = env->async_wrap_ctor_template(); + if (tmpl.IsEmpty()) { + tmpl = env->NewFunctionTemplate(nullptr); + tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap")); + tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); + env->SetProtoMethod(tmpl, "getAsyncId", AsyncWrap::GetAsyncId); + env->SetProtoMethod(tmpl, "asyncReset", AsyncWrap::AsyncReset); + env->SetProtoMethod(tmpl, "getProviderType", AsyncWrap::GetProviderType); + env->set_async_wrap_ctor_template(tmpl); + } + return tmpl; +} + +void AsyncWrap::Initialize(Local target, + Local unused, + Local context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + Isolate* isolate = env->isolate(); + HandleScope scope(isolate); + + env->SetMethod(target, "setupHooks", SetupHooks); + env->SetMethod(target, "setCallbackTrampoline", SetCallbackTrampoline); + env->SetMethod(target, "pushAsyncContext", PushAsyncContext); + env->SetMethod(target, "popAsyncContext", PopAsyncContext); + env->SetMethod(target, "executionAsyncResource", ExecutionAsyncResource); + env->SetMethod(target, "clearAsyncIdStack", ClearAsyncIdStack); + env->SetMethod(target, "queueDestroyAsyncId", QueueDestroyAsyncId); + env->SetMethod(target, "setPromiseHooks", SetPromiseHooks); + env->SetMethod(target, "registerDestroyHook", RegisterDestroyHook); + + PropertyAttribute ReadOnlyDontDelete = + static_cast(ReadOnly | DontDelete); + +#define FORCE_SET_TARGET_FIELD(obj, str, field) \ + (obj)->DefineOwnProperty(context, \ + FIXED_ONE_BYTE_STRING(isolate, str), \ + field, \ + ReadOnlyDontDelete).FromJust() + + // Attach the uint32_t[] where each slot contains the count of the number of + // callbacks waiting to be called on a particular event. It can then be + // incremented/decremented from JS quickly to communicate to C++ if there are + // any callbacks waiting to be called. + FORCE_SET_TARGET_FIELD(target, + "async_hook_fields", + env->async_hooks()->fields().GetJSArray()); + + // The following v8::Float64Array has 5 fields. These fields are shared in + // this way to allow JS and C++ to read/write each value as quickly as + // possible. The fields are represented as follows: + // + // kAsyncIdCounter: Maintains the state of the next unique id to be assigned. + // + // kDefaultTriggerAsyncId: Write the id of the resource responsible for a + // handle's creation just before calling the new handle's constructor. + // After the new handle is constructed kDefaultTriggerAsyncId is set back + // to kInvalidAsyncId. + FORCE_SET_TARGET_FIELD(target, + "async_id_fields", + env->async_hooks()->async_id_fields().GetJSArray()); + + FORCE_SET_TARGET_FIELD(target, + "execution_async_resources", + env->async_hooks()->js_execution_async_resources()); + + target->Set(context, + env->async_ids_stack_string(), + env->async_hooks()->async_ids_stack().GetJSArray()).Check(); + + Local constants = Object::New(isolate); +#define SET_HOOKS_CONSTANT(name) \ + FORCE_SET_TARGET_FIELD( \ + constants, #name, Integer::New(isolate, AsyncHooks::name)) + + SET_HOOKS_CONSTANT(kInit); + SET_HOOKS_CONSTANT(kBefore); + SET_HOOKS_CONSTANT(kAfter); + SET_HOOKS_CONSTANT(kDestroy); + SET_HOOKS_CONSTANT(kPromiseResolve); + SET_HOOKS_CONSTANT(kTotals); + SET_HOOKS_CONSTANT(kCheck); + SET_HOOKS_CONSTANT(kExecutionAsyncId); + SET_HOOKS_CONSTANT(kTriggerAsyncId); + SET_HOOKS_CONSTANT(kAsyncIdCounter); + SET_HOOKS_CONSTANT(kDefaultTriggerAsyncId); + SET_HOOKS_CONSTANT(kUsesExecutionAsyncResource); + SET_HOOKS_CONSTANT(kStackLength); +#undef SET_HOOKS_CONSTANT + FORCE_SET_TARGET_FIELD(target, "constants", constants); + + Local async_providers = Object::New(isolate); +#define V(p) \ + FORCE_SET_TARGET_FIELD( \ + async_providers, #p, Integer::New(isolate, AsyncWrap::PROVIDER_ ## p)); + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V + FORCE_SET_TARGET_FIELD(target, "Providers", async_providers); + +#undef FORCE_SET_TARGET_FIELD + + env->set_async_hooks_init_function(Local()); + env->set_async_hooks_before_function(Local()); + env->set_async_hooks_after_function(Local()); + env->set_async_hooks_destroy_function(Local()); + env->set_async_hooks_promise_resolve_function(Local()); + env->set_async_hooks_binding(target); + + target->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "AsyncWrap"), + AsyncWrapObject::GetConstructorTemplate(env) + ->GetFunction(env->context()).ToLocalChecked()).Check(); +} + +AsyncWrap::AsyncWrap(Environment* env, + Local object, + ProviderType provider, + double execution_async_id) + : AsyncWrap(env, object, provider, execution_async_id, false) {} + +AsyncWrap::AsyncWrap(Environment* env, + Local object, + ProviderType provider, + double execution_async_id, + bool silent) + : AsyncWrap(env, object) { + CHECK_NE(provider, PROVIDER_NONE); + provider_type_ = provider; + + // Use AsyncReset() call to execute the init() callbacks. + AsyncReset(object, execution_async_id, silent); + init_hook_ran_ = true; +} + +AsyncWrap::AsyncWrap(Environment* env, + Local object, + ProviderType provider, + double execution_async_id, + double trigger_async_id) + : AsyncWrap(env, object, provider, execution_async_id, true) { + trigger_async_id_ = trigger_async_id; +} + +AsyncWrap::AsyncWrap(Environment* env, Local object) + : BaseObject(env, object) { +} + +// This method is necessary to work around one specific problem: +// Before the init() hook runs, if there is one, the BaseObject() constructor +// registers this object with the Environment for finalization and debugging +// purposes. +// If the Environment decides to inspect this object for debugging, it tries to +// call virtual methods on this object that are only (meaningfully) implemented +// by the subclasses of AsyncWrap. +// This could, with bad luck, happen during the AsyncWrap() constructor, +// because we run JS code as part of it and that in turn can lead to a heapdump +// being taken, either through the inspector or our programmatic API for it. +// The object being initialized is not fully constructed at that point, and +// in particular its virtual function table points to the AsyncWrap one +// (as the subclass constructor has not yet begun execution at that point). +// This means that the functions that are used for heap dump memory tracking +// are not yet available, and trying to call them would crash the process. +// We use this particular `IsDoneInitializing()` method to tell the Environment +// that such debugging methods are not yet available. +// This may be somewhat unreliable when it comes to future changes, because +// at this point it *only* protects AsyncWrap subclasses, and *only* for cases +// where heap dumps are being taken while the init() hook is on the call stack. +// For now, it seems like the best solution, though. +bool AsyncWrap::IsDoneInitializing() const { + return init_hook_ran_; +} + +AsyncWrap::~AsyncWrap() { + EmitTraceEventDestroy(); + EmitDestroy(true /* from gc */); +} + +void AsyncWrap::EmitTraceEventDestroy() { + switch (provider_type()) { + #define V(PROVIDER) \ + case PROVIDER_ ## PROVIDER: \ + TRACE_EVENT_NESTABLE_ASYNC_END0( \ + TRACING_CATEGORY_NODE1(async_hooks), \ + #PROVIDER, static_cast(get_async_id())); \ + break; + NODE_ASYNC_PROVIDER_TYPES(V) + #undef V + default: + UNREACHABLE(); + } +} + +void AsyncWrap::EmitDestroy(Environment* env, double async_id) { + if (env->async_hooks()->fields()[AsyncHooks::kDestroy] == 0 || + !env->can_call_into_js()) { + return; + } + + if (env->destroy_async_id_list()->empty()) { + env->SetImmediate(&DestroyAsyncIdsCallback, CallbackFlags::kUnrefed); + } + + // If the list gets very large empty it faster using a Microtask. + // Microtasks can't be added in GC context therefore we use an + // interrupt to get this Microtask scheduled as fast as possible. + if (env->destroy_async_id_list()->size() == 16384) { + env->RequestInterrupt([](Environment* env) { + env->isolate()->EnqueueMicrotask( + [](void* arg) { + DestroyAsyncIdsCallback(static_cast(arg)); + }, env); + }); + } + + env->destroy_async_id_list()->push_back(async_id); +} + +// Generalized call for both the constructor and for handles that are pooled +// and reused over their lifetime. This way a new uid can be assigned when +// the resource is pulled out of the pool and put back into use. +void AsyncWrap::AsyncReset(Local resource, double execution_async_id, + bool silent) { + CHECK_NE(provider_type(), PROVIDER_NONE); + + if (async_id_ != kInvalidAsyncId) { + // This instance was in use before, we have already emitted an init with + // its previous async_id and need to emit a matching destroy for that + // before generating a new async_id. + EmitDestroy(); + } + + // Now we can assign a new async_id_ to this instance. + async_id_ = execution_async_id == kInvalidAsyncId ? env()->new_async_id() + : execution_async_id; + trigger_async_id_ = env()->get_default_trigger_async_id(); + + { + HandleScope handle_scope(env()->isolate()); + Local obj = object(); + CHECK(!obj.IsEmpty()); + if (resource != obj) { + USE(obj->Set(env()->context(), env()->resource_symbol(), resource)); + } + } + + switch (provider_type()) { +#define V(PROVIDER) \ + case PROVIDER_ ## PROVIDER: \ + if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( \ + TRACING_CATEGORY_NODE1(async_hooks))) { \ + auto data = tracing::TracedValue::Create(); \ + data->SetInteger("executionAsyncId", \ + static_cast(env()->execution_async_id())); \ + data->SetInteger("triggerAsyncId", \ + static_cast(get_trigger_async_id())); \ + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( \ + TRACING_CATEGORY_NODE1(async_hooks), \ + #PROVIDER, static_cast(get_async_id()), \ + "data", std::move(data)); \ + } \ + break; + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V + default: + UNREACHABLE(); + } + + if (silent) return; + + EmitAsyncInit(env(), resource, + env()->async_hooks()->provider_string(provider_type()), + async_id_, trigger_async_id_); +} + + +void AsyncWrap::EmitAsyncInit(Environment* env, + Local object, + Local type, + double async_id, + double trigger_async_id) { + CHECK(!object.IsEmpty()); + CHECK(!type.IsEmpty()); + AsyncHooks* async_hooks = env->async_hooks(); + + // Nothing to execute, so can continue normally. + if (async_hooks->fields()[AsyncHooks::kInit] == 0) { + return; + } + + HandleScope scope(env->isolate()); + Local init_fn = env->async_hooks_init_function(); + + Local argv[] = { + Number::New(env->isolate(), async_id), + type, + Number::New(env->isolate(), trigger_async_id), + object, + }; + + TryCatchScope try_catch(env, TryCatchScope::CatchMode::kFatal); + USE(init_fn->Call(env->context(), object, arraysize(argv), argv)); +} + + +MaybeLocal AsyncWrap::MakeCallback(const Local cb, + int argc, + Local* argv) { + EmitTraceEventBefore(); + + ProviderType provider = provider_type(); + async_context context { get_async_id(), get_trigger_async_id() }; + MaybeLocal ret = InternalMakeCallback( + env(), object(), object(), cb, argc, argv, context); + + // This is a static call with cached values because the `this` object may + // no longer be alive at this point. + EmitTraceEventAfter(provider, context.async_id); + + return ret; +} + +std::string AsyncWrap::MemoryInfoName() const { + return provider_names[provider_type()]; +} + +std::string AsyncWrap::diagnostic_name() const { + return MemoryInfoName() + " (" + std::to_string(env()->thread_id()) + ":" + + std::to_string(static_cast(async_id_)) + ")"; +} + +Local AsyncWrap::GetOwner() { + return GetOwner(env(), object()); +} + +Local AsyncWrap::GetOwner(Environment* env, Local obj) { + EscapableHandleScope handle_scope(env->isolate()); + CHECK(!obj.IsEmpty()); + + TryCatchScope ignore_exceptions(env); + while (true) { + Local owner; + if (!obj->Get(env->context(), + env->owner_symbol()).ToLocal(&owner) || + !owner->IsObject()) { + return handle_scope.Escape(obj); + } + + obj = owner.As(); + } +} + +} // namespace node + +NODE_MODULE_CONTEXT_AWARE_INTERNAL(async_wrap, node::AsyncWrap::Initialize) diff --git a/third_party/node/src/async_wrap.h b/third_party/node/src/async_wrap.h new file mode 100644 index 000000000..71012dd09 --- /dev/null +++ b/third_party/node/src/async_wrap.h @@ -0,0 +1,235 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_ASYNC_WRAP_H_ +#define SRC_ASYNC_WRAP_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "base_object.h" +#include "v8.h" + +#include + +namespace node { + +#define NODE_ASYNC_NON_CRYPTO_PROVIDER_TYPES(V) \ + V(NONE) \ + V(DIRHANDLE) \ + V(DNSCHANNEL) \ + V(ELDHISTOGRAM) \ + V(FILEHANDLE) \ + V(FILEHANDLECLOSEREQ) \ + V(FIXEDSIZEBLOBCOPY) \ + V(FSEVENTWRAP) \ + V(FSREQCALLBACK) \ + V(FSREQPROMISE) \ + V(GETADDRINFOREQWRAP) \ + V(GETNAMEINFOREQWRAP) \ + V(HEAPSNAPSHOT) \ + V(HTTP2SESSION) \ + V(HTTP2STREAM) \ + V(HTTP2PING) \ + V(HTTP2SETTINGS) \ + V(HTTPINCOMINGMESSAGE) \ + V(HTTPCLIENTREQUEST) \ + V(JSSTREAM) \ + V(JSUDPWRAP) \ + V(MESSAGEPORT) \ + V(PIPECONNECTWRAP) \ + V(PIPESERVERWRAP) \ + V(PIPEWRAP) \ + V(PROCESSWRAP) \ + V(PROMISE) \ + V(QUERYWRAP) \ + V(SHUTDOWNWRAP) \ + V(SIGNALWRAP) \ + V(STATWATCHER) \ + V(STREAMPIPE) \ + V(TCPCONNECTWRAP) \ + V(TCPSERVERWRAP) \ + V(TCPWRAP) \ + V(TTYWRAP) \ + V(UDPSENDWRAP) \ + V(UDPWRAP) \ + V(SIGINTWATCHDOG) \ + V(WORKER) \ + V(WORKERHEAPSNAPSHOT) \ + V(WRITEWRAP) \ + V(ZLIB) + +#if HAVE_OPENSSL +#define NODE_ASYNC_CRYPTO_PROVIDER_TYPES(V) \ + V(PBKDF2REQUEST) \ + V(KEYPAIRGENREQUEST) \ + V(RANDOMBYTESREQUEST) \ + V(SCRYPTREQUEST) \ + V(TLSWRAP) +#else +#define NODE_ASYNC_CRYPTO_PROVIDER_TYPES(V) +#endif // HAVE_OPENSSL + +#if HAVE_INSPECTOR +#define NODE_ASYNC_INSPECTOR_PROVIDER_TYPES(V) \ + V(INSPECTORJSBINDING) +#else +#define NODE_ASYNC_INSPECTOR_PROVIDER_TYPES(V) +#endif // HAVE_INSPECTOR + +#define NODE_ASYNC_PROVIDER_TYPES(V) \ + NODE_ASYNC_NON_CRYPTO_PROVIDER_TYPES(V) \ + NODE_ASYNC_CRYPTO_PROVIDER_TYPES(V) \ + NODE_ASYNC_INSPECTOR_PROVIDER_TYPES(V) + +class Environment; +class DestroyParam; + +class AsyncWrap : public BaseObject { + public: + enum ProviderType { +#define V(PROVIDER) \ + PROVIDER_ ## PROVIDER, + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V + PROVIDERS_LENGTH, + }; + + AsyncWrap(Environment* env, + v8::Local object, + ProviderType provider, + double execution_async_id = kInvalidAsyncId); + + // This constructor creates a reusable instance where user is responsible + // to call set_provider_type() and AsyncReset() before use. + AsyncWrap(Environment* env, v8::Local object); + + ~AsyncWrap() override; + + AsyncWrap() = delete; + + static constexpr double kInvalidAsyncId = -1; + + static v8::Local GetConstructorTemplate( + Environment* env); + + static void Initialize(v8::Local target, + v8::Local unused, + v8::Local context, + void* priv); + + static void GetAsyncId(const v8::FunctionCallbackInfo& args); + static void PushAsyncContext(const v8::FunctionCallbackInfo& args); + static void PopAsyncContext(const v8::FunctionCallbackInfo& args); + static void ExecutionAsyncResource( + const v8::FunctionCallbackInfo& args); + static void ClearAsyncIdStack( + const v8::FunctionCallbackInfo& args); + static void AsyncReset(const v8::FunctionCallbackInfo& args); + static void GetProviderType(const v8::FunctionCallbackInfo& args); + static void QueueDestroyAsyncId( + const v8::FunctionCallbackInfo& args); + static void SetCallbackTrampoline( + const v8::FunctionCallbackInfo& args); + + static void EmitAsyncInit(Environment* env, + v8::Local object, + v8::Local type, + double async_id, + double trigger_async_id); + + static void EmitDestroy(Environment* env, double async_id); + static void EmitBefore(Environment* env, double async_id); + static void EmitAfter(Environment* env, double async_id); + static void EmitPromiseResolve(Environment* env, double async_id); + + void EmitDestroy(bool from_gc = false); + + void EmitTraceEventBefore(); + static void EmitTraceEventAfter(ProviderType type, double async_id); + void EmitTraceEventDestroy(); + + static void DestroyAsyncIdsCallback(Environment* env); + + inline ProviderType provider_type() const; + inline ProviderType set_provider_type(ProviderType provider); + + inline double get_async_id() const; + inline double get_trigger_async_id() const; + + void AsyncReset(v8::Local resource, + double execution_async_id = kInvalidAsyncId, + bool silent = false); + + // Only call these within a valid HandleScope. + v8::MaybeLocal MakeCallback(const v8::Local cb, + int argc, + v8::Local* argv); + inline v8::MaybeLocal MakeCallback( + const v8::Local symbol, + int argc, + v8::Local* argv); + inline v8::MaybeLocal MakeCallback( + const v8::Local symbol, + int argc, + v8::Local* argv); + inline v8::MaybeLocal MakeCallback( + const v8::Local symbol, + int argc, + v8::Local* argv); + + virtual std::string diagnostic_name() const; + std::string MemoryInfoName() const override; + + static void WeakCallback(const v8::WeakCallbackInfo &info); + + // Returns the object that 'owns' an async wrap. For example, for a + // TCP connection handle, this is the corresponding net.Socket. + v8::Local GetOwner(); + static v8::Local GetOwner(Environment* env, + v8::Local obj); + + bool IsDoneInitializing() const override; + + private: + friend class PromiseWrap; + + AsyncWrap(Environment* env, + v8::Local promise, + ProviderType provider, + double execution_async_id, + bool silent); + AsyncWrap(Environment* env, + v8::Local promise, + ProviderType provider, + double execution_async_id, + double trigger_async_id); + ProviderType provider_type_ = PROVIDER_NONE; + bool init_hook_ran_ = false; + // Because the values may be Reset(), cannot be made const. + double async_id_ = kInvalidAsyncId; + double trigger_async_id_; +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_ASYNC_WRAP_H_ diff --git a/third_party/node/src/base64-inl.h b/third_party/node/src/base64-inl.h new file mode 100644 index 000000000..1b6cdd93f --- /dev/null +++ b/third_party/node/src/base64-inl.h @@ -0,0 +1,189 @@ +#ifndef SRC_BASE64_INL_H_ +#define SRC_BASE64_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "base64.h" +#include "util.h" + +namespace node { + +extern const int8_t unbase64_table[256]; + + +inline static int8_t unbase64(uint8_t x) { + return unbase64_table[x]; +} + + +inline uint32_t ReadUint32BE(const unsigned char* p) { + return static_cast(p[0] << 24U) | + static_cast(p[1] << 16U) | + static_cast(p[2] << 8U) | + static_cast(p[3]); +} + +#ifdef _MSC_VER +#pragma warning(push) +// MSVC C4003: not enough actual parameters for macro 'identifier' +#pragma warning(disable : 4003) +#endif + +template +bool base64_decode_group_slow(char* const dst, const size_t dstlen, + const TypeName* const src, const size_t srclen, + size_t* const i, size_t* const k) { + uint8_t hi; + uint8_t lo; +#define V(expr) \ + for (;;) { \ + const uint8_t c = static_cast(src[*i]); \ + lo = unbase64(c); \ + *i += 1; \ + if (lo < 64) break; /* Legal character. */ \ + if (c == '=' || *i >= srclen) return false; /* Stop decoding. */ \ + } \ + expr; \ + if (*i >= srclen) return false; \ + if (*k >= dstlen) return false; \ + hi = lo; + V(/* Nothing. */); + V(dst[(*k)++] = ((hi & 0x3F) << 2) | ((lo & 0x30) >> 4)); + V(dst[(*k)++] = ((hi & 0x0F) << 4) | ((lo & 0x3C) >> 2)); + V(dst[(*k)++] = ((hi & 0x03) << 6) | ((lo & 0x3F) >> 0)); +#undef V + return true; // Continue decoding. +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +size_t base64_decode_fast(char* const dst, const size_t dstlen, + const TypeName* const src, const size_t srclen, + const size_t decoded_size) { + const size_t available = dstlen < decoded_size ? dstlen : decoded_size; + const size_t max_k = available / 3 * 3; + size_t max_i = srclen / 4 * 4; + size_t i = 0; + size_t k = 0; + while (i < max_i && k < max_k) { + const unsigned char txt[] = { + static_cast(unbase64(static_cast(src[i + 0]))), + static_cast(unbase64(static_cast(src[i + 1]))), + static_cast(unbase64(static_cast(src[i + 2]))), + static_cast(unbase64(static_cast(src[i + 3]))), + }; + + const uint32_t v = ReadUint32BE(txt); + // If MSB is set, input contains whitespace or is not valid base64. + if (v & 0x80808080) { + if (!base64_decode_group_slow(dst, dstlen, src, srclen, &i, &k)) + return k; + max_i = i + (srclen - i) / 4 * 4; // Align max_i again. + } else { + dst[k + 0] = ((v >> 22) & 0xFC) | ((v >> 20) & 0x03); + dst[k + 1] = ((v >> 12) & 0xF0) | ((v >> 10) & 0x0F); + dst[k + 2] = ((v >> 2) & 0xC0) | ((v >> 0) & 0x3F); + i += 4; + k += 3; + } + } + if (i < srclen && k < dstlen) { + base64_decode_group_slow(dst, dstlen, src, srclen, &i, &k); + } + return k; +} + + +template +size_t base64_decoded_size(const TypeName* src, size_t size) { + // 1-byte input cannot be decoded + if (size < 2) + return 0; + + if (src[size - 1] == '=') { + size--; + if (src[size - 1] == '=') + size--; + } + return base64_decoded_size_fast(size); +} + + +template +size_t base64_decode(char* const dst, const size_t dstlen, + const TypeName* const src, const size_t srclen) { + const size_t decoded_size = base64_decoded_size(src, srclen); + return base64_decode_fast(dst, dstlen, src, srclen, decoded_size); +} + + +inline size_t base64_encode(const char* src, + size_t slen, + char* dst, + size_t dlen, + Base64Mode mode) { + // We know how much we'll write, just make sure that there's space. + CHECK(dlen >= base64_encoded_size(slen, mode) && + "not enough space provided for base64 encode"); + + dlen = base64_encoded_size(slen, mode); + + unsigned a; + unsigned b; + unsigned c; + unsigned i; + unsigned k; + unsigned n; + + const char* table = base64_select_table(mode); + + i = 0; + k = 0; + n = slen / 3 * 3; + + while (i < n) { + a = src[i + 0] & 0xff; + b = src[i + 1] & 0xff; + c = src[i + 2] & 0xff; + + dst[k + 0] = table[a >> 2]; + dst[k + 1] = table[((a & 3) << 4) | (b >> 4)]; + dst[k + 2] = table[((b & 0x0f) << 2) | (c >> 6)]; + dst[k + 3] = table[c & 0x3f]; + + i += 3; + k += 4; + } + + switch (slen - n) { + case 1: + a = src[i + 0] & 0xff; + dst[k + 0] = table[a >> 2]; + dst[k + 1] = table[(a & 3) << 4]; + if (mode == Base64Mode::NORMAL) { + dst[k + 2] = '='; + dst[k + 3] = '='; + } + break; + case 2: + a = src[i + 0] & 0xff; + b = src[i + 1] & 0xff; + dst[k + 0] = table[a >> 2]; + dst[k + 1] = table[((a & 3) << 4) | (b >> 4)]; + dst[k + 2] = table[(b & 0x0f) << 2]; + if (mode == Base64Mode::NORMAL) + dst[k + 3] = '='; + break; + } + + return dlen; +} + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_BASE64_INL_H_ diff --git a/third_party/node/src/base64.h b/third_party/node/src/base64.h new file mode 100644 index 000000000..cf6e82539 --- /dev/null +++ b/third_party/node/src/base64.h @@ -0,0 +1,69 @@ +#ifndef SRC_BASE64_H_ +#define SRC_BASE64_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "util.h" + +#include +#include +#include + +namespace node { +//// Base 64 //// + +enum class Base64Mode { + NORMAL, + URL +}; + +static constexpr char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static constexpr char base64_table_url[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_"; + +static inline const char* base64_select_table(Base64Mode mode) { + switch (mode) { + case Base64Mode::NORMAL: return base64_table; + case Base64Mode::URL: return base64_table_url; + default: UNREACHABLE(); + } +} + +static inline constexpr size_t base64_encoded_size( + size_t size, + Base64Mode mode = Base64Mode::NORMAL) { + return mode == Base64Mode::NORMAL + ? ((size + 2) / 3 * 4) + : std::ceil(static_cast(size * 4) / 3); +} + +// Doesn't check for padding at the end. Can be 1-2 bytes over. +static inline constexpr size_t base64_decoded_size_fast(size_t size) { + // 1-byte input cannot be decoded + return size > 1 ? (size / 4) * 3 + (size % 4 + 1) / 2 : 0; +} + +inline uint32_t ReadUint32BE(const unsigned char* p); + +template +size_t base64_decoded_size(const TypeName* src, size_t size); + +template +size_t base64_decode(char* const dst, const size_t dstlen, + const TypeName* const src, const size_t srclen); + +inline size_t base64_encode(const char* src, + size_t slen, + char* dst, + size_t dlen, + Base64Mode mode = Base64Mode::NORMAL); +} // namespace node + + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_BASE64_H_ diff --git a/third_party/node/src/base_object-inl.h b/third_party/node/src/base_object-inl.h new file mode 100644 index 000000000..43bcdc640 --- /dev/null +++ b/third_party/node/src/base_object-inl.h @@ -0,0 +1,378 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_BASE_OBJECT_INL_H_ +#define SRC_BASE_OBJECT_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "base_object.h" +#include "env-inl.h" +#include "util.h" + +#if (__GNUC__ >= 8) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif +#include "v8.h" +#if (__GNUC__ >= 8) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +namespace node { + +BaseObject::BaseObject(Environment* env, v8::Local object) + : persistent_handle_(env->isolate(), object), env_(env) { + CHECK_EQ(false, object.IsEmpty()); + CHECK_GT(object->InternalFieldCount(), 0); + object->SetAlignedPointerInInternalField( + BaseObject::kSlot, + static_cast(this)); + env->AddCleanupHook(DeleteMe, static_cast(this)); + env->modify_base_object_count(1); +} + +BaseObject::~BaseObject() { + env()->modify_base_object_count(-1); + env()->RemoveCleanupHook(DeleteMe, static_cast(this)); + + if (UNLIKELY(has_pointer_data())) { + PointerData* metadata = pointer_data(); + CHECK_EQ(metadata->strong_ptr_count, 0); + metadata->self = nullptr; + if (metadata->weak_ptr_count == 0) + delete metadata; + } + + if (persistent_handle_.IsEmpty()) { + // This most likely happened because the weak callback below cleared it. + return; + } + + { + v8::HandleScope handle_scope(env()->isolate()); + object()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); + } +} + +void BaseObject::Detach() { + CHECK_GT(pointer_data()->strong_ptr_count, 0); + pointer_data()->is_detached = true; +} + +v8::Global& BaseObject::persistent() { + return persistent_handle_; +} + + +v8::Local BaseObject::object() const { + return PersistentToLocal::Default(env()->isolate(), persistent_handle_); +} + +v8::Local BaseObject::object(v8::Isolate* isolate) const { + v8::Local handle = object(); + + DCHECK_EQ(handle->CreationContext()->GetIsolate(), isolate); + DCHECK_EQ(env()->isolate(), isolate); + + return handle; +} + +Environment* BaseObject::env() const { + return env_; +} + +BaseObject* BaseObject::FromJSObject(v8::Local value) { + v8::Local obj = value.As(); + DCHECK_GE(obj->InternalFieldCount(), BaseObject::kSlot); + return static_cast( + obj->GetAlignedPointerFromInternalField(BaseObject::kSlot)); +} + + +template +T* BaseObject::FromJSObject(v8::Local object) { + return static_cast(FromJSObject(object)); +} + + +void BaseObject::MakeWeak() { + if (has_pointer_data()) { + pointer_data()->wants_weak_jsobj = true; + if (pointer_data()->strong_ptr_count > 0) return; + } + + persistent_handle_.SetWeak( + this, + [](const v8::WeakCallbackInfo& data) { + BaseObject* obj = data.GetParameter(); + // Clear the persistent handle so that ~BaseObject() doesn't attempt + // to mess with internal fields, since the JS object may have + // transitioned into an invalid state. + // Refs: https://github.com/nodejs/node/issues/18897 + obj->persistent_handle_.Reset(); + CHECK_IMPLIES(obj->has_pointer_data(), + obj->pointer_data()->strong_ptr_count == 0); + obj->OnGCCollect(); + }, v8::WeakCallbackType::kParameter); +} + +void BaseObject::OnGCCollect() { + delete this; +} + +void BaseObject::ClearWeak() { + if (has_pointer_data()) + pointer_data()->wants_weak_jsobj = false; + + persistent_handle_.ClearWeak(); +} + +bool BaseObject::IsWeakOrDetached() const { + if (persistent_handle_.IsWeak()) return true; + + if (!has_pointer_data()) return false; + const PointerData* pd = const_cast(this)->pointer_data(); + return pd->wants_weak_jsobj || pd->is_detached; +} + +v8::Local +BaseObject::MakeLazilyInitializedJSTemplate(Environment* env) { + auto constructor = [](const v8::FunctionCallbackInfo& args) { + DCHECK(args.IsConstructCall()); + DCHECK_GT(args.This()->InternalFieldCount(), 0); + args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); + }; + + v8::Local t = env->NewFunctionTemplate(constructor); + t->Inherit(BaseObject::GetConstructorTemplate(env)); + t->InstanceTemplate()->SetInternalFieldCount( + BaseObject::kInternalFieldCount); + return t; +} + +template +void BaseObject::InternalFieldGet( + v8::Local property, + const v8::PropertyCallbackInfo& info) { + info.GetReturnValue().Set(info.This()->GetInternalField(Field)); +} + +template +void BaseObject::InternalFieldSet(v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info) { + // This could be e.g. value->IsFunction(). + CHECK(((*value)->*typecheck)()); + info.This()->SetInternalField(Field, value); +} + +bool BaseObject::has_pointer_data() const { + return pointer_data_ != nullptr; +} + +BaseObject::PointerData* BaseObject::pointer_data() { + if (!has_pointer_data()) { + PointerData* metadata = new PointerData(); + metadata->wants_weak_jsobj = persistent_handle_.IsWeak(); + metadata->self = this; + pointer_data_ = metadata; + } + CHECK(has_pointer_data()); + return pointer_data_; +} + +void BaseObject::decrease_refcount() { + CHECK(has_pointer_data()); + PointerData* metadata = pointer_data(); + CHECK_GT(metadata->strong_ptr_count, 0); + unsigned int new_refcount = --metadata->strong_ptr_count; + if (new_refcount == 0) { + if (metadata->is_detached) { + OnGCCollect(); + } else if (metadata->wants_weak_jsobj && !persistent_handle_.IsEmpty()) { + MakeWeak(); + } + } +} + +void BaseObject::increase_refcount() { + unsigned int prev_refcount = pointer_data()->strong_ptr_count++; + if (prev_refcount == 0 && !persistent_handle_.IsEmpty()) + persistent_handle_.ClearWeak(); +} + +template +BaseObject::PointerData* +BaseObjectPtrImpl::pointer_data() const { + if (kIsWeak) { + return data_.pointer_data; + } + if (get_base_object() == nullptr) { + return nullptr; + } + return get_base_object()->pointer_data(); +} + +template +BaseObject* BaseObjectPtrImpl::get_base_object() const { + if (kIsWeak) { + if (pointer_data() == nullptr) { + return nullptr; + } + return pointer_data()->self; + } + return data_.target; +} + +template +BaseObjectPtrImpl::~BaseObjectPtrImpl() { + if (kIsWeak) { + if (pointer_data() != nullptr && + --pointer_data()->weak_ptr_count == 0 && + pointer_data()->self == nullptr) { + delete pointer_data(); + } + } else if (get() != nullptr) { + get()->decrease_refcount(); + } +} + +template +BaseObjectPtrImpl::BaseObjectPtrImpl() { + data_.target = nullptr; +} + +template +BaseObjectPtrImpl::BaseObjectPtrImpl(T* target) + : BaseObjectPtrImpl() { + if (target == nullptr) return; + if (kIsWeak) { + data_.pointer_data = target->pointer_data(); + CHECK_NOT_NULL(pointer_data()); + pointer_data()->weak_ptr_count++; + } else { + data_.target = target; + CHECK_NOT_NULL(pointer_data()); + get()->increase_refcount(); + } +} + +template +template +BaseObjectPtrImpl::BaseObjectPtrImpl( + const BaseObjectPtrImpl& other) + : BaseObjectPtrImpl(other.get()) {} + +template +BaseObjectPtrImpl::BaseObjectPtrImpl(const BaseObjectPtrImpl& other) + : BaseObjectPtrImpl(other.get()) {} + +template +template +BaseObjectPtrImpl& BaseObjectPtrImpl::operator=( + const BaseObjectPtrImpl& other) { + if (other.get() == get()) return *this; + this->~BaseObjectPtrImpl(); + return *new (this) BaseObjectPtrImpl(other); +} + +template +BaseObjectPtrImpl& BaseObjectPtrImpl::operator=( + const BaseObjectPtrImpl& other) { + if (other.get() == get()) return *this; + this->~BaseObjectPtrImpl(); + return *new (this) BaseObjectPtrImpl(other); +} + +template +BaseObjectPtrImpl::BaseObjectPtrImpl(BaseObjectPtrImpl&& other) + : data_(other.data_) { + if (kIsWeak) + other.data_.target = nullptr; + else + other.data_.pointer_data = nullptr; +} + +template +BaseObjectPtrImpl& BaseObjectPtrImpl::operator=( + BaseObjectPtrImpl&& other) { + if (&other == this) return *this; + this->~BaseObjectPtrImpl(); + return *new (this) BaseObjectPtrImpl(std::move(other)); +} + +template +void BaseObjectPtrImpl::reset(T* ptr) { + *this = BaseObjectPtrImpl(ptr); +} + +template +T* BaseObjectPtrImpl::get() const { + return static_cast(get_base_object()); +} + +template +T& BaseObjectPtrImpl::operator*() const { + return *get(); +} + +template +T* BaseObjectPtrImpl::operator->() const { + return get(); +} + +template +BaseObjectPtrImpl::operator bool() const { + return get() != nullptr; +} + +template +template +bool BaseObjectPtrImpl::operator ==( + const BaseObjectPtrImpl& other) const { + return get() == other.get(); +} + +template +template +bool BaseObjectPtrImpl::operator !=( + const BaseObjectPtrImpl& other) const { + return get() != other.get(); +} + +template +BaseObjectPtr MakeBaseObject(Args&&... args) { + return BaseObjectPtr(new T(std::forward(args)...)); +} + +template +BaseObjectPtr MakeDetachedBaseObject(Args&&... args) { + BaseObjectPtr target = MakeBaseObject(std::forward(args)...); + target->Detach(); + return target; +} + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_BASE_OBJECT_INL_H_ diff --git a/third_party/node/src/base_object.h b/third_party/node/src/base_object.h new file mode 100644 index 000000000..b61e19dff --- /dev/null +++ b/third_party/node/src/base_object.h @@ -0,0 +1,290 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_BASE_OBJECT_H_ +#define SRC_BASE_OBJECT_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include // std::remove_reference +#include "memory_tracker.h" +#include "v8.h" + +namespace node { + +class Environment; +template +class BaseObjectPtrImpl; + +namespace worker { +class TransferData; +} + +class BaseObject : public MemoryRetainer { + public: + enum InternalFields { kSlot, kInternalFieldCount }; + + // Associates this object with `object`. It uses the 0th internal field for + // that, and in particular aborts if there is no such field. + inline BaseObject(Environment* env, v8::Local object); + inline ~BaseObject() override; + + BaseObject() = delete; + + // Returns the wrapped object. Returns an empty handle when + // persistent.IsEmpty() is true. + inline v8::Local object() const; + + // Same as the above, except it additionally verifies that this object + // is associated with the passed Isolate in debug mode. + inline v8::Local object(v8::Isolate* isolate) const; + + inline v8::Global& persistent(); + + inline Environment* env() const; + + // Get a BaseObject* pointer, or subclass pointer, for the JS object that + // was also passed to the `BaseObject()` constructor initially. + // This may return `nullptr` if the C++ object has not been constructed yet, + // e.g. when the JS object used `MakeLazilyInitializedJSTemplate`. + static inline BaseObject* FromJSObject(v8::Local object); + template + static inline T* FromJSObject(v8::Local object); + + // Make the `v8::Global` a weak reference and, `delete` this object once + // the JS object has been garbage collected and there are no (strong) + // BaseObjectPtr references to it. + inline void MakeWeak(); + + // Undo `MakeWeak()`, i.e. turn this into a strong reference that is a GC + // root and will not be touched by the garbage collector. + inline void ClearWeak(); + + // Reports whether this BaseObject is using a weak reference or detached, + // i.e. whether is can be deleted by GC once no strong BaseObjectPtrs refer + // to it anymore. + inline bool IsWeakOrDetached() const; + + // Utility to create a FunctionTemplate with one internal field (used for + // the `BaseObject*` pointer) and a constructor that initializes that field + // to `nullptr`. + static inline v8::Local MakeLazilyInitializedJSTemplate( + Environment* env); + + // Setter/Getter pair for internal fields that can be passed to SetAccessor. + template + static void InternalFieldGet(v8::Local property, + const v8::PropertyCallbackInfo& info); + template + static void InternalFieldSet(v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info); + + // This is a bit of a hack. See the override in async_wrap.cc for details. + virtual bool IsDoneInitializing() const; + + // Can be used to avoid this object keepling itself alive as a GC root + // indefinitely, for example when this object is owned and deleted by another + // BaseObject once that is torn down. This can only be called when there is + // a BaseObjectPtr to this object. + inline void Detach(); + + static v8::Local GetConstructorTemplate( + Environment* env); + + // Interface for transferring BaseObject instances using the .postMessage() + // method of MessagePorts (and, by extension, Workers). + // GetTransferMode() returns a transfer mode that indicates how to deal with + // the current object: + // - kUntransferable: + // No transfer is possible, either because this type of BaseObject does + // not know how to be transferred, or because it is not in a state in + // which it is possible to do so (e.g. because it has already been + // transferred). + // - kTransferable: + // This object can be transferred in a destructive fashion, i.e. will be + // rendered unusable on the sending side of the channel in the process + // of being transferred. (In C++ this would be referred to as movable but + // not copyable.) Objects of this type need to be listed in the + // `transferList` argument of the relevant postMessage() call in order to + // make sure that they are not accidentally destroyed on the sending side. + // TransferForMessaging() will be called to get a representation of the + // object that is used for subsequent deserialization. + // The NestedTransferables() method can be used to transfer other objects + // along with this one, if a situation requires it. + // - kCloneable: + // This object can be cloned without being modified. + // CloneForMessaging() will be called to get a representation of the + // object that is used for subsequent deserialization, unless the + // object is listed in transferList, in which case TransferForMessaging() + // is attempted first. + // After a successful clone, FinalizeTransferRead() is called on the receiving + // end, and can read deserialize JS data possibly serialized by a previous + // FinalizeTransferWrite() call. + enum class TransferMode { + kUntransferable, + kTransferable, + kCloneable + }; + virtual TransferMode GetTransferMode() const; + virtual std::unique_ptr TransferForMessaging(); + virtual std::unique_ptr CloneForMessaging() const; + virtual v8::Maybe>> + NestedTransferables() const; + virtual v8::Maybe FinalizeTransferRead( + v8::Local context, v8::ValueDeserializer* deserializer); + + // Indicates whether this object is expected to use a strong reference during + // a clean process exit (due to an empty event loop). + virtual bool IsNotIndicativeOfMemoryLeakAtExit() const; + + virtual inline void OnGCCollect(); + + private: + v8::Local WrappedObject() const override; + bool IsRootNode() const override; + static void DeleteMe(void* data); + + // persistent_handle_ needs to be at a fixed offset from the start of the + // class because it is used by src/node_postmortem_metadata.cc to calculate + // offsets and generate debug symbols for BaseObject, which assumes that the + // position of members in memory are predictable. For more information please + // refer to `doc/guides/node-postmortem-support.md` + friend int GenDebugSymbols(); + friend class CleanupHookCallback; + template + friend class BaseObjectPtrImpl; + + v8::Global persistent_handle_; + + // Metadata that is associated with this BaseObject if there are BaseObjectPtr + // or BaseObjectWeakPtr references to it. + // This object is deleted when the BaseObject itself is destroyed, and there + // are no weak references to it. + struct PointerData { + // Number of BaseObjectPtr instances that refer to this object. If this + // is non-zero, the BaseObject is always a GC root and will not be destroyed + // during cleanup until the count drops to zero again. + unsigned int strong_ptr_count = 0; + // Number of BaseObjectWeakPtr instances that refer to this object. + unsigned int weak_ptr_count = 0; + // Indicates whether MakeWeak() has been called. + bool wants_weak_jsobj = false; + // Indicates whether Detach() has been called. If that is the case, this + // object will be destroyed once the strong pointer count drops to zero. + bool is_detached = false; + // Reference to the original BaseObject. This is used by weak pointers. + BaseObject* self = nullptr; + }; + + inline bool has_pointer_data() const; + // This creates a PointerData struct if none was associated with this + // BaseObject before. + inline PointerData* pointer_data(); + + // Functions that adjust the strong pointer count. + inline void decrease_refcount(); + inline void increase_refcount(); + + Environment* env_; + PointerData* pointer_data_ = nullptr; +}; + +// Global alias for FromJSObject() to avoid churn. +template +inline T* Unwrap(v8::Local obj) { + return BaseObject::FromJSObject(obj); +} + +#define ASSIGN_OR_RETURN_UNWRAP(ptr, obj, ...) \ + do { \ + *ptr = static_cast::type>( \ + BaseObject::FromJSObject(obj)); \ + if (*ptr == nullptr) return __VA_ARGS__; \ + } while (0) + +// Implementation of a generic strong or weak pointer to a BaseObject. +// If strong, this will keep the target BaseObject alive regardless of other +// circumstances such as the GC or Environment cleanup. +// If weak, destruction behaviour is not affected, but the pointer will be +// reset to nullptr once the BaseObject is destroyed. +// The API matches std::shared_ptr closely. +template +class BaseObjectPtrImpl final { + public: + inline BaseObjectPtrImpl(); + inline ~BaseObjectPtrImpl(); + inline explicit BaseObjectPtrImpl(T* target); + + // Copy and move constructors. Note that the templated version is not a copy + // or move constructor in the C++ sense of the word, so an identical + // untemplated version is provided. + template + inline BaseObjectPtrImpl(const BaseObjectPtrImpl& other); + inline BaseObjectPtrImpl(const BaseObjectPtrImpl& other); + template + inline BaseObjectPtrImpl& operator=(const BaseObjectPtrImpl& other); + inline BaseObjectPtrImpl& operator=(const BaseObjectPtrImpl& other); + inline BaseObjectPtrImpl(BaseObjectPtrImpl&& other); + inline BaseObjectPtrImpl& operator=(BaseObjectPtrImpl&& other); + + inline void reset(T* ptr = nullptr); + inline T* get() const; + inline T& operator*() const; + inline T* operator->() const; + inline operator bool() const; + + template + inline bool operator ==(const BaseObjectPtrImpl& other) const; + template + inline bool operator !=(const BaseObjectPtrImpl& other) const; + + private: + union { + BaseObject* target; // Used for strong pointers. + BaseObject::PointerData* pointer_data; // Used for weak pointers. + } data_; + + inline BaseObject* get_base_object() const; + inline BaseObject::PointerData* pointer_data() const; +}; + +template +using BaseObjectPtr = BaseObjectPtrImpl; +template +using BaseObjectWeakPtr = BaseObjectPtrImpl; + +// Create a BaseObject instance and return a pointer to it. +// This variant leaves the object as a GC root by default. +template +inline BaseObjectPtr MakeBaseObject(Args&&... args); +// Create a BaseObject instance and return a pointer to it. +// This variant detaches the object by default, meaning that the caller fully +// owns it, and once the last BaseObjectPtr to it is destroyed, the object +// itself is also destroyed. +template +inline BaseObjectPtr MakeDetachedBaseObject(Args&&... args); + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_BASE_OBJECT_H_ diff --git a/third_party/node/src/callback_queue-inl.h b/third_party/node/src/callback_queue-inl.h new file mode 100644 index 000000000..9e46ae486 --- /dev/null +++ b/third_party/node/src/callback_queue-inl.h @@ -0,0 +1,97 @@ +#ifndef SRC_CALLBACK_QUEUE_INL_H_ +#define SRC_CALLBACK_QUEUE_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "callback_queue.h" + +namespace node { + +template +template +std::unique_ptr::Callback> +CallbackQueue::CreateCallback(Fn&& fn, CallbackFlags::Flags flags) { + return std::make_unique>(std::move(fn), flags); +} + +template +std::unique_ptr::Callback> +CallbackQueue::Shift() { + std::unique_ptr ret = std::move(head_); + if (ret) { + head_ = ret->get_next(); + if (!head_) + tail_ = nullptr; // The queue is now empty. + size_--; + } + return ret; +} + +template +void CallbackQueue::Push(std::unique_ptr cb) { + Callback* prev_tail = tail_; + + size_++; + tail_ = cb.get(); + if (prev_tail != nullptr) + prev_tail->set_next(std::move(cb)); + else + head_ = std::move(cb); +} + +template +void CallbackQueue::ConcatMove(CallbackQueue&& other) { + size_ += other.size_; + if (tail_ != nullptr) + tail_->set_next(std::move(other.head_)); + else + head_ = std::move(other.head_); + tail_ = other.tail_; + other.tail_ = nullptr; + other.size_ = 0; +} + +template +size_t CallbackQueue::size() const { + return size_.load(); +} + +template +CallbackQueue::Callback::Callback(CallbackFlags::Flags flags) + : flags_(flags) {} + +template +CallbackFlags::Flags CallbackQueue::Callback::flags() const { + return flags_; +} + +template +std::unique_ptr::Callback> +CallbackQueue::Callback::get_next() { + return std::move(next_); +} + +template +void CallbackQueue::Callback::set_next( + std::unique_ptr next) { + next_ = std::move(next); +} + +template +template +CallbackQueue::CallbackImpl::CallbackImpl( + Fn&& callback, CallbackFlags::Flags flags) + : Callback(flags), + callback_(std::move(callback)) {} + +template +template +R CallbackQueue::CallbackImpl::Call(Args... args) { + return callback_(std::forward(args)...); +} + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CALLBACK_QUEUE_INL_H_ diff --git a/third_party/node/src/callback_queue.h b/third_party/node/src/callback_queue.h new file mode 100644 index 000000000..e5694d5e1 --- /dev/null +++ b/third_party/node/src/callback_queue.h @@ -0,0 +1,78 @@ +#ifndef SRC_CALLBACK_QUEUE_H_ +#define SRC_CALLBACK_QUEUE_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include + +namespace node { + +namespace CallbackFlags { +enum Flags { + kUnrefed = 0, + kRefed = 1, +}; +} + +// A queue of C++ functions that take Args... as arguments and return R +// (this is similar to the signature of std::function). +// New entries are added using `CreateCallback()`/`Push()`, and removed using +// `Shift()`. +// The `refed` flag is left for easier use in situations in which some of these +// should be run even if nothing else is keeping the event loop alive. +template +class CallbackQueue { + public: + class Callback { + public: + explicit inline Callback(CallbackFlags::Flags flags); + + virtual ~Callback() = default; + virtual R Call(Args... args) = 0; + + inline CallbackFlags::Flags flags() const; + + private: + inline std::unique_ptr get_next(); + inline void set_next(std::unique_ptr next); + + CallbackFlags::Flags flags_; + std::unique_ptr next_; + + friend class CallbackQueue; + }; + + template + inline std::unique_ptr CreateCallback( + Fn&& fn, CallbackFlags::Flags); + + inline std::unique_ptr Shift(); + inline void Push(std::unique_ptr cb); + // ConcatMove adds elements from 'other' to the end of this list, and clears + // 'other' afterwards. + inline void ConcatMove(CallbackQueue&& other); + + // size() is atomic and may be called from any thread. + inline size_t size() const; + + private: + template + class CallbackImpl final : public Callback { + public: + CallbackImpl(Fn&& callback, CallbackFlags::Flags flags); + R Call(Args... args) override; + + private: + Fn callback_; + }; + + std::atomic size_ {0}; + std::unique_ptr head_; + Callback* tail_ = nullptr; +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CALLBACK_QUEUE_H_ diff --git a/third_party/node/src/cares_wrap.cc b/third_party/node/src/cares_wrap.cc new file mode 100644 index 000000000..7f5769569 --- /dev/null +++ b/third_party/node/src/cares_wrap.cc @@ -0,0 +1,1961 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#include "async_wrap-inl.h" +#include "base_object-inl.h" +#include "base64-inl.h" +#include "cares_wrap.h" +#include "env-inl.h" +#include "memory_tracker-inl.h" +#include "node.h" +#include "node_errors.h" +#include "req_wrap-inl.h" +#include "util-inl.h" +#include "v8.h" +#include "uv.h" + +#include +#include +#include +#include +#include + +#ifndef T_CAA +# define T_CAA 257 /* Certification Authority Authorization */ +#endif + +// OpenBSD does not define these +#ifndef AI_ALL +# define AI_ALL 0 +#endif +#ifndef AI_V4MAPPED +# define AI_V4MAPPED 0 +#endif + + +namespace node { +namespace cares_wrap { + +using v8::Array; +using v8::Context; +using v8::EscapableHandleScope; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::HandleScope; +using v8::Int32; +using v8::Integer; +using v8::Isolate; +using v8::Just; +using v8::Local; +using v8::Maybe; +using v8::Nothing; +using v8::Null; +using v8::Object; +using v8::String; +using v8::Value; + +namespace { + +Mutex ares_library_mutex; + +inline uint16_t cares_get_16bit(const unsigned char* p) { + return static_cast(p[0] << 8U) | (static_cast(p[1])); +} + +void ares_poll_cb(uv_poll_t* watcher, int status, int events) { + NodeAresTask* task = ContainerOf(&NodeAresTask::poll_watcher, watcher); + ChannelWrap* channel = task->channel; + + /* Reset the idle timer */ + uv_timer_again(channel->timer_handle()); + + if (status < 0) { + /* An error happened. Just pretend that the socket is both readable and */ + /* writable. */ + ares_process_fd(channel->cares_channel(), task->sock, task->sock); + return; + } + + /* Process DNS responses */ + ares_process_fd(channel->cares_channel(), + events & UV_READABLE ? task->sock : ARES_SOCKET_BAD, + events & UV_WRITABLE ? task->sock : ARES_SOCKET_BAD); +} + + +void ares_poll_close_cb(uv_poll_t* watcher) { + std::unique_ptr free_me( + ContainerOf(&NodeAresTask::poll_watcher, watcher)); +} + + +/* Callback from ares when socket operation is started */ +void ares_sockstate_cb(void* data, ares_socket_t sock, int read, int write) { + ChannelWrap* channel = static_cast(data); + NodeAresTask* task; + + NodeAresTask lookup_task; + lookup_task.sock = sock; + auto it = channel->task_list()->find(&lookup_task); + + task = (it == channel->task_list()->end()) ? nullptr : *it; + + if (read || write) { + if (!task) { + /* New socket */ + channel->StartTimer(); + + task = NodeAresTask::Create(channel, sock); + if (task == nullptr) { + /* This should never happen unless we're out of memory or something */ + /* is seriously wrong. The socket won't be polled, but the query will */ + /* eventually time out. */ + return; + } + + channel->task_list()->insert(task); + } + + /* This should never fail. If it fails anyway, the query will eventually */ + /* time out. */ + uv_poll_start(&task->poll_watcher, + (read ? UV_READABLE : 0) | (write ? UV_WRITABLE : 0), + ares_poll_cb); + + } else { + /* read == 0 and write == 0 this is c-ares's way of notifying us that */ + /* the socket is now closed. We must free the data associated with */ + /* socket. */ + CHECK(task && + "When an ares socket is closed we should have a handle for it"); + + channel->task_list()->erase(it); + channel->env()->CloseHandle(&task->poll_watcher, ares_poll_close_cb); + + if (channel->task_list()->empty()) { + channel->CloseTimer(); + } + } +} + +Local HostentToNames(Environment* env, struct hostent* host) { + EscapableHandleScope scope(env->isolate()); + + std::vector> names; + + for (uint32_t i = 0; host->h_aliases[i] != nullptr; ++i) + names.emplace_back(OneByteString(env->isolate(), host->h_aliases[i])); + + Local ret = Array::New(env->isolate(), names.data(), names.size()); + + return scope.Escape(ret); +} + +Local HostentToNames(Environment* env, + struct hostent* host, + Local names) { + size_t offset = names->Length(); + + for (uint32_t i = 0; host->h_aliases[i] != nullptr; ++i) { + names->Set( + env->context(), + i + offset, + OneByteString(env->isolate(), host->h_aliases[i])).Check(); + } + + return names; +} + +template +Local AddrTTLToArray( + Environment* env, + const T* addrttls, + size_t naddrttls) { + MaybeStackBuffer, 8> ttls(naddrttls); + for (size_t i = 0; i < naddrttls; i++) + ttls[i] = Integer::NewFromUnsigned(env->isolate(), addrttls[i].ttl); + + return Array::New(env->isolate(), ttls.out(), naddrttls); +} + +int ParseGeneralReply( + Environment* env, + const unsigned char* buf, + int len, + int* type, + Local ret, + void* addrttls = nullptr, + int* naddrttls = nullptr) { + HandleScope handle_scope(env->isolate()); + hostent* host; + + int status; + switch (*type) { + case ns_t_a: + case ns_t_cname: + case ns_t_cname_or_a: + status = ares_parse_a_reply(buf, + len, + &host, + static_cast(addrttls), + naddrttls); + break; + case ns_t_aaaa: + status = ares_parse_aaaa_reply(buf, + len, + &host, + static_cast(addrttls), + naddrttls); + break; + case ns_t_ns: + status = ares_parse_ns_reply(buf, len, &host); + break; + case ns_t_ptr: + status = ares_parse_ptr_reply(buf, len, nullptr, 0, AF_INET, &host); + break; + default: + CHECK(0 && "Bad NS type"); + break; + } + + if (status != ARES_SUCCESS) + return status; + + CHECK_NOT_NULL(host); + HostEntPointer ptr(host); + + /* If it's `CNAME`, return the CNAME value; + * And if it's `CNAME_OR_A` and it has value in `h_name` and `h_aliases[0]`, + * we consider it's a CNAME record, otherwise we consider it's an A record. */ + if ((*type == ns_t_cname_or_a && ptr->h_name && ptr->h_aliases[0]) || + *type == ns_t_cname) { + // A cname lookup always returns a single record but we follow the + // common API here. + *type = ns_t_cname; + ret->Set(env->context(), + ret->Length(), + OneByteString(env->isolate(), ptr->h_name)).Check(); + return ARES_SUCCESS; + } + + if (*type == ns_t_cname_or_a) + *type = ns_t_a; + + if (*type == ns_t_ns) { + HostentToNames(env, ptr.get(), ret); + } else if (*type == ns_t_ptr) { + uint32_t offset = ret->Length(); + for (uint32_t i = 0; ptr->h_aliases[i] != nullptr; i++) { + auto alias = OneByteString(env->isolate(), ptr->h_aliases[i]); + ret->Set(env->context(), i + offset, alias).Check(); + } + } else { + uint32_t offset = ret->Length(); + char ip[INET6_ADDRSTRLEN]; + for (uint32_t i = 0; ptr->h_addr_list[i] != nullptr; ++i) { + uv_inet_ntop(ptr->h_addrtype, ptr->h_addr_list[i], ip, sizeof(ip)); + auto address = OneByteString(env->isolate(), ip); + ret->Set(env->context(), i + offset, address).Check(); + } + } + + return ARES_SUCCESS; +} + +int ParseMxReply( + Environment* env, + const unsigned char* buf, + int len, + Local ret, + bool need_type = false) { + HandleScope handle_scope(env->isolate()); + + struct ares_mx_reply* mx_start; + int status = ares_parse_mx_reply(buf, len, &mx_start); + if (status != ARES_SUCCESS) + return status; + + uint32_t offset = ret->Length(); + ares_mx_reply* current = mx_start; + for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { + Local mx_record = Object::New(env->isolate()); + mx_record->Set(env->context(), + env->exchange_string(), + OneByteString(env->isolate(), current->host)).Check(); + mx_record->Set(env->context(), + env->priority_string(), + Integer::New(env->isolate(), current->priority)).Check(); + if (need_type) + mx_record->Set(env->context(), + env->type_string(), + env->dns_mx_string()).Check(); + + ret->Set(env->context(), i + offset, mx_record).Check(); + } + + ares_free_data(mx_start); + return ARES_SUCCESS; +} + +int ParseCaaReply( + Environment* env, + const unsigned char* buf, + int len, + Local ret, + bool need_type = false) { + HandleScope handle_scope(env->isolate()); + + struct ares_caa_reply* caa_start; + int status = ares_parse_caa_reply(buf, len, &caa_start); + if (status != ARES_SUCCESS) + return status; + + uint32_t offset = ret->Length(); + ares_caa_reply* current = caa_start; + for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { + Local caa_record = Object::New(env->isolate()); + + caa_record->Set(env->context(), + env->dns_critical_string(), + Integer::New(env->isolate(), current->critical)).Check(); + caa_record->Set(env->context(), + OneByteString(env->isolate(), current->property), + OneByteString(env->isolate(), current->value)).Check(); + if (need_type) + caa_record->Set(env->context(), + env->type_string(), + env->dns_caa_string()).Check(); + + ret->Set(env->context(), i + offset, caa_record).Check(); + } + + ares_free_data(caa_start); + return ARES_SUCCESS; +} + +int ParseTxtReply( + Environment* env, + const unsigned char* buf, + int len, + Local ret, + bool need_type = false) { + HandleScope handle_scope(env->isolate()); + + struct ares_txt_ext* txt_out; + + int status = ares_parse_txt_reply_ext(buf, len, &txt_out); + if (status != ARES_SUCCESS) + return status; + + Local txt_chunk; + + struct ares_txt_ext* current = txt_out; + uint32_t i = 0, j; + uint32_t offset = ret->Length(); + for (j = 0; current != nullptr; current = current->next) { + Local txt = + OneByteString(env->isolate(), current->txt, current->length); + + // New record found - write out the current chunk + if (current->record_start) { + if (!txt_chunk.IsEmpty()) { + if (need_type) { + Local elem = Object::New(env->isolate()); + elem->Set(env->context(), env->entries_string(), txt_chunk).Check(); + elem->Set(env->context(), + env->type_string(), + env->dns_txt_string()).Check(); + ret->Set(env->context(), offset + i++, elem).Check(); + } else { + ret->Set(env->context(), offset + i++, txt_chunk).Check(); + } + } + + txt_chunk = Array::New(env->isolate()); + j = 0; + } + + txt_chunk->Set(env->context(), j++, txt).Check(); + } + + // Push last chunk if it isn't empty + if (!txt_chunk.IsEmpty()) { + if (need_type) { + Local elem = Object::New(env->isolate()); + elem->Set(env->context(), env->entries_string(), txt_chunk).Check(); + elem->Set(env->context(), + env->type_string(), + env->dns_txt_string()).Check(); + ret->Set(env->context(), offset + i, elem).Check(); + } else { + ret->Set(env->context(), offset + i, txt_chunk).Check(); + } + } + + ares_free_data(txt_out); + return ARES_SUCCESS; +} + + +int ParseSrvReply( + Environment* env, + const unsigned char* buf, + int len, + Local ret, + bool need_type = false) { + HandleScope handle_scope(env->isolate()); + + struct ares_srv_reply* srv_start; + int status = ares_parse_srv_reply(buf, len, &srv_start); + if (status != ARES_SUCCESS) + return status; + + ares_srv_reply* current = srv_start; + int offset = ret->Length(); + for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { + Local srv_record = Object::New(env->isolate()); + srv_record->Set(env->context(), + env->name_string(), + OneByteString(env->isolate(), current->host)).Check(); + srv_record->Set(env->context(), + env->port_string(), + Integer::New(env->isolate(), current->port)).Check(); + srv_record->Set(env->context(), + env->priority_string(), + Integer::New(env->isolate(), current->priority)).Check(); + srv_record->Set(env->context(), + env->weight_string(), + Integer::New(env->isolate(), current->weight)).Check(); + if (need_type) + srv_record->Set(env->context(), + env->type_string(), + env->dns_srv_string()).Check(); + + ret->Set(env->context(), i + offset, srv_record).Check(); + } + + ares_free_data(srv_start); + return ARES_SUCCESS; +} + + +int ParseNaptrReply( + Environment* env, + const unsigned char* buf, + int len, + Local ret, + bool need_type = false) { + HandleScope handle_scope(env->isolate()); + + ares_naptr_reply* naptr_start; + int status = ares_parse_naptr_reply(buf, len, &naptr_start); + + if (status != ARES_SUCCESS) + return status; + + ares_naptr_reply* current = naptr_start; + int offset = ret->Length(); + for (uint32_t i = 0; current != nullptr; ++i, current = current->next) { + Local naptr_record = Object::New(env->isolate()); + naptr_record->Set(env->context(), + env->flags_string(), + OneByteString(env->isolate(), current->flags)).Check(); + naptr_record->Set(env->context(), + env->service_string(), + OneByteString(env->isolate(), + current->service)).Check(); + naptr_record->Set(env->context(), + env->regexp_string(), + OneByteString(env->isolate(), + current->regexp)).Check(); + naptr_record->Set(env->context(), + env->replacement_string(), + OneByteString(env->isolate(), + current->replacement)).Check(); + naptr_record->Set(env->context(), + env->order_string(), + Integer::New(env->isolate(), current->order)).Check(); + naptr_record->Set(env->context(), + env->preference_string(), + Integer::New(env->isolate(), + current->preference)).Check(); + if (need_type) + naptr_record->Set(env->context(), + env->type_string(), + env->dns_naptr_string()).Check(); + + ret->Set(env->context(), i + offset, naptr_record).Check(); + } + + ares_free_data(naptr_start); + return ARES_SUCCESS; +} + + +int ParseSoaReply( + Environment* env, + unsigned char* buf, + int len, + Local* ret) { + EscapableHandleScope handle_scope(env->isolate()); + + // Manage memory using standardard smart pointer std::unique_tr + struct AresDeleter { + void operator()(char* ptr) const noexcept { ares_free_string(ptr); } + }; + using ares_unique_ptr = std::unique_ptr; + + // Can't use ares_parse_soa_reply() here which can only parse single record + const unsigned int ancount = cares_get_16bit(buf + 6); + unsigned char* ptr = buf + NS_HFIXEDSZ; + char* name_temp = nullptr; + long temp_len; // NOLINT(runtime/int) + int status = ares_expand_name(ptr, buf, len, &name_temp, &temp_len); + if (status != ARES_SUCCESS) { + // returns EBADRESP in case of invalid input + return status == ARES_EBADNAME ? ARES_EBADRESP : status; + } + + const ares_unique_ptr name(name_temp); + + if (ptr + temp_len + NS_QFIXEDSZ > buf + len) { + return ARES_EBADRESP; + } + ptr += temp_len + NS_QFIXEDSZ; + + for (unsigned int i = 0; i < ancount; i++) { + char* rr_name_temp = nullptr; + long rr_temp_len; // NOLINT(runtime/int) + int status2 = ares_expand_name(ptr, buf, len, &rr_name_temp, &rr_temp_len); + + if (status2 != ARES_SUCCESS) + return status2 == ARES_EBADNAME ? ARES_EBADRESP : status2; + + const ares_unique_ptr rr_name(rr_name_temp); + + ptr += rr_temp_len; + if (ptr + NS_RRFIXEDSZ > buf + len) { + return ARES_EBADRESP; + } + + const int rr_type = cares_get_16bit(ptr); + const int rr_len = cares_get_16bit(ptr + 8); + ptr += NS_RRFIXEDSZ; + + // only need SOA + if (rr_type == ns_t_soa) { + char* nsname_temp = nullptr; + long nsname_temp_len; // NOLINT(runtime/int) + + int status3 = ares_expand_name(ptr, buf, len, + &nsname_temp, + &nsname_temp_len); + if (status3 != ARES_SUCCESS) { + return status3 == ARES_EBADNAME ? ARES_EBADRESP : status3; + } + const ares_unique_ptr nsname(nsname_temp); + ptr += nsname_temp_len; + + char* hostmaster_temp = nullptr; + long hostmaster_temp_len; // NOLINT(runtime/int) + int status4 = ares_expand_name(ptr, buf, len, + &hostmaster_temp, + &hostmaster_temp_len); + if (status4 != ARES_SUCCESS) { + return status4 == ARES_EBADNAME ? ARES_EBADRESP : status4; + } + const ares_unique_ptr hostmaster(hostmaster_temp); + ptr += hostmaster_temp_len; + + if (ptr + 5 * 4 > buf + len) { + return ARES_EBADRESP; + } + + const unsigned int serial = ReadUint32BE(ptr + 0 * 4); + const unsigned int refresh = ReadUint32BE(ptr + 1 * 4); + const unsigned int retry = ReadUint32BE(ptr + 2 * 4); + const unsigned int expire = ReadUint32BE(ptr + 3 * 4); + const unsigned int minttl = ReadUint32BE(ptr + 4 * 4); + + Local soa_record = Object::New(env->isolate()); + soa_record->Set(env->context(), + env->nsname_string(), + OneByteString(env->isolate(), nsname.get())).Check(); + soa_record->Set(env->context(), + env->hostmaster_string(), + OneByteString(env->isolate(), + hostmaster.get())).Check(); + soa_record->Set(env->context(), + env->serial_string(), + Integer::NewFromUnsigned(env->isolate(), serial)).Check(); + soa_record->Set(env->context(), + env->refresh_string(), + Integer::New(env->isolate(), refresh)).Check(); + soa_record->Set(env->context(), + env->retry_string(), + Integer::New(env->isolate(), retry)).Check(); + soa_record->Set(env->context(), + env->expire_string(), + Integer::New(env->isolate(), expire)).Check(); + soa_record->Set(env->context(), + env->minttl_string(), + Integer::NewFromUnsigned(env->isolate(), minttl)).Check(); + soa_record->Set(env->context(), + env->type_string(), + env->dns_soa_string()).Check(); + + + *ret = handle_scope.Escape(soa_record); + break; + } + + ptr += rr_len; + } + + return ARES_SUCCESS; +} +} // anonymous namespace + +ChannelWrap::ChannelWrap( + Environment* env, + Local object, + int timeout, + int tries) + : AsyncWrap(env, object, PROVIDER_DNSCHANNEL), + timeout_(timeout), + tries_(tries) { + MakeWeak(); + + Setup(); +} + +void ChannelWrap::MemoryInfo(MemoryTracker* tracker) const { + if (timer_handle_ != nullptr) + tracker->TrackField("timer_handle", *timer_handle_); + tracker->TrackField("task_list", task_list_, "NodeAresTask::List"); +} + +void ChannelWrap::New(const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); + CHECK_EQ(args.Length(), 2); + CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsInt32()); + const int timeout = args[0].As()->Value(); + const int tries = args[1].As()->Value(); + Environment* env = Environment::GetCurrent(args); + new ChannelWrap(env, args.This(), timeout, tries); +} + +GetAddrInfoReqWrap::GetAddrInfoReqWrap( + Environment* env, + Local req_wrap_obj, + bool verbatim) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP), + verbatim_(verbatim) {} + +GetNameInfoReqWrap::GetNameInfoReqWrap( + Environment* env, + Local req_wrap_obj) + : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) {} + +/* This is called once per second by loop->timer. It is used to constantly */ +/* call back into c-ares for possibly processing timeouts. */ +void ChannelWrap::AresTimeout(uv_timer_t* handle) { + ChannelWrap* channel = static_cast(handle->data); + CHECK_EQ(channel->timer_handle(), handle); + CHECK_EQ(false, channel->task_list()->empty()); + ares_process_fd(channel->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD); +} + + +void NodeAresTask::MemoryInfo(MemoryTracker* tracker) const { + tracker->TrackField("channel", channel); +} + +/* Allocates and returns a new NodeAresTask */ +NodeAresTask* NodeAresTask::Create(ChannelWrap* channel, ares_socket_t sock) { + auto task = new NodeAresTask(); + + task->channel = channel; + task->sock = sock; + + if (uv_poll_init_socket(channel->env()->event_loop(), + &task->poll_watcher, sock) < 0) { + /* This should never happen. */ + delete task; + return nullptr; + } + + return task; +} + +void ChannelWrap::Setup() { + struct ares_options options; + memset(&options, 0, sizeof(options)); + options.flags = ARES_FLAG_NOCHECKRESP; + options.sock_state_cb = ares_sockstate_cb; + options.sock_state_cb_data = this; + options.timeout = timeout_; + options.tries = tries_; + + int r; + if (!library_inited_) { + Mutex::ScopedLock lock(ares_library_mutex); + // Multiple calls to ares_library_init() increase a reference counter, + // so this is a no-op except for the first call to it. + r = ares_library_init(ARES_LIB_INIT_ALL); + if (r != ARES_SUCCESS) + return env()->ThrowError(ToErrorCodeString(r)); + } + + /* We do the call to ares_init_option for caller. */ + const int optmask = + ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | + ARES_OPT_SOCK_STATE_CB | ARES_OPT_TRIES; + r = ares_init_options(&channel_, &options, optmask); + + if (r != ARES_SUCCESS) { + Mutex::ScopedLock lock(ares_library_mutex); + ares_library_cleanup(); + return env()->ThrowError(ToErrorCodeString(r)); + } + + library_inited_ = true; +} + +void ChannelWrap::StartTimer() { + if (timer_handle_ == nullptr) { + timer_handle_ = new uv_timer_t(); + timer_handle_->data = static_cast(this); + uv_timer_init(env()->event_loop(), timer_handle_); + } else if (uv_is_active(reinterpret_cast(timer_handle_))) { + return; + } + int timeout = timeout_; + if (timeout == 0) timeout = 1; + if (timeout < 0 || timeout > 1000) timeout = 1000; + uv_timer_start(timer_handle_, AresTimeout, timeout, timeout); +} + +void ChannelWrap::CloseTimer() { + if (timer_handle_ == nullptr) + return; + + env()->CloseHandle(timer_handle_, [](uv_timer_t* handle) { delete handle; }); + timer_handle_ = nullptr; +} + +ChannelWrap::~ChannelWrap() { + ares_destroy(channel_); + + if (library_inited_) { + Mutex::ScopedLock lock(ares_library_mutex); + // This decreases the reference counter increased by ares_library_init(). + ares_library_cleanup(); + } + + CloseTimer(); +} + + +void ChannelWrap::ModifyActivityQueryCount(int count) { + active_query_count_ += count; + CHECK_GE(active_query_count_, 0); +} + + +/** + * This function is to check whether current servers are fallback servers + * when cares initialized. + * + * The fallback servers of cares is [ "127.0.0.1" ] with no user additional + * setting. + */ +void ChannelWrap::EnsureServers() { + /* if last query is OK or servers are set by user self, do not check */ + if (query_last_ok_ || !is_servers_default_) { + return; + } + + ares_addr_port_node* servers = nullptr; + + ares_get_servers_ports(channel_, &servers); + + /* if no server or multi-servers, ignore */ + if (servers == nullptr) return; + if (servers->next != nullptr) { + ares_free_data(servers); + is_servers_default_ = false; + return; + } + + /* if the only server is not 127.0.0.1, ignore */ + if (servers[0].family != AF_INET || + servers[0].addr.addr4.s_addr != htonl(INADDR_LOOPBACK) || + servers[0].tcp_port != 0 || + servers[0].udp_port != 0) { + ares_free_data(servers); + is_servers_default_ = false; + return; + } + + ares_free_data(servers); + servers = nullptr; + + /* destroy channel and reset channel */ + ares_destroy(channel_); + + CloseTimer(); + Setup(); +} + +int AnyTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_any); + return 0; +} + +int ATraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_a); + return 0; +} + +int AaaaTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_aaaa); + return 0; +} + +int CaaTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, T_CAA); + return 0; +} + +int CnameTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_cname); + return 0; +} + +int MxTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_mx); + return 0; +} + +int NsTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_ns); + return 0; +} + +int TxtTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_txt); + return 0; +} + +int SrvTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_srv); + return 0; +} + +int PtrTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_ptr); + return 0; +} + +int NaptrTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_naptr); + return 0; +} + +int SoaTraits::Send(QueryWrap* wrap, const char* name) { + wrap->AresQuery(name, ns_c_in, ns_t_soa); + return 0; +} + +int AnyTraits::Parse( + QueryAnyWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local ret = Array::New(env->isolate()); + int type, status, old_count; + + /* Parse A records or CNAME records */ + ares_addrttl addrttls[256]; + int naddrttls = arraysize(addrttls); + + type = ns_t_cname_or_a; + status = ParseGeneralReply(env, + buf, + len, + &type, + ret, + addrttls, + &naddrttls); + uint32_t a_count = ret->Length(); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + if (type == ns_t_a) { + CHECK_EQ(static_cast(naddrttls), a_count); + for (uint32_t i = 0; i < a_count; i++) { + Local obj = Object::New(env->isolate()); + obj->Set(env->context(), + env->address_string(), + ret->Get(env->context(), i).ToLocalChecked()).Check(); + obj->Set(env->context(), + env->ttl_string(), + Integer::NewFromUnsigned( + env->isolate(), addrttls[i].ttl)).Check(); + obj->Set(env->context(), + env->type_string(), + env->dns_a_string()).Check(); + ret->Set(env->context(), i, obj).Check(); + } + } else { + for (uint32_t i = 0; i < a_count; i++) { + Local obj = Object::New(env->isolate()); + obj->Set(env->context(), + env->value_string(), + ret->Get(env->context(), i).ToLocalChecked()).Check(); + obj->Set(env->context(), + env->type_string(), + env->dns_cname_string()).Check(); + ret->Set(env->context(), i, obj).Check(); + } + } + + /* Parse AAAA records */ + ares_addr6ttl addr6ttls[256]; + int naddr6ttls = arraysize(addr6ttls); + + type = ns_t_aaaa; + status = ParseGeneralReply(env, + buf, + len, + &type, + ret, + addr6ttls, + &naddr6ttls); + uint32_t aaaa_count = ret->Length() - a_count; + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + CHECK_EQ(aaaa_count, static_cast(naddr6ttls)); + CHECK_EQ(ret->Length(), a_count + aaaa_count); + for (uint32_t i = a_count; i < ret->Length(); i++) { + Local obj = Object::New(env->isolate()); + obj->Set(env->context(), + env->address_string(), + ret->Get(env->context(), i).ToLocalChecked()).Check(); + obj->Set(env->context(), + env->ttl_string(), + Integer::NewFromUnsigned( + env->isolate(), addr6ttls[i - a_count].ttl)).Check(); + obj->Set(env->context(), + env->type_string(), + env->dns_aaaa_string()).Check(); + ret->Set(env->context(), i, obj).Check(); + } + + /* Parse MX records */ + status = ParseMxReply(env, buf, len, ret, true); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + /* Parse NS records */ + type = ns_t_ns; + old_count = ret->Length(); + status = ParseGeneralReply(env, buf, len, &type, ret); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + for (uint32_t i = old_count; i < ret->Length(); i++) { + Local obj = Object::New(env->isolate()); + obj->Set(env->context(), + env->value_string(), + ret->Get(env->context(), i).ToLocalChecked()).Check(); + obj->Set(env->context(), + env->type_string(), + env->dns_ns_string()).Check(); + ret->Set(env->context(), i, obj).Check(); + } + + /* Parse TXT records */ + status = ParseTxtReply(env, buf, len, ret, true); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + /* Parse SRV records */ + status = ParseSrvReply(env, buf, len, ret, true); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + /* Parse PTR records */ + type = ns_t_ptr; + old_count = ret->Length(); + status = ParseGeneralReply(env, buf, len, &type, ret); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + for (uint32_t i = old_count; i < ret->Length(); i++) { + Local obj = Object::New(env->isolate()); + obj->Set(env->context(), + env->value_string(), + ret->Get(env->context(), i).ToLocalChecked()).Check(); + obj->Set(env->context(), + env->type_string(), + env->dns_ptr_string()).Check(); + ret->Set(env->context(), i, obj).Check(); + } + + /* Parse NAPTR records */ + status = ParseNaptrReply(env, buf, len, ret, true); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + /* Parse SOA records */ + Local soa_record = Local(); + status = ParseSoaReply(env, buf, len, &soa_record); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + if (!soa_record.IsEmpty()) + ret->Set(env->context(), ret->Length(), soa_record).Check(); + + /* Parse CAA records */ + status = ParseCaaReply(env, buf, len, ret, true); + if (status != ARES_SUCCESS && status != ARES_ENODATA) + return status; + + wrap->CallOnComplete(ret); + return 0; +} + +int ATraits::Parse( + QueryAWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + ares_addrttl addrttls[256]; + int naddrttls = arraysize(addrttls), status; + Local ret = Array::New(env->isolate()); + + int type = ns_t_a; + status = ParseGeneralReply(env, + buf, + len, + &type, + ret, + addrttls, + &naddrttls); + if (status != ARES_SUCCESS) + return status; + + Local ttls = AddrTTLToArray(env, addrttls, naddrttls); + + wrap->CallOnComplete(ret, ttls); + return 0; +} + +int AaaaTraits::Parse( + QueryAaaaWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + ares_addr6ttl addrttls[256]; + int naddrttls = arraysize(addrttls), status; + Local ret = Array::New(env->isolate()); + + int type = ns_t_aaaa; + status = ParseGeneralReply(env, + buf, + len, + &type, + ret, + addrttls, + &naddrttls); + if (status != ARES_SUCCESS) + return status; + + Local ttls = AddrTTLToArray(env, addrttls, naddrttls); + + wrap->CallOnComplete(ret, ttls); + return 0; +} + +int CaaTraits::Parse( + QueryCaaWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local ret = Array::New(env->isolate()); + int status = ParseCaaReply(env, buf, len, ret); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(ret); + return 0; +} + +int CnameTraits::Parse( + QueryCnameWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local ret = Array::New(env->isolate()); + int type = ns_t_cname; + int status = ParseGeneralReply(env, buf, len, &type, ret); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(ret); + return 0; +} + +int MxTraits::Parse( + QueryMxWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local mx_records = Array::New(env->isolate()); + int status = ParseMxReply(env, buf, len, mx_records); + + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(mx_records); + return 0; +} + +int NsTraits::Parse( + QueryNsWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + int type = ns_t_ns; + Local names = Array::New(env->isolate()); + int status = ParseGeneralReply(env, buf, len, &type, names); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(names); + return 0; +} + +int TxtTraits::Parse( + QueryTxtWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local txt_records = Array::New(env->isolate()); + int status = ParseTxtReply(env, buf, len, txt_records); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(txt_records); + return 0; +} + +int SrvTraits::Parse( + QuerySrvWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local srv_records = Array::New(env->isolate()); + int status = ParseSrvReply(env, buf, len, srv_records); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(srv_records); + return 0; +} + +int PtrTraits::Parse( + QueryPtrWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + int type = ns_t_ptr; + Local aliases = Array::New(env->isolate()); + + int status = ParseGeneralReply(env, buf, len, &type, aliases); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(aliases); + return 0; +} + +int NaptrTraits::Parse( + QueryNaptrWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local naptr_records = Array::New(env->isolate()); + int status = ParseNaptrReply(env, buf, len, naptr_records); + if (status != ARES_SUCCESS) + return status; + + wrap->CallOnComplete(naptr_records); + return 0; +} + +int SoaTraits::Parse( + QuerySoaWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(response->is_host)) + return ARES_EBADRESP; + + unsigned char* buf = response->buf.data; + int len = response->buf.size; + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + ares_soa_reply* soa_out; + int status = ares_parse_soa_reply(buf, len, &soa_out); + + if (status != ARES_SUCCESS) + return status; + + Local soa_record = Object::New(env->isolate()); + + soa_record->Set(env->context(), + env->nsname_string(), + OneByteString(env->isolate(), soa_out->nsname)).Check(); + soa_record->Set(env->context(), + env->hostmaster_string(), + OneByteString(env->isolate(), soa_out->hostmaster)).Check(); + soa_record->Set(env->context(), + env->serial_string(), + Integer::NewFromUnsigned( + env->isolate(), soa_out->serial)).Check(); + soa_record->Set(env->context(), + env->refresh_string(), + Integer::New(env->isolate(), soa_out->refresh)).Check(); + soa_record->Set(env->context(), + env->retry_string(), + Integer::New(env->isolate(), soa_out->retry)).Check(); + soa_record->Set(env->context(), + env->expire_string(), + Integer::New(env->isolate(), soa_out->expire)).Check(); + soa_record->Set(env->context(), + env->minttl_string(), + Integer::NewFromUnsigned( + env->isolate(), soa_out->minttl)).Check(); + + ares_free_data(soa_out); + + wrap->CallOnComplete(soa_record); + return 0; +} + +int ReverseTraits::Send(GetHostByAddrWrap* wrap, const char* name) { + int length, family; + char address_buffer[sizeof(struct in6_addr)]; + + if (uv_inet_pton(AF_INET, name, &address_buffer) == 0) { + length = sizeof(struct in_addr); + family = AF_INET; + } else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 0) { + length = sizeof(struct in6_addr); + family = AF_INET6; + } else { + return UV_EINVAL; // So errnoException() reports a proper error. + } + + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + TRACING_CATEGORY_NODE2(dns, native), "reverse", wrap, + "name", TRACE_STR_COPY(name), + "family", family == AF_INET ? "ipv4" : "ipv6"); + + ares_gethostbyaddr( + wrap->channel()->cares_channel(), + address_buffer, + length, + family, + GetHostByAddrWrap::Callback, + wrap->MakeCallbackPointer()); + return 0; +} + +int ReverseTraits::Parse( + GetHostByAddrWrap* wrap, + const std::unique_ptr& response) { + if (UNLIKELY(!response->is_host)) + return ARES_EBADRESP; + + struct hostent* host = response->host.get(); + + Environment* env = wrap->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + wrap->CallOnComplete(HostentToNames(env, host)); + return 0; +} + +namespace { +template +static void Query(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + ChannelWrap* channel; + ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + + CHECK_EQ(false, args.IsConstructCall()); + CHECK(args[0]->IsObject()); + CHECK(args[1]->IsString()); + + Local req_wrap_obj = args[0].As(); + Local string = args[1].As(); + auto wrap = std::make_unique(channel, req_wrap_obj); + + node::Utf8Value name(env->isolate(), string); + channel->ModifyActivityQueryCount(1); + int err = wrap->Send(*name); + if (err) { + channel->ModifyActivityQueryCount(-1); + } else { + // Release ownership of the pointer allowing the ownership to be transferred + USE(wrap.release()); + } + + args.GetReturnValue().Set(err); +} + + +void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { + std::unique_ptr req_wrap { + static_cast(req->data)}; + Environment* env = req_wrap->env(); + + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local argv[] = { + Integer::New(env->isolate(), status), + Null(env->isolate()) + }; + + uint64_t n = 0; + const bool verbatim = req_wrap->verbatim(); + + if (status == 0) { + Local results = Array::New(env->isolate()); + + auto add = [&] (bool want_ipv4, bool want_ipv6) -> Maybe { + for (auto p = res; p != nullptr; p = p->ai_next) { + CHECK_EQ(p->ai_socktype, SOCK_STREAM); + + const char* addr; + if (want_ipv4 && p->ai_family == AF_INET) { + addr = reinterpret_cast( + &(reinterpret_cast(p->ai_addr)->sin_addr)); + } else if (want_ipv6 && p->ai_family == AF_INET6) { + addr = reinterpret_cast( + &(reinterpret_cast(p->ai_addr)->sin6_addr)); + } else { + continue; + } + + char ip[INET6_ADDRSTRLEN]; + if (uv_inet_ntop(p->ai_family, addr, ip, sizeof(ip))) + continue; + + Local s = OneByteString(env->isolate(), ip); + if (results->Set(env->context(), n, s).IsNothing()) + return Nothing(); + n++; + } + return Just(true); + }; + + if (add(true, verbatim).IsNothing()) + return; + if (verbatim == false) { + if (add(false, true).IsNothing()) + return; + } + + // No responses were found to return + if (n == 0) { + argv[0] = Integer::New(env->isolate(), UV_EAI_NODATA); + } + + argv[1] = results; + } + + uv_freeaddrinfo(res); + + TRACE_EVENT_NESTABLE_ASYNC_END2( + TRACING_CATEGORY_NODE2(dns, native), "lookup", req_wrap.get(), + "count", n, "verbatim", verbatim); + + // Make the callback into JavaScript + req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv); +} + + +void AfterGetNameInfo(uv_getnameinfo_t* req, + int status, + const char* hostname, + const char* service) { + std::unique_ptr req_wrap { + static_cast(req->data)}; + Environment* env = req_wrap->env(); + + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + Local argv[] = { + Integer::New(env->isolate(), status), + Null(env->isolate()), + Null(env->isolate()) + }; + + if (status == 0) { + // Success + Local js_hostname = OneByteString(env->isolate(), hostname); + Local js_service = OneByteString(env->isolate(), service); + argv[1] = js_hostname; + argv[2] = js_service; + } + + TRACE_EVENT_NESTABLE_ASYNC_END2( + TRACING_CATEGORY_NODE2(dns, native), "lookupService", req_wrap.get(), + "hostname", TRACE_STR_COPY(hostname), + "service", TRACE_STR_COPY(service)); + + // Make the callback into JavaScript + req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv); +} + +using ParseIPResult = + decltype(static_cast(nullptr)->addr); + +int ParseIP(const char* ip, ParseIPResult* result = nullptr) { + ParseIPResult tmp; + if (result == nullptr) result = &tmp; + if (0 == uv_inet_pton(AF_INET, ip, result)) return 4; + if (0 == uv_inet_pton(AF_INET6, ip, result)) return 6; + return 0; +} + +void CanonicalizeIP(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + node::Utf8Value ip(isolate, args[0]); + + ParseIPResult result; + const int rc = ParseIP(*ip, &result); + if (rc == 0) return; + + char canonical_ip[INET6_ADDRSTRLEN]; + const int af = (rc == 4 ? AF_INET : AF_INET6); + CHECK_EQ(0, uv_inet_ntop(af, &result, canonical_ip, sizeof(canonical_ip))); + Local val = String::NewFromUtf8(isolate, canonical_ip) + .ToLocalChecked(); + args.GetReturnValue().Set(val); +} + +void GetAddrInfo(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + CHECK(args[0]->IsObject()); + CHECK(args[1]->IsString()); + CHECK(args[2]->IsInt32()); + CHECK(args[4]->IsBoolean()); + Local req_wrap_obj = args[0].As(); + node::Utf8Value hostname(env->isolate(), args[1]); + + int32_t flags = 0; + if (args[3]->IsInt32()) { + flags = args[3].As()->Value(); + } + + int family; + + switch (args[2].As()->Value()) { + case 0: + family = AF_UNSPEC; + break; + case 4: + family = AF_INET; + break; + case 6: + family = AF_INET6; + break; + default: + CHECK(0 && "bad address family"); + } + + auto req_wrap = std::make_unique(env, + req_wrap_obj, + args[4]->IsTrue()); + + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = flags; + + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + TRACING_CATEGORY_NODE2(dns, native), "lookup", req_wrap.get(), + "hostname", TRACE_STR_COPY(*hostname), + "family", + family == AF_INET ? "ipv4" : family == AF_INET6 ? "ipv6" : "unspec"); + + int err = req_wrap->Dispatch(uv_getaddrinfo, + AfterGetAddrInfo, + *hostname, + nullptr, + &hints); + if (err == 0) + // Release ownership of the pointer allowing the ownership to be transferred + USE(req_wrap.release()); + + args.GetReturnValue().Set(err); +} + + +void GetNameInfo(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + CHECK(args[0]->IsObject()); + CHECK(args[1]->IsString()); + CHECK(args[2]->IsUint32()); + Local req_wrap_obj = args[0].As(); + node::Utf8Value ip(env->isolate(), args[1]); + const unsigned port = args[2]->Uint32Value(env->context()).FromJust(); + struct sockaddr_storage addr; + + CHECK(uv_ip4_addr(*ip, port, reinterpret_cast(&addr)) == 0 || + uv_ip6_addr(*ip, port, reinterpret_cast(&addr)) == 0); + + auto req_wrap = std::make_unique(env, req_wrap_obj); + + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + TRACING_CATEGORY_NODE2(dns, native), "lookupService", req_wrap.get(), + "ip", TRACE_STR_COPY(*ip), "port", port); + + int err = req_wrap->Dispatch(uv_getnameinfo, + AfterGetNameInfo, + reinterpret_cast(&addr), + NI_NAMEREQD); + if (err == 0) + // Release ownership of the pointer allowing the ownership to be transferred + USE(req_wrap.release()); + + args.GetReturnValue().Set(err); +} + + +void GetServers(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + ChannelWrap* channel; + ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + + Local server_array = Array::New(env->isolate()); + + ares_addr_port_node* servers; + + int r = ares_get_servers_ports(channel->cares_channel(), &servers); + CHECK_EQ(r, ARES_SUCCESS); + auto cleanup = OnScopeLeave([&]() { ares_free_data(servers); }); + + ares_addr_port_node* cur = servers; + + for (uint32_t i = 0; cur != nullptr; ++i, cur = cur->next) { + char ip[INET6_ADDRSTRLEN]; + + const void* caddr = static_cast(&cur->addr); + int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip)); + CHECK_EQ(err, 0); + + Local ret[] = { + OneByteString(env->isolate(), ip), + Integer::New(env->isolate(), cur->udp_port) + }; + + if (server_array->Set(env->context(), i, + Array::New(env->isolate(), ret, arraysize(ret))) + .IsNothing()) { + return; + } + } + + args.GetReturnValue().Set(server_array); +} + + +void SetServers(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + ChannelWrap* channel; + ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + + if (channel->active_query_count()) { + return args.GetReturnValue().Set(DNS_ESETSRVPENDING); + } + + CHECK(args[0]->IsArray()); + + Local arr = Local::Cast(args[0]); + + uint32_t len = arr->Length(); + + if (len == 0) { + int rv = ares_set_servers(channel->cares_channel(), nullptr); + return args.GetReturnValue().Set(rv); + } + + std::vector servers(len); + ares_addr_port_node* last = nullptr; + + int err; + + for (uint32_t i = 0; i < len; i++) { + CHECK(arr->Get(env->context(), i).ToLocalChecked()->IsArray()); + + Local elm = + Local::Cast(arr->Get(env->context(), i).ToLocalChecked()); + + CHECK(elm->Get(env->context(), + 0).ToLocalChecked()->Int32Value(env->context()).FromJust()); + CHECK(elm->Get(env->context(), 1).ToLocalChecked()->IsString()); + CHECK(elm->Get(env->context(), + 2).ToLocalChecked()->Int32Value(env->context()).FromJust()); + + int fam = elm->Get(env->context(), 0) + .ToLocalChecked()->Int32Value(env->context()).FromJust(); + node::Utf8Value ip(env->isolate(), + elm->Get(env->context(), 1).ToLocalChecked()); + int port = elm->Get(env->context(), 2) + .ToLocalChecked()->Int32Value(env->context()).FromJust(); + + ares_addr_port_node* cur = &servers[i]; + + cur->tcp_port = cur->udp_port = port; + switch (fam) { + case 4: + cur->family = AF_INET; + err = uv_inet_pton(AF_INET, *ip, &cur->addr); + break; + case 6: + cur->family = AF_INET6; + err = uv_inet_pton(AF_INET6, *ip, &cur->addr); + break; + default: + CHECK(0 && "Bad address family."); + } + + if (err) + break; + + cur->next = nullptr; + + if (last != nullptr) + last->next = cur; + + last = cur; + } + + if (err == 0) + err = ares_set_servers_ports(channel->cares_channel(), &servers[0]); + else + err = ARES_EBADSTR; + + if (err == ARES_SUCCESS) + channel->set_is_servers_default(false); + + args.GetReturnValue().Set(err); +} + +void SetLocalAddress(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + ChannelWrap* channel; + ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + + CHECK_EQ(args.Length(), 2); + CHECK(args[0]->IsString()); + + Isolate* isolate = args.GetIsolate(); + node::Utf8Value ip0(isolate, args[0]); + + unsigned char addr0[sizeof(struct in6_addr)]; + unsigned char addr1[sizeof(struct in6_addr)]; + int type0 = 0; + + // This function accepts 2 arguments. The first may be either an IPv4 + // address or an IPv6 address. If present, the second argument must be the + // other type of address. Otherwise, the unspecified type of IP is set + // to 0 (any). + + if (uv_inet_pton(AF_INET, *ip0, &addr0) == 0) { + ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr0)); + type0 = 4; + } else if (uv_inet_pton(AF_INET6, *ip0, &addr0) == 0) { + ares_set_local_ip6(channel->cares_channel(), addr0); + type0 = 6; + } else { + THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address."); + return; + } + + if (!args[1]->IsUndefined()) { + CHECK(args[1]->IsString()); + node::Utf8Value ip1(isolate, args[1]); + + if (uv_inet_pton(AF_INET, *ip1, &addr1) == 0) { + if (type0 == 4) { + THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv4 addresses."); + return; + } else { + ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr1)); + } + } else if (uv_inet_pton(AF_INET6, *ip1, &addr1) == 0) { + if (type0 == 6) { + THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv6 addresses."); + return; + } else { + ares_set_local_ip6(channel->cares_channel(), addr1); + } + } else { + THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address."); + return; + } + } else { + // No second arg specified + if (type0 == 4) { + memset(&addr1, 0, sizeof(addr1)); + ares_set_local_ip6(channel->cares_channel(), addr1); + } else { + ares_set_local_ip4(channel->cares_channel(), 0); + } + } +} + +void Cancel(const FunctionCallbackInfo& args) { + ChannelWrap* channel; + ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + + TRACE_EVENT_INSTANT0(TRACING_CATEGORY_NODE2(dns, native), + "cancel", TRACE_EVENT_SCOPE_THREAD); + + ares_cancel(channel->cares_channel()); +} + +const char EMSG_ESETSRVPENDING[] = "There are pending queries."; +void StrError(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + int code = args[0]->Int32Value(env->context()).FromJust(); + const char* errmsg = (code == DNS_ESETSRVPENDING) ? + EMSG_ESETSRVPENDING : + ares_strerror(code); + args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg)); +} + +} // namespace + +inline void safe_free_hostent(struct hostent* host) { + int idx; + + if (host->h_addr_list != nullptr) { + idx = 0; + while (host->h_addr_list[idx]) { + free(host->h_addr_list[idx++]); + } + free(host->h_addr_list); + host->h_addr_list = nullptr; + } + + if (host->h_aliases != nullptr) { + idx = 0; + while (host->h_aliases[idx]) { + free(host->h_aliases[idx++]); + } + free(host->h_aliases); + host->h_aliases = nullptr; + } + + free(host->h_name); + free(host); +} + +void Initialize(Local target, + Local unused, + Local context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + + env->SetMethod(target, "getaddrinfo", GetAddrInfo); + env->SetMethod(target, "getnameinfo", GetNameInfo); + env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP); + + env->SetMethod(target, "strerror", StrError); + + target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"), + Integer::New(env->isolate(), AF_INET)).Check(); + target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET6"), + Integer::New(env->isolate(), AF_INET6)).Check(); + target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), + "AF_UNSPEC"), + Integer::New(env->isolate(), AF_UNSPEC)).Check(); + target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), + "AI_ADDRCONFIG"), + Integer::New(env->isolate(), AI_ADDRCONFIG)).Check(); + target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), + "AI_ALL"), + Integer::New(env->isolate(), AI_ALL)).Check(); + target->Set(env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), + "AI_V4MAPPED"), + Integer::New(env->isolate(), AI_V4MAPPED)).Check(); + + Local aiw = + BaseObject::MakeLazilyInitializedJSTemplate(env); + aiw->Inherit(AsyncWrap::GetConstructorTemplate(env)); + env->SetConstructorFunction(target, "GetAddrInfoReqWrap", aiw); + + Local niw = + BaseObject::MakeLazilyInitializedJSTemplate(env); + niw->Inherit(AsyncWrap::GetConstructorTemplate(env)); + env->SetConstructorFunction(target, "GetNameInfoReqWrap", niw); + + Local qrw = + BaseObject::MakeLazilyInitializedJSTemplate(env); + qrw->Inherit(AsyncWrap::GetConstructorTemplate(env)); + env->SetConstructorFunction(target, "QueryReqWrap", qrw); + + Local channel_wrap = + env->NewFunctionTemplate(ChannelWrap::New); + channel_wrap->InstanceTemplate()->SetInternalFieldCount( + ChannelWrap::kInternalFieldCount); + channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env)); + + env->SetProtoMethod(channel_wrap, "queryAny", Query); + env->SetProtoMethod(channel_wrap, "queryA", Query); + env->SetProtoMethod(channel_wrap, "queryAaaa", Query); + env->SetProtoMethod(channel_wrap, "queryCaa", Query); + env->SetProtoMethod(channel_wrap, "queryCname", Query); + env->SetProtoMethod(channel_wrap, "queryMx", Query); + env->SetProtoMethod(channel_wrap, "queryNs", Query); + env->SetProtoMethod(channel_wrap, "queryTxt", Query); + env->SetProtoMethod(channel_wrap, "querySrv", Query); + env->SetProtoMethod(channel_wrap, "queryPtr", Query); + env->SetProtoMethod(channel_wrap, "queryNaptr", Query); + env->SetProtoMethod(channel_wrap, "querySoa", Query); + env->SetProtoMethod(channel_wrap, "getHostByAddr", Query); + + env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers); + env->SetProtoMethod(channel_wrap, "setServers", SetServers); + env->SetProtoMethod(channel_wrap, "setLocalAddress", SetLocalAddress); + env->SetProtoMethod(channel_wrap, "cancel", Cancel); + + env->SetConstructorFunction(target, "ChannelWrap", channel_wrap); +} + +} // namespace cares_wrap +} // namespace node + +NODE_MODULE_CONTEXT_AWARE_INTERNAL(cares_wrap, node::cares_wrap::Initialize) diff --git a/third_party/node/src/cares_wrap.h b/third_party/node/src/cares_wrap.h new file mode 100644 index 000000000..60f99e65e --- /dev/null +++ b/third_party/node/src/cares_wrap.h @@ -0,0 +1,523 @@ +#ifndef SRC_CARES_WRAP_H_ +#define SRC_CARES_WRAP_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#define CARES_STATICLIB + +#include "async_wrap.h" +#include "base_object.h" +#include "env.h" +#include "memory_tracker.h" +#include "util.h" +#include "node.h" + +#include "ares.h" +#include "v8.h" +#include "uv.h" + +#include + +#ifdef __POSIX__ +# include +#endif // __POSIX__ + +# include + +namespace node { +namespace cares_wrap { + +constexpr int ns_t_cname_or_a = -1; +constexpr int DNS_ESETSRVPENDING = -1000; + +class ChannelWrap; + +inline void safe_free_hostent(struct hostent* host); + +using HostEntPointer = DeleteFnPtr; +using SafeHostEntPointer = DeleteFnPtr; + +inline const char* ToErrorCodeString(int status) { + switch (status) { +#define V(code) case ARES_##code: return #code; + V(EADDRGETNETWORKPARAMS) + V(EBADFAMILY) + V(EBADFLAGS) + V(EBADHINTS) + V(EBADNAME) + V(EBADQUERY) + V(EBADRESP) + V(EBADSTR) + V(ECANCELLED) + V(ECONNREFUSED) + V(EDESTRUCTION) + V(EFILE) + V(EFORMERR) + V(ELOADIPHLPAPI) + V(ENODATA) + V(ENOMEM) + V(ENONAME) + V(ENOTFOUND) + V(ENOTIMP) + V(ENOTINITIALIZED) + V(EOF) + V(EREFUSED) + V(ESERVFAIL) + V(ETIMEOUT) +#undef V + } + + return "UNKNOWN_ARES_ERROR"; +} + +inline void cares_wrap_hostent_cpy( + struct hostent* dest, + const struct hostent* src) { + dest->h_addr_list = nullptr; + dest->h_addrtype = 0; + dest->h_aliases = nullptr; + dest->h_length = 0; + dest->h_name = nullptr; + + /* copy `h_name` */ + size_t name_size = strlen(src->h_name) + 1; + dest->h_name = node::Malloc(name_size); + memcpy(dest->h_name, src->h_name, name_size); + + /* copy `h_aliases` */ + size_t alias_count; + for (alias_count = 0; + src->h_aliases[alias_count] != nullptr; + alias_count++) { + } + + dest->h_aliases = node::Malloc(alias_count + 1); + for (size_t i = 0; i < alias_count; i++) { + const size_t cur_alias_size = strlen(src->h_aliases[i]) + 1; + dest->h_aliases[i] = node::Malloc(cur_alias_size); + memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_size); + } + dest->h_aliases[alias_count] = nullptr; + + /* copy `h_addr_list` */ + size_t list_count; + for (list_count = 0; + src->h_addr_list[list_count] != nullptr; + list_count++) { + } + + dest->h_addr_list = node::Malloc(list_count + 1); + for (size_t i = 0; i < list_count; i++) { + dest->h_addr_list[i] = node::Malloc(src->h_length); + memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length); + } + dest->h_addr_list[list_count] = nullptr; + + /* work after work */ + dest->h_length = src->h_length; + dest->h_addrtype = src->h_addrtype; +} + + +struct NodeAresTask final : public MemoryRetainer { + ChannelWrap* channel; + ares_socket_t sock; + uv_poll_t poll_watcher; + + inline void MemoryInfo(MemoryTracker* trakcer) const override; + SET_MEMORY_INFO_NAME(NodeAresTask) + SET_SELF_SIZE(NodeAresTask) + + struct Hash { + inline size_t operator()(NodeAresTask* a) const { + return std::hash()(a->sock); + } + }; + + struct Equal { + inline bool operator()(NodeAresTask* a, NodeAresTask* b) const { + return a->sock == b->sock; + } + }; + + static NodeAresTask* Create(ChannelWrap* channel, ares_socket_t sock); + + using List = std::unordered_set; +}; + +class ChannelWrap final : public AsyncWrap { + public: + ChannelWrap( + Environment* env, + v8::Local object, + int timeout, + int tries); + ~ChannelWrap() override; + + static void New(const v8::FunctionCallbackInfo& args); + + void Setup(); + void EnsureServers(); + void StartTimer(); + void CloseTimer(); + + void ModifyActivityQueryCount(int count); + + inline uv_timer_t* timer_handle() { return timer_handle_; } + inline ares_channel cares_channel() { return channel_; } + inline void set_query_last_ok(bool ok) { query_last_ok_ = ok; } + inline void set_is_servers_default(bool is_default) { + is_servers_default_ = is_default; + } + inline int active_query_count() { return active_query_count_; } + inline NodeAresTask::List* task_list() { return &task_list_; } + + void MemoryInfo(MemoryTracker* tracker) const override; + SET_MEMORY_INFO_NAME(ChannelWrap) + SET_SELF_SIZE(ChannelWrap) + + static void AresTimeout(uv_timer_t* handle); + + private: + uv_timer_t* timer_handle_ = nullptr; + ares_channel channel_ = nullptr; + bool query_last_ok_ = true; + bool is_servers_default_ = true; + bool library_inited_ = false; + int timeout_; + int tries_; + int active_query_count_ = 0; + NodeAresTask::List task_list_; +}; + +class GetAddrInfoReqWrap final : public ReqWrap { + public: + GetAddrInfoReqWrap(Environment* env, + v8::Local req_wrap_obj, + bool verbatim); + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(GetAddrInfoReqWrap) + SET_SELF_SIZE(GetAddrInfoReqWrap) + + bool verbatim() const { return verbatim_; } + + private: + const bool verbatim_; +}; + +class GetNameInfoReqWrap final : public ReqWrap { + public: + GetNameInfoReqWrap(Environment* env, v8::Local req_wrap_obj); + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(GetNameInfoReqWrap) + SET_SELF_SIZE(GetNameInfoReqWrap) +}; + +struct ResponseData final { + int status; + bool is_host; + SafeHostEntPointer host; + MallocedBuffer buf; +}; + +template +class QueryWrap final : public AsyncWrap { + public: + QueryWrap(ChannelWrap* channel, v8::Local req_wrap_obj) + : AsyncWrap(channel->env(), req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP), + channel_(channel), + trace_name_(Traits::name) {} + + ~QueryWrap() { + CHECK_EQ(false, persistent().IsEmpty()); + + // Let Callback() know that this object no longer exists. + if (callback_ptr_ != nullptr) + *callback_ptr_ = nullptr; + } + + int Send(const char* name) { + return Traits::Send(this, name); + } + + void AresQuery(const char* name, int dnsclass, int type) { + channel_->EnsureServers(); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + TRACING_CATEGORY_NODE2(dns, native), trace_name_, this, + "name", TRACE_STR_COPY(name)); + ares_query( + channel_->cares_channel(), + name, + dnsclass, + type, + Callback, + MakeCallbackPointer()); + } + + void ParseError(int status) { + CHECK_NE(status, ARES_SUCCESS); + v8::HandleScope handle_scope(env()->isolate()); + v8::Context::Scope context_scope(env()->context()); + const char* code = ToErrorCodeString(status); + v8::Local arg = OneByteString(env()->isolate(), code); + TRACE_EVENT_NESTABLE_ASYNC_END1( + TRACING_CATEGORY_NODE2(dns, native), trace_name_, this, + "error", status); + MakeCallback(env()->oncomplete_string(), 1, &arg); + } + + const BaseObjectPtr& channel() const { return channel_; } + + void AfterResponse() { + CHECK(response_data_); + + int status = response_data_->status; + + if (status != ARES_SUCCESS) + return ParseError(status); + + status = Traits::Parse(this, response_data_); + + if (status != ARES_SUCCESS) + ParseError(status); + } + + void* MakeCallbackPointer() { + CHECK_NULL(callback_ptr_); + callback_ptr_ = new QueryWrap*(this); + return callback_ptr_; + } + + static QueryWrap* FromCallbackPointer(void* arg) { + std::unique_ptr*> wrap_ptr { + static_cast**>(arg) + }; + QueryWrap* wrap = *wrap_ptr.get(); + if (wrap == nullptr) return nullptr; + wrap->callback_ptr_ = nullptr; + return wrap; + } + + static void Callback( + void* arg, + int status, + int timeouts, + unsigned char* answer_buf, + int answer_len) { + QueryWrap* wrap = FromCallbackPointer(arg); + if (wrap == nullptr) return; + + unsigned char* buf_copy = nullptr; + if (status == ARES_SUCCESS) { + buf_copy = node::Malloc(answer_len); + memcpy(buf_copy, answer_buf, answer_len); + } + + wrap->response_data_ = std::make_unique(); + ResponseData* data = wrap->response_data_.get(); + data->status = status; + data->is_host = false; + data->buf = MallocedBuffer(buf_copy, answer_len); + + wrap->QueueResponseCallback(status); + } + + static void Callback( + void* arg, + int status, + int timeouts, + struct hostent* host) { + QueryWrap* wrap = FromCallbackPointer(arg); + if (wrap == nullptr) return; + + struct hostent* host_copy = nullptr; + if (status == ARES_SUCCESS) { + host_copy = node::Malloc(1); + cares_wrap_hostent_cpy(host_copy, host); + } + + wrap->response_data_ = std::make_unique(); + ResponseData* data = wrap->response_data_.get(); + data->status = status; + data->host.reset(host_copy); + data->is_host = true; + + wrap->QueueResponseCallback(status); + } + + void QueueResponseCallback(int status) { + BaseObjectPtr> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment*) { + AfterResponse(); + + // Delete once strong_ref goes out of scope. + Detach(); + }); + + channel_->set_query_last_ok(status != ARES_ECONNREFUSED); + channel_->ModifyActivityQueryCount(-1); + } + + void CallOnComplete( + v8::Local answer, + v8::Local extra = v8::Local()) { + v8::HandleScope handle_scope(env()->isolate()); + v8::Context::Scope context_scope(env()->context()); + v8::Local argv[] = { + v8::Integer::New(env()->isolate(), 0), + answer, + extra + }; + const int argc = arraysize(argv) - extra.IsEmpty(); + TRACE_EVENT_NESTABLE_ASYNC_END0( + TRACING_CATEGORY_NODE2(dns, native), trace_name_, this); + + MakeCallback(env()->oncomplete_string(), argc, argv); + } + + void MemoryInfo(MemoryTracker* tracker) const override { + tracker->TrackField("channel", channel_); + if (response_data_) { + tracker->TrackFieldWithSize("response", response_data_->buf.size); + } + } + + SET_MEMORY_INFO_NAME(QueryWrap) + SET_SELF_SIZE(QueryWrap) + + private: + BaseObjectPtr channel_; + + std::unique_ptr response_data_; + const char* trace_name_; + // Pointer to pointer to 'this' that can be reset from the destructor, + // in order to let Callback() know that 'this' no longer exists. + QueryWrap** callback_ptr_ = nullptr; +}; + +struct AnyTraits final { + static constexpr const char* name = "resolveAny"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct ATraits final { + static constexpr const char* name = "resolve4"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct AaaaTraits final { + static constexpr const char* name = "resolve6"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct CaaTraits final { + static constexpr const char* name = "resolveCaa"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct CnameTraits final { + static constexpr const char* name = "resolveCname"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct MxTraits final { + static constexpr const char* name = "resolveMx"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct NsTraits final { + static constexpr const char* name = "resolveNs"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct TxtTraits final { + static constexpr const char* name = "resolveTxt"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct SrvTraits final { + static constexpr const char* name = "resolveSrv"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct PtrTraits final { + static constexpr const char* name = "resolvePtr"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct NaptrTraits final { + static constexpr const char* name = "resolveNaptr"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct SoaTraits final { + static constexpr const char* name = "resolveSoa"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +struct ReverseTraits final { + static constexpr const char* name = "reverse"; + static int Send(QueryWrap* wrap, const char* name); + static int Parse( + QueryWrap* wrap, + const std::unique_ptr& response); +}; + +using QueryAnyWrap = QueryWrap; +using QueryAWrap = QueryWrap; +using QueryAaaaWrap = QueryWrap; +using QueryCaaWrap = QueryWrap; +using QueryCnameWrap = QueryWrap; +using QueryMxWrap = QueryWrap; +using QueryNsWrap = QueryWrap; +using QueryTxtWrap = QueryWrap; +using QuerySrvWrap = QueryWrap; +using QueryPtrWrap = QueryWrap; +using QueryNaptrWrap = QueryWrap; +using QuerySoaWrap = QueryWrap; +using GetHostByAddrWrap = QueryWrap; + +} // namespace cares_wrap +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CARES_WRAP_H_ diff --git a/third_party/node/src/connect_wrap.cc b/third_party/node/src/connect_wrap.cc new file mode 100644 index 000000000..e1d34c11a --- /dev/null +++ b/third_party/node/src/connect_wrap.cc @@ -0,0 +1,16 @@ +#include "connect_wrap.h" +#include "req_wrap-inl.h" + +namespace node { + +using v8::Local; +using v8::Object; + +class Environment; + +ConnectWrap::ConnectWrap(Environment* env, + Local req_wrap_obj, + AsyncWrap::ProviderType provider) : ReqWrap(env, req_wrap_obj, provider) { +} + +} // namespace node diff --git a/third_party/node/src/connect_wrap.h b/third_party/node/src/connect_wrap.h new file mode 100644 index 000000000..eaa533025 --- /dev/null +++ b/third_party/node/src/connect_wrap.h @@ -0,0 +1,26 @@ +#ifndef SRC_CONNECT_WRAP_H_ +#define SRC_CONNECT_WRAP_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "req_wrap-inl.h" +#include "async_wrap.h" + +namespace node { + +class ConnectWrap : public ReqWrap { + public: + ConnectWrap(Environment* env, + v8::Local req_wrap_obj, + AsyncWrap::ProviderType provider); + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(ConnectWrap) + SET_SELF_SIZE(ConnectWrap) +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CONNECT_WRAP_H_ diff --git a/third_party/node/src/connection_wrap.cc b/third_party/node/src/connection_wrap.cc new file mode 100644 index 000000000..300f7d316 --- /dev/null +++ b/third_party/node/src/connection_wrap.cc @@ -0,0 +1,137 @@ +#include "connection_wrap.h" + +#include "connect_wrap.h" +#include "env-inl.h" +#include "pipe_wrap.h" +#include "stream_base-inl.h" +#include "stream_wrap.h" +#include "tcp_wrap.h" +#include "util-inl.h" + +namespace node { + +using v8::Boolean; +using v8::Context; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Object; +using v8::Value; + + +template +ConnectionWrap::ConnectionWrap(Environment* env, + Local object, + ProviderType provider) + : LibuvStreamWrap(env, + object, + reinterpret_cast(&handle_), + provider) {} + + +template +void ConnectionWrap::OnConnection(uv_stream_t* handle, + int status) { + WrapType* wrap_data = static_cast(handle->data); + CHECK_NOT_NULL(wrap_data); + CHECK_EQ(&wrap_data->handle_, reinterpret_cast(handle)); + + Environment* env = wrap_data->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + // We should not be getting this callback if someone has already called + // uv_close() on the handle. + CHECK_EQ(wrap_data->persistent().IsEmpty(), false); + + Local client_handle; + + if (status == 0) { + // Instantiate the client javascript object and handle. + Local client_obj; + if (!WrapType::Instantiate(env, wrap_data, WrapType::SOCKET) + .ToLocal(&client_obj)) + return; + + // Unwrap the client javascript object. + WrapType* wrap; + ASSIGN_OR_RETURN_UNWRAP(&wrap, client_obj); + uv_stream_t* client = reinterpret_cast(&wrap->handle_); + // uv_accept can fail if the new connection has already been closed, in + // which case an EAGAIN (resource temporarily unavailable) will be + // returned. + if (uv_accept(handle, client)) + return; + + // Successful accept. Call the onconnection callback in JavaScript land. + client_handle = client_obj; + } else { + client_handle = Undefined(env->isolate()); + } + + Local argv[] = { Integer::New(env->isolate(), status), client_handle }; + wrap_data->MakeCallback(env->onconnection_string(), arraysize(argv), argv); +} + + +template +void ConnectionWrap::AfterConnect(uv_connect_t* req, + int status) { + std::unique_ptr req_wrap + (static_cast(req->data)); + CHECK_NOT_NULL(req_wrap); + WrapType* wrap = static_cast(req->handle->data); + CHECK_EQ(req_wrap->env(), wrap->env()); + Environment* env = wrap->env(); + + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + // The wrap and request objects should still be there. + CHECK_EQ(req_wrap->persistent().IsEmpty(), false); + CHECK_EQ(wrap->persistent().IsEmpty(), false); + + bool readable, writable; + + if (status) { + readable = writable = false; + } else { + readable = uv_is_readable(req->handle) != 0; + writable = uv_is_writable(req->handle) != 0; + } + + Local argv[5] = { + Integer::New(env->isolate(), status), + wrap->object(), + req_wrap->object(), + Boolean::New(env->isolate(), readable), + Boolean::New(env->isolate(), writable) + }; + + req_wrap->MakeCallback(env->oncomplete_string(), arraysize(argv), argv); +} + +template ConnectionWrap::ConnectionWrap( + Environment* env, + Local object, + ProviderType provider); + +template ConnectionWrap::ConnectionWrap( + Environment* env, + Local object, + ProviderType provider); + +template void ConnectionWrap::OnConnection( + uv_stream_t* handle, int status); + +template void ConnectionWrap::OnConnection( + uv_stream_t* handle, int status); + +template void ConnectionWrap::AfterConnect( + uv_connect_t* handle, int status); + +template void ConnectionWrap::AfterConnect( + uv_connect_t* handle, int status); + + +} // namespace node diff --git a/third_party/node/src/connection_wrap.h b/third_party/node/src/connection_wrap.h new file mode 100644 index 000000000..e91b2ab35 --- /dev/null +++ b/third_party/node/src/connection_wrap.h @@ -0,0 +1,30 @@ +#ifndef SRC_CONNECTION_WRAP_H_ +#define SRC_CONNECTION_WRAP_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "stream_wrap.h" + +namespace node { + +class Environment; + +template +class ConnectionWrap : public LibuvStreamWrap { + public: + static void OnConnection(uv_stream_t* handle, int status); + static void AfterConnect(uv_connect_t* req, int status); + + protected: + ConnectionWrap(Environment* env, + v8::Local object, + ProviderType provider); + + UVType handle_; +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CONNECTION_WRAP_H_ diff --git a/third_party/node/src/debug_utils-inl.h b/third_party/node/src/debug_utils-inl.h new file mode 100644 index 000000000..d87dd62c8 --- /dev/null +++ b/third_party/node/src/debug_utils-inl.h @@ -0,0 +1,223 @@ +#ifndef SRC_DEBUG_UTILS_INL_H_ +#define SRC_DEBUG_UTILS_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "debug_utils.h" +#include "env.h" + +#include + +namespace node { + +struct ToStringHelper { + template + static std::string Convert( + const T& value, + std::string(T::* to_string)() const = &T::ToString) { + return (value.*to_string)(); + } + template ::value, bool>::type, + typename dummy = bool> + static std::string Convert(const T& value) { return std::to_string(value); } + static std::string Convert(const char* value) { + return value != nullptr ? value : "(null)"; + } + static std::string Convert(const std::string& value) { return value; } + static std::string Convert(bool value) { return value ? "true" : "false"; } + template ::value, int>::type = 0> + static std::string BaseConvert(const T& value) { + auto v = static_cast(value); + char ret[3 * sizeof(T)]; + char* ptr = ret + 3 * sizeof(T) - 1; + *ptr = '\0'; + const char* digits = "0123456789abcdef"; + do { + unsigned digit = v & ((1 << BASE_BITS) - 1); + *--ptr = + (BASE_BITS < 4 ? static_cast('0' + digit) : digits[digit]); + } while ((v >>= BASE_BITS) != 0); + return ptr; + } + template ::value, int>::type = 0> + static std::string BaseConvert(T value) { + return Convert(std::forward(value)); + } +}; + +template +std::string ToString(const T& value) { + return ToStringHelper::Convert(value); +} + +template +std::string ToBaseString(const T& value) { + return ToStringHelper::BaseConvert(value); +} + +inline std::string SPrintFImpl(const char* format) { + const char* p = strchr(format, '%'); + if (LIKELY(p == nullptr)) return format; + CHECK_EQ(p[1], '%'); // Only '%%' allowed when there are no arguments. + + return std::string(format, p + 1) + SPrintFImpl(p + 2); +} + +template +std::string COLD_NOINLINE SPrintFImpl( // NOLINT(runtime/string) + const char* format, Arg&& arg, Args&&... args) { + const char* p = strchr(format, '%'); + CHECK_NOT_NULL(p); // If you hit this, you passed in too many arguments. + std::string ret(format, p); + // Ignore long / size_t modifiers + while (strchr("lz", *++p) != nullptr) {} + switch (*p) { + case '%': { + return ret + '%' + SPrintFImpl(p + 1, + std::forward(arg), + std::forward(args)...); + } + default: { + return ret + '%' + SPrintFImpl(p, + std::forward(arg), + std::forward(args)...); + } + case 'd': + case 'i': + case 'u': + case 's': + ret += ToString(arg); + break; + case 'o': + ret += ToBaseString<3>(arg); + break; + case 'x': + ret += ToBaseString<4>(arg); + break; + case 'X': + ret += node::ToUpper(ToBaseString<4>(arg)); + break; + case 'p': { + CHECK(std::is_pointer::type>::value); + char out[20]; + int n = snprintf(out, + sizeof(out), + "%p", + *reinterpret_cast(&arg)); + CHECK_GE(n, 0); + ret += out; + break; + } + } + return ret + SPrintFImpl(p + 1, std::forward(args)...); +} + +template +std::string COLD_NOINLINE SPrintF( // NOLINT(runtime/string) + const char* format, Args&&... args) { + return SPrintFImpl(format, std::forward(args)...); +} + +template +void COLD_NOINLINE FPrintF(FILE* file, const char* format, Args&&... args) { + FWrite(file, SPrintF(format, std::forward(args)...)); +} + +template +inline void FORCE_INLINE Debug(EnabledDebugList* list, + DebugCategory cat, + const char* format, + Args&&... args) { + if (!UNLIKELY(list->enabled(cat))) return; + FPrintF(stderr, format, std::forward(args)...); +} + +inline void FORCE_INLINE Debug(EnabledDebugList* list, + DebugCategory cat, + const char* message) { + if (!UNLIKELY(list->enabled(cat))) return; + FPrintF(stderr, "%s", message); +} + +template +inline void FORCE_INLINE +Debug(Environment* env, DebugCategory cat, const char* format, Args&&... args) { + Debug(env->enabled_debug_list(), cat, format, std::forward(args)...); +} + +inline void FORCE_INLINE Debug(Environment* env, + DebugCategory cat, + const char* message) { + Debug(env->enabled_debug_list(), cat, message); +} + +template +inline void Debug(Environment* env, + DebugCategory cat, + const std::string& format, + Args&&... args) { + Debug(env->enabled_debug_list(), + cat, + format.c_str(), + std::forward(args)...); +} + +// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that +// the FORCE_INLINE flag on them doesn't apply to the contents of this function +// as well. +// We apply COLD_NOINLINE to tell the compiler that it's not worth optimizing +// this function for speed and it should rather focus on keeping it out of +// hot code paths. In particular, we want to keep the string concatenating code +// out of the function containing the original `Debug()` call. +template +void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap, + const char* format, + Args&&... args) { + Debug(async_wrap->env(), + static_cast(async_wrap->provider_type()), + async_wrap->diagnostic_name() + " " + format + "\n", + std::forward(args)...); +} + +template +inline void FORCE_INLINE Debug(AsyncWrap* async_wrap, + const char* format, + Args&&... args) { + DCHECK_NOT_NULL(async_wrap); + DebugCategory cat = static_cast(async_wrap->provider_type()); + if (!UNLIKELY(async_wrap->env()->enabled_debug_list()->enabled(cat))) return; + UnconditionalAsyncWrapDebug(async_wrap, format, std::forward(args)...); +} + +template +inline void FORCE_INLINE Debug(AsyncWrap* async_wrap, + const std::string& format, + Args&&... args) { + Debug(async_wrap, format.c_str(), std::forward(args)...); +} + +namespace per_process { + +template +inline void FORCE_INLINE Debug(DebugCategory cat, + const char* format, + Args&&... args) { + Debug(&enabled_debug_list, cat, format, std::forward(args)...); +} + +inline void FORCE_INLINE Debug(DebugCategory cat, const char* message) { + Debug(&enabled_debug_list, cat, message); +} + +} // namespace per_process +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_DEBUG_UTILS_INL_H_ diff --git a/third_party/node/src/debug_utils.cc b/third_party/node/src/debug_utils.cc new file mode 100644 index 000000000..c4c476942 --- /dev/null +++ b/third_party/node/src/debug_utils.cc @@ -0,0 +1,516 @@ +#include "debug_utils-inl.h" // NOLINT(build/include) +#include "env-inl.h" +#include "node_internals.h" + +#ifdef __POSIX__ +#if defined(__linux__) +#include +#endif + +#ifdef __ANDROID__ +#include +#endif + +#if defined(__linux__) && !defined(__GLIBC__) || \ + defined(__UCLIBC__) || \ + defined(_AIX) +#define HAVE_EXECINFO_H 0 +#else +#define HAVE_EXECINFO_H 1 +#endif + +#if HAVE_EXECINFO_H +#include +#include +#include +#include +#include +#include +#endif + +#endif // __POSIX__ + +#if defined(__linux__) || defined(__sun) || \ + defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) +#include +#endif + +#ifdef __APPLE__ +#include // _dyld_get_image_name() +#endif // __APPLE__ + +#ifdef _AIX +#include // ld_info structure +#endif // _AIX + +#ifdef _WIN32 +#include +#include +#include +#include +#include +#include +#endif // _WIN32 + +namespace node { +namespace per_process { +EnabledDebugList enabled_debug_list; +} + +void EnabledDebugList::Parse(Environment* env) { + std::string cats; + credentials::SafeGetenv("NODE_DEBUG_NATIVE", &cats, env); + Parse(cats, true); +} + +void EnabledDebugList::Parse(const std::string& cats, bool enabled) { + std::string debug_categories = cats; + while (!debug_categories.empty()) { + std::string::size_type comma_pos = debug_categories.find(','); + std::string wanted = ToLower(debug_categories.substr(0, comma_pos)); + +#define V(name) \ + { \ + static const std::string available_category = ToLower(#name); \ + if (available_category.find(wanted) != std::string::npos) \ + set_enabled(DebugCategory::name, enabled); \ + } + + DEBUG_CATEGORY_NAMES(V) +#undef V + + if (comma_pos == std::string::npos) break; + // Use everything after the `,` as the list for the next iteration. + debug_categories = debug_categories.substr(comma_pos + 1); + } +} + +#ifdef __POSIX__ +#if HAVE_EXECINFO_H +class PosixSymbolDebuggingContext final : public NativeSymbolDebuggingContext { + public: + PosixSymbolDebuggingContext() : pagesize_(getpagesize()) { } + + SymbolInfo LookupSymbol(void* address) override { + Dl_info info; + const bool have_info = dladdr(address, &info); + SymbolInfo ret; + if (!have_info) + return ret; + + if (info.dli_sname != nullptr) { + if (char* demangled = + abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, nullptr)) { + ret.name = demangled; + free(demangled); + } else { + ret.name = info.dli_sname; + } + } + + if (info.dli_fname != nullptr) { + ret.filename = info.dli_fname; + } + + return ret; + } + + bool IsMapped(void* address) override { + void* page_aligned = reinterpret_cast( + reinterpret_cast(address) & ~(pagesize_ - 1)); + return msync(page_aligned, pagesize_, MS_ASYNC) == 0; + } + + int GetStackTrace(void** frames, int count) override { + return backtrace(frames, count); + } + + private: + uintptr_t pagesize_; +}; + +std::unique_ptr +NativeSymbolDebuggingContext::New() { + return std::make_unique(); +} + +#else // HAVE_EXECINFO_H + +std::unique_ptr +NativeSymbolDebuggingContext::New() { + return std::make_unique(); +} + +#endif // HAVE_EXECINFO_H + +#else // __POSIX__ + +class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext { + public: + Win32SymbolDebuggingContext() { + current_process_ = GetCurrentProcess(); + USE(SymInitialize(current_process_, nullptr, true)); + } + + ~Win32SymbolDebuggingContext() override { + USE(SymCleanup(current_process_)); + } + + using NameAndDisplacement = std::pair; + NameAndDisplacement WrappedSymFromAddr(DWORD64 dwAddress) const { + // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address + // Patches: + // Use `fprintf(stderr, ` instead of `printf` + // `sym.filename = pSymbol->Name` on success + // `current_process_` instead of `hProcess. + DWORD64 dwDisplacement = 0; + // Patch: made into arg - DWORD64 dwAddress = SOME_ADDRESS; + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + const auto pSymbol = reinterpret_cast(buffer); + + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYM_NAME; + + if (SymFromAddr(current_process_, dwAddress, &dwDisplacement, pSymbol)) { + // SymFromAddr returned success + return NameAndDisplacement(pSymbol->Name, dwDisplacement); + } else { + // SymFromAddr failed + const DWORD error = GetLastError(); // "eat" the error anyway +#ifdef DEBUG + fprintf(stderr, "SymFromAddr returned error : %lu\n", error); +#endif + } + // End MSDN code + + return NameAndDisplacement(); + } + + SymbolInfo WrappedGetLine(DWORD64 dwAddress) const { + SymbolInfo sym{}; + + // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address + // Patches: + // Use `fprintf(stderr, ` instead of `printf`. + // Assign values to `sym` on success. + // `current_process_` instead of `hProcess. + + // Patch: made into arg - DWORD64 dwAddress; + DWORD dwDisplacement; + IMAGEHLP_LINE64 line; + + SymSetOptions(SYMOPT_LOAD_LINES); + + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + // Patch: made into arg - dwAddress = 0x1000000; + + if (SymGetLineFromAddr64(current_process_, dwAddress, + &dwDisplacement, &line)) { + // SymGetLineFromAddr64 returned success + sym.filename = line.FileName; + sym.line = line.LineNumber; + } else { + // SymGetLineFromAddr64 failed + const DWORD error = GetLastError(); // "eat" the error anyway +#ifdef DEBUG + fprintf(stderr, "SymGetLineFromAddr64 returned error : %lu\n", error); +#endif + } + // End MSDN code + + return sym; + } + + // Fills the SymbolInfo::name of the io/out argument `sym` + std::string WrappedUnDecorateSymbolName(const char* name) const { + // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-undecorated-symbol-names + // Patches: + // Use `fprintf(stderr, ` instead of `printf`. + // return `szUndName` instead of `printf` on success + char szUndName[MAX_SYM_NAME]; + if (UnDecorateSymbolName(name, szUndName, sizeof(szUndName), + UNDNAME_COMPLETE)) { + // UnDecorateSymbolName returned success + return szUndName; + } else { + // UnDecorateSymbolName failed + const DWORD error = GetLastError(); // "eat" the error anyway +#ifdef DEBUG + fprintf(stderr, "UnDecorateSymbolName returned error %lu\n", error); +#endif + } + return nullptr; + } + + SymbolInfo LookupSymbol(void* address) override { + const DWORD64 dw_address = reinterpret_cast(address); + SymbolInfo ret = WrappedGetLine(dw_address); + std::tie(ret.name, ret.dis) = WrappedSymFromAddr(dw_address); + if (!ret.name.empty()) { + ret.name = WrappedUnDecorateSymbolName(ret.name.c_str()); + } + return ret; + } + + bool IsMapped(void* address) override { + MEMORY_BASIC_INFORMATION info; + + if (VirtualQuery(address, &info, sizeof(info)) != sizeof(info)) + return false; + + return info.State == MEM_COMMIT && info.Protect != 0; + } + + int GetStackTrace(void** frames, int count) override { + return CaptureStackBackTrace(0, count, frames, nullptr); + } + + Win32SymbolDebuggingContext(const Win32SymbolDebuggingContext&) = delete; + Win32SymbolDebuggingContext(Win32SymbolDebuggingContext&&) = delete; + Win32SymbolDebuggingContext operator=(const Win32SymbolDebuggingContext&) + = delete; + Win32SymbolDebuggingContext operator=(Win32SymbolDebuggingContext&&) + = delete; + + private: + HANDLE current_process_; +}; + +std::unique_ptr +NativeSymbolDebuggingContext::New() { + return std::unique_ptr( + new Win32SymbolDebuggingContext()); +} + +#endif // __POSIX__ + +std::string NativeSymbolDebuggingContext::SymbolInfo::Display() const { + std::ostringstream oss; + oss << name; + if (dis != 0) { + oss << "+" << dis; + } + if (!filename.empty()) { + oss << " [" << filename << ']'; + } + if (line != 0) { + oss << ":L" << line; + } + return oss.str(); +} + +void DumpBacktrace(FILE* fp) { + auto sym_ctx = NativeSymbolDebuggingContext::New(); + void* frames[256]; + const int size = sym_ctx->GetStackTrace(frames, arraysize(frames)); + for (int i = 1; i < size; i += 1) { + void* frame = frames[i]; + NativeSymbolDebuggingContext::SymbolInfo s = sym_ctx->LookupSymbol(frame); + fprintf(fp, "%2d: %p %s\n", i, frame, s.Display().c_str()); + } +} + +void CheckedUvLoopClose(uv_loop_t* loop) { + if (uv_loop_close(loop) == 0) return; + + PrintLibuvHandleInformation(loop, stderr); + + fflush(stderr); + // Finally, abort. + CHECK(0 && "uv_loop_close() while having open handles"); +} + +void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream) { + struct Info { + std::unique_ptr ctx; + FILE* stream; + size_t num_handles; + }; + + Info info { NativeSymbolDebuggingContext::New(), stream, 0 }; + + fprintf(stream, "uv loop at [%p] has open handles:\n", loop); + + uv_walk(loop, [](uv_handle_t* handle, void* arg) { + Info* info = static_cast(arg); + NativeSymbolDebuggingContext* sym_ctx = info->ctx.get(); + FILE* stream = info->stream; + info->num_handles++; + + fprintf(stream, "[%p] %s%s\n", handle, uv_handle_type_name(handle->type), + uv_is_active(handle) ? " (active)" : ""); + + void* close_cb = reinterpret_cast(handle->close_cb); + fprintf(stream, "\tClose callback: %p %s\n", + close_cb, sym_ctx->LookupSymbol(close_cb).Display().c_str()); + + fprintf(stream, "\tData: %p %s\n", + handle->data, sym_ctx->LookupSymbol(handle->data).Display().c_str()); + + // We are also interested in the first field of what `handle->data` + // points to, because for C++ code that is usually the virtual table pointer + // and gives us information about the exact kind of object we're looking at. + void* first_field = nullptr; + // `handle->data` might be any value, including `nullptr`, or something + // cast from a completely different type; therefore, check that it’s + // dereferenceable first. + if (sym_ctx->IsMapped(handle->data)) + first_field = *reinterpret_cast(handle->data); + + if (first_field != nullptr) { + fprintf(stream, "\t(First field): %p %s\n", + first_field, sym_ctx->LookupSymbol(first_field).Display().c_str()); + } + }, &info); + + fprintf(stream, "uv loop at [%p] has %zu open handles in total\n", + loop, info.num_handles); +} + +std::vector NativeSymbolDebuggingContext::GetLoadedLibraries() { + std::vector list; +#if defined(__linux__) || defined(__FreeBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) + dl_iterate_phdr( + [](struct dl_phdr_info* info, size_t size, void* data) { + auto list = static_cast*>(data); + if (*info->dlpi_name != '\0') { + list->emplace_back(info->dlpi_name); + } + return 0; + }, + &list); +#elif __APPLE__ + uint32_t i = 0; + for (const char* name = _dyld_get_image_name(i); name != nullptr; + name = _dyld_get_image_name(++i)) { + list.emplace_back(name); + } + +#elif _AIX + // We can't tell in advance how large the buffer needs to be. + // Retry until we reach too large a size (1Mb). + const unsigned int kBufferGrowStep = 4096; + MallocedBuffer buffer(kBufferGrowStep); + int rc = -1; + do { + rc = loadquery(L_GETINFO, buffer.data, buffer.size); + if (rc == 0) break; + buffer = MallocedBuffer(buffer.size + kBufferGrowStep); + } while (buffer.size < 1024 * 1024); + + if (rc == 0) { + char* buf = buffer.data; + ld_info* cur_info = nullptr; + do { + std::ostringstream str; + cur_info = reinterpret_cast(buf); + char* member_name = cur_info->ldinfo_filename + + strlen(cur_info->ldinfo_filename) + 1; + if (*member_name != '\0') { + str << cur_info->ldinfo_filename << "(" << member_name << ")"; + list.emplace_back(str.str()); + str.str(""); + } else { + list.emplace_back(cur_info->ldinfo_filename); + } + buf += cur_info->ldinfo_next; + } while (cur_info->ldinfo_next != 0); + } +#elif __sun + Link_map* p; + + if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &p) != -1) { + for (Link_map* l = p; l != nullptr; l = l->l_next) { + list.emplace_back(l->l_name); + } + } + +#elif _WIN32 + // Windows implementation - get a handle to the process. + HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, + FALSE, GetCurrentProcessId()); + if (process_handle == nullptr) { + // Cannot proceed, return an empty list. + return list; + } + // Get a list of all the modules in this process + DWORD size_1 = 0; + DWORD size_2 = 0; + // First call to get the size of module array needed + if (EnumProcessModules(process_handle, nullptr, 0, &size_1)) { + MallocedBuffer modules(size_1); + + // Second call to populate the module array + if (EnumProcessModules(process_handle, modules.data, size_1, &size_2)) { + for (DWORD i = 0; + i < (size_1 / sizeof(HMODULE)) && i < (size_2 / sizeof(HMODULE)); + i++) { + WCHAR module_name[MAX_PATH]; + // Obtain and report the full pathname for each module + if (GetModuleFileNameExW(process_handle, + modules.data[i], + module_name, + arraysize(module_name) / sizeof(WCHAR))) { + DWORD size = WideCharToMultiByte( + CP_UTF8, 0, module_name, -1, nullptr, 0, nullptr, nullptr); + char* str = new char[size]; + WideCharToMultiByte( + CP_UTF8, 0, module_name, -1, str, size, nullptr, nullptr); + list.emplace_back(str); + } + } + } + } + + // Release the handle to the process. + CloseHandle(process_handle); +#endif + return list; +} + +void FWrite(FILE* file, const std::string& str) { + auto simple_fwrite = [&]() { + // The return value is ignored because there's no good way to handle it. + fwrite(str.data(), str.size(), 1, file); + }; + + if (file != stderr && file != stdout) { + simple_fwrite(); + return; + } +#ifdef _WIN32 + HANDLE handle = + GetStdHandle(file == stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); + + // Check if stderr is something other than a tty/console + if (handle == INVALID_HANDLE_VALUE || handle == nullptr || + uv_guess_handle(_fileno(file)) != UV_TTY) { + simple_fwrite(); + return; + } + + // Get required wide buffer size + int n = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), nullptr, 0); + + std::vector wbuf(n); + MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), wbuf.data(), n); + + WriteConsoleW(handle, wbuf.data(), n, nullptr, nullptr); + return; +#elif defined(__ANDROID__) + if (file == stderr) { + __android_log_print(ANDROID_LOG_ERROR, "nodejs", "%s", str.data()); + return; + } +#endif + simple_fwrite(); +} + +} // namespace node + +extern "C" void __DumpBacktrace(FILE* fp) { + node::DumpBacktrace(fp); +} diff --git a/third_party/node/src/debug_utils.h b/third_party/node/src/debug_utils.h new file mode 100644 index 000000000..cec5eb6da --- /dev/null +++ b/third_party/node/src/debug_utils.h @@ -0,0 +1,182 @@ +#ifndef SRC_DEBUG_UTILS_H_ +#define SRC_DEBUG_UTILS_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "async_wrap.h" + +#include +#include +#include + +// Use FORCE_INLINE on functions that have a debug-category-enabled check first +// and then ideally only a single function call following it, to maintain +// performance for the common case (no debugging used). +#ifdef __GNUC__ +#define FORCE_INLINE __attribute__((always_inline)) +#define COLD_NOINLINE __attribute__((cold, noinline)) +#else +#define FORCE_INLINE +#define COLD_NOINLINE +#endif + +namespace node { +class Environment; + +template +inline std::string ToString(const T& value); + +// C++-style variant of sprintf()/fprintf() that: +// - Returns an std::string +// - Handles \0 bytes correctly +// - Supports %p and %s. %d, %i and %u are aliases for %s. +// - Accepts any class that has a ToString() method for stringification. +template +inline std::string SPrintF(const char* format, Args&&... args); +template +inline void FPrintF(FILE* file, const char* format, Args&&... args); +void FWrite(FILE* file, const std::string& str); + +// Listing the AsyncWrap provider types first enables us to cast directly +// from a provider type to a debug category. +#define DEBUG_CATEGORY_NAMES(V) \ + NODE_ASYNC_PROVIDER_TYPES(V) \ + V(DIAGNOSTICS) \ + V(HUGEPAGES) \ + V(INSPECTOR_SERVER) \ + V(INSPECTOR_PROFILER) \ + V(CODE_CACHE) \ + V(WASI) + +enum class DebugCategory { +#define V(name) name, + DEBUG_CATEGORY_NAMES(V) +#undef V + CATEGORY_COUNT +}; + +class EnabledDebugList { + public: + bool enabled(DebugCategory category) const { + DCHECK_GE(static_cast(category), 0); + DCHECK_LT(static_cast(category), + static_cast(DebugCategory::CATEGORY_COUNT)); + return enabled_[static_cast(category)]; + } + + // Uses NODE_DEBUG_NATIVE to initialize the categories. When env is not a + // nullptr, the environment variables set in the Environment are used. + // Otherwise the system environment variables are used. + void Parse(Environment* env); + + private: + // Set all categories matching cats to the value of enabled. + void Parse(const std::string& cats, bool enabled); + void set_enabled(DebugCategory category, bool enabled) { + DCHECK_GE(static_cast(category), 0); + DCHECK_LT(static_cast(category), + static_cast(DebugCategory::CATEGORY_COUNT)); + enabled_[static_cast(category)] = true; + } + + bool enabled_[static_cast(DebugCategory::CATEGORY_COUNT)] = {false}; +}; + +template +inline void FORCE_INLINE Debug(EnabledDebugList* list, + DebugCategory cat, + const char* format, + Args&&... args); + +inline void FORCE_INLINE Debug(EnabledDebugList* list, + DebugCategory cat, + const char* message); + +template +inline void FORCE_INLINE +Debug(Environment* env, DebugCategory cat, const char* format, Args&&... args); + +inline void FORCE_INLINE Debug(Environment* env, + DebugCategory cat, + const char* message); + +template +inline void Debug(Environment* env, + DebugCategory cat, + const std::string& format, + Args&&... args); + +// Used internally by the 'real' Debug(AsyncWrap*, ...) functions below, so that +// the FORCE_INLINE flag on them doesn't apply to the contents of this function +// as well. +// We apply COLD_NOINLINE to tell the compiler that it's not worth optimizing +// this function for speed and it should rather focus on keeping it out of +// hot code paths. In particular, we want to keep the string concatenating code +// out of the function containing the original `Debug()` call. +template +void COLD_NOINLINE UnconditionalAsyncWrapDebug(AsyncWrap* async_wrap, + const char* format, + Args&&... args); + +template +inline void FORCE_INLINE Debug(AsyncWrap* async_wrap, + const char* format, + Args&&... args); + +template +inline void FORCE_INLINE Debug(AsyncWrap* async_wrap, + const std::string& format, + Args&&... args); + +// Debug helper for inspecting the currently running `node` executable. +class NativeSymbolDebuggingContext { + public: + static std::unique_ptr New(); + + class SymbolInfo { + public: + std::string name; + std::string filename; + size_t line = 0; + size_t dis = 0; + + std::string Display() const; + }; + + NativeSymbolDebuggingContext() = default; + virtual ~NativeSymbolDebuggingContext() = default; + + virtual SymbolInfo LookupSymbol(void* address) { return {}; } + virtual bool IsMapped(void* address) { return false; } + virtual int GetStackTrace(void** frames, int count) { return 0; } + + NativeSymbolDebuggingContext(const NativeSymbolDebuggingContext&) = delete; + NativeSymbolDebuggingContext(NativeSymbolDebuggingContext&&) = delete; + NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&) + = delete; + NativeSymbolDebuggingContext operator=(NativeSymbolDebuggingContext&&) + = delete; + static std::vector GetLoadedLibraries(); +}; + +// Variant of `uv_loop_close` that tries to be as helpful as possible +// about giving information on currently existing handles, if there are any, +// but still aborts the process. +void CheckedUvLoopClose(uv_loop_t* loop); +void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream); + +namespace per_process { +extern EnabledDebugList enabled_debug_list; + +template +inline void FORCE_INLINE Debug(DebugCategory cat, + const char* format, + Args&&... args); + +inline void FORCE_INLINE Debug(DebugCategory cat, const char* message); +} // namespace per_process +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_DEBUG_UTILS_H_ diff --git a/third_party/node/src/diagnosticfilename-inl.h b/third_party/node/src/diagnosticfilename-inl.h new file mode 100644 index 000000000..a0d44fd56 --- /dev/null +++ b/third_party/node/src/diagnosticfilename-inl.h @@ -0,0 +1,33 @@ +#ifndef SRC_DIAGNOSTICFILENAME_INL_H_ +#define SRC_DIAGNOSTICFILENAME_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "node_internals.h" +namespace node { + +class Environment; + +inline DiagnosticFilename::DiagnosticFilename( + Environment* env, + const char* prefix, + const char* ext) : + filename_(MakeFilename(env->thread_id(), prefix, ext)) { +} + +inline DiagnosticFilename::DiagnosticFilename( + uint64_t thread_id, + const char* prefix, + const char* ext) : + filename_(MakeFilename(thread_id, prefix, ext)) { +} + +inline const char* DiagnosticFilename::operator*() const { + return filename_.c_str(); +} + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_DIAGNOSTICFILENAME_INL_H_ diff --git a/third_party/node/src/env-inl.h b/third_party/node/src/env-inl.h new file mode 100644 index 000000000..c4b64d77d --- /dev/null +++ b/third_party/node/src/env-inl.h @@ -0,0 +1,1267 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_ENV_INL_H_ +#define SRC_ENV_INL_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "aliased_buffer.h" +#include "callback_queue-inl.h" +#include "env.h" +#include "node.h" +#include "util-inl.h" +#include "uv.h" +#include "v8.h" +#include "node_perf_common.h" +#include "node_context_data.h" + +#include +#include + +#include + +namespace node { + +inline v8::Isolate* IsolateData::isolate() const { + return isolate_; +} + +inline uv_loop_t* IsolateData::event_loop() const { + return event_loop_; +} + +inline NodeArrayBufferAllocator* IsolateData::node_allocator() const { + return node_allocator_; +} + +inline MultiIsolatePlatform* IsolateData::platform() const { + return platform_; +} + +inline void IsolateData::set_worker_context(worker::Worker* context) { + CHECK_NULL(worker_context_); // Should be set only once. + worker_context_ = context; +} + +inline worker::Worker* IsolateData::worker_context() const { + return worker_context_; +} + +inline v8::Local IsolateData::async_wrap_provider(int index) const { + return async_wrap_providers_[index].Get(isolate_); +} + +inline AsyncHooks::AsyncHooks() + : async_ids_stack_(env()->isolate(), 16 * 2), + fields_(env()->isolate(), kFieldsCount), + async_id_fields_(env()->isolate(), kUidFieldsCount) { + clear_async_id_stack(); + + // Always perform async_hooks checks, not just when async_hooks is enabled. + // TODO(AndreasMadsen): Consider removing this for LTS releases. + // See discussion in https://github.com/nodejs/node/pull/15454 + // When removing this, do it by reverting the commit. Otherwise the test + // and flag changes won't be included. + fields_[kCheck] = 1; + + // kDefaultTriggerAsyncId should be -1, this indicates that there is no + // specified default value and it should fallback to the executionAsyncId. + // 0 is not used as the magic value, because that indicates a missing context + // which is different from a default context. + async_id_fields_[AsyncHooks::kDefaultTriggerAsyncId] = -1; + + // kAsyncIdCounter should start at 1 because that'll be the id the execution + // context during bootstrap (code that runs before entering uv_run()). + async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1; +} +inline AliasedUint32Array& AsyncHooks::fields() { + return fields_; +} + +inline AliasedFloat64Array& AsyncHooks::async_id_fields() { + return async_id_fields_; +} + +inline AliasedFloat64Array& AsyncHooks::async_ids_stack() { + return async_ids_stack_; +} + +v8::Local AsyncHooks::js_execution_async_resources() { + if (UNLIKELY(js_execution_async_resources_.IsEmpty())) { + js_execution_async_resources_.Reset( + env()->isolate(), v8::Array::New(env()->isolate())); + } + return PersistentToLocal::Strong(js_execution_async_resources_); +} + +v8::Local AsyncHooks::native_execution_async_resource(size_t i) { + if (i >= native_execution_async_resources_.size()) return {}; + return PersistentToLocal::Strong(native_execution_async_resources_[i]); +} + +inline void AsyncHooks::SetJSPromiseHooks(v8::Local init, + v8::Local before, + v8::Local after, + v8::Local resolve) { + js_promise_hooks_[0].Reset(env()->isolate(), init); + js_promise_hooks_[1].Reset(env()->isolate(), before); + js_promise_hooks_[2].Reset(env()->isolate(), after); + js_promise_hooks_[3].Reset(env()->isolate(), resolve); + for (auto it = contexts_.begin(); it != contexts_.end(); it++) { + if (it->IsEmpty()) { + it = contexts_.erase(it); + it--; + continue; + } + PersistentToLocal::Weak(env()->isolate(), *it) + ->SetPromiseHooks(init, before, after, resolve); + } +} + +inline v8::Local AsyncHooks::provider_string(int idx) { + return env()->isolate_data()->async_wrap_provider(idx); +} + +inline void AsyncHooks::no_force_checks() { + fields_[kCheck] -= 1; +} + +inline Environment* AsyncHooks::env() { + return Environment::ForAsyncHooks(this); +} + +// Remember to keep this code aligned with pushAsyncContext() in JS. +inline void AsyncHooks::push_async_context(double async_id, + double trigger_async_id, + v8::Local resource) { + // Since async_hooks is experimental, do only perform the check + // when async_hooks is enabled. + if (fields_[kCheck] > 0) { + CHECK_GE(async_id, -1); + CHECK_GE(trigger_async_id, -1); + } + + uint32_t offset = fields_[kStackLength]; + if (offset * 2 >= async_ids_stack_.Length()) + grow_async_ids_stack(); + async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId]; + async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId]; + fields_[kStackLength] += 1; + async_id_fields_[kExecutionAsyncId] = async_id; + async_id_fields_[kTriggerAsyncId] = trigger_async_id; + +#ifdef DEBUG + for (uint32_t i = offset; i < native_execution_async_resources_.size(); i++) + CHECK(native_execution_async_resources_[i].IsEmpty()); +#endif + + // When this call comes from JS (as a way of increasing the stack size), + // `resource` will be empty, because JS caches these values anyway, and + // we should avoid creating strong global references that might keep + // these JS resource objects alive longer than necessary. + if (!resource.IsEmpty()) { + native_execution_async_resources_.resize(offset + 1); + native_execution_async_resources_[offset].Reset(env()->isolate(), resource); + } +} + +// Remember to keep this code aligned with popAsyncContext() in JS. +inline bool AsyncHooks::pop_async_context(double async_id) { + // In case of an exception then this may have already been reset, if the + // stack was multiple MakeCallback()'s deep. + if (fields_[kStackLength] == 0) return false; + + // Ask for the async_id to be restored as a check that the stack + // hasn't been corrupted. + // Since async_hooks is experimental, do only perform the check + // when async_hooks is enabled. + if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) { + fprintf(stderr, + "Error: async hook stack has become corrupted (" + "actual: %.f, expected: %.f)\n", + async_id_fields_.GetValue(kExecutionAsyncId), + async_id); + DumpBacktrace(stderr); + fflush(stderr); + if (!env()->abort_on_uncaught_exception()) + exit(1); + fprintf(stderr, "\n"); + fflush(stderr); + ABORT_NO_BACKTRACE(); + } + + uint32_t offset = fields_[kStackLength] - 1; + async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset]; + async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1]; + fields_[kStackLength] = offset; + + if (LIKELY(offset < native_execution_async_resources_.size() && + !native_execution_async_resources_[offset].IsEmpty())) { +#ifdef DEBUG + for (uint32_t i = offset + 1; + i < native_execution_async_resources_.size(); + i++) { + CHECK(native_execution_async_resources_[i].IsEmpty()); + } +#endif + native_execution_async_resources_.resize(offset); + if (native_execution_async_resources_.size() < + native_execution_async_resources_.capacity() / 2 && + native_execution_async_resources_.size() > 16) { + native_execution_async_resources_.shrink_to_fit(); + } + } + + if (UNLIKELY(js_execution_async_resources()->Length() > offset)) { + v8::HandleScope handle_scope(env()->isolate()); + USE(js_execution_async_resources()->Set( + env()->context(), + env()->length_string(), + v8::Integer::NewFromUnsigned(env()->isolate(), offset))); + } + + return fields_[kStackLength] > 0; +} + +void AsyncHooks::clear_async_id_stack() { + v8::Isolate* isolate = env()->isolate(); + v8::HandleScope handle_scope(isolate); + if (!js_execution_async_resources_.IsEmpty()) { + USE(PersistentToLocal::Strong(js_execution_async_resources_)->Set( + env()->context(), + env()->length_string(), + v8::Integer::NewFromUnsigned(isolate, 0))); + } + native_execution_async_resources_.clear(); + native_execution_async_resources_.shrink_to_fit(); + + async_id_fields_[kExecutionAsyncId] = 0; + async_id_fields_[kTriggerAsyncId] = 0; + fields_[kStackLength] = 0; +} + +inline void AsyncHooks::AddContext(v8::Local ctx) { + ctx->SetPromiseHooks( + js_promise_hooks_[0].IsEmpty() ? + v8::Local() : + PersistentToLocal::Strong(js_promise_hooks_[0]), + js_promise_hooks_[1].IsEmpty() ? + v8::Local() : + PersistentToLocal::Strong(js_promise_hooks_[1]), + js_promise_hooks_[2].IsEmpty() ? + v8::Local() : + PersistentToLocal::Strong(js_promise_hooks_[2]), + js_promise_hooks_[3].IsEmpty() ? + v8::Local() : + PersistentToLocal::Strong(js_promise_hooks_[3])); + + size_t id = contexts_.size(); + contexts_.resize(id + 1); + contexts_[id].Reset(env()->isolate(), ctx); + contexts_[id].SetWeak(); +} + +inline void AsyncHooks::RemoveContext(v8::Local ctx) { + v8::Isolate* isolate = env()->isolate(); + v8::HandleScope handle_scope(isolate); + for (auto it = contexts_.begin(); it != contexts_.end(); it++) { + if (it->IsEmpty()) { + it = contexts_.erase(it); + it--; + continue; + } + v8::Local saved_context = + PersistentToLocal::Weak(isolate, *it); + if (saved_context == ctx) { + it->Reset(); + contexts_.erase(it); + break; + } + } +} + +// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in +// async_wrap-inl.h to avoid a circular dependency. + +inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope( + Environment* env, double default_trigger_async_id) + : async_hooks_(env->async_hooks()) { + if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) { + CHECK_GE(default_trigger_async_id, 0); + } + + old_default_trigger_async_id_ = + async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; + async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = + default_trigger_async_id; +} + +inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() { + async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = + old_default_trigger_async_id_; +} + +Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) { + return ContainerOf(&Environment::async_hooks_, hooks); +} + +inline size_t Environment::async_callback_scope_depth() const { + return async_callback_scope_depth_; +} + +inline void Environment::PushAsyncCallbackScope() { + async_callback_scope_depth_++; +} + +inline void Environment::PopAsyncCallbackScope() { + async_callback_scope_depth_--; +} + +inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate) + : fields_(isolate, kFieldsCount) {} + +inline AliasedUint32Array& ImmediateInfo::fields() { + return fields_; +} + +inline uint32_t ImmediateInfo::count() const { + return fields_[kCount]; +} + +inline uint32_t ImmediateInfo::ref_count() const { + return fields_[kRefCount]; +} + +inline bool ImmediateInfo::has_outstanding() const { + return fields_[kHasOutstanding] == 1; +} + +inline void ImmediateInfo::ref_count_inc(uint32_t increment) { + fields_[kRefCount] += increment; +} + +inline void ImmediateInfo::ref_count_dec(uint32_t decrement) { + fields_[kRefCount] -= decrement; +} + +inline TickInfo::TickInfo(v8::Isolate* isolate) + : fields_(isolate, kFieldsCount) {} + +inline AliasedUint8Array& TickInfo::fields() { + return fields_; +} + +inline bool TickInfo::has_tick_scheduled() const { + return fields_[kHasTickScheduled] == 1; +} + +inline bool TickInfo::has_rejection_to_warn() const { + return fields_[kHasRejectionToWarn] == 1; +} + +inline void Environment::AssignToContext(v8::Local context, + const ContextInfo& info) { + context->SetAlignedPointerInEmbedderData( + ContextEmbedderIndex::kEnvironment, this); + // Used by Environment::GetCurrent to know that we are on a node context. + context->SetAlignedPointerInEmbedderData( + ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr); + // Used to retrieve bindings + context->SetAlignedPointerInEmbedderData( + ContextEmbedderIndex::kBindingListIndex, &(this->bindings_)); + +#if HAVE_INSPECTOR + inspector_agent()->ContextCreated(context, info); +#endif // HAVE_INSPECTOR + + this->async_hooks()->AddContext(context); +} + +inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { + if (UNLIKELY(!isolate->InContext())) return nullptr; + v8::HandleScope handle_scope(isolate); + return GetCurrent(isolate->GetCurrentContext()); +} + +inline Environment* Environment::GetCurrent(v8::Local context) { + if (UNLIKELY(context.IsEmpty())) { + return nullptr; + } + if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <= + ContextEmbedderIndex::kContextTag)) { + return nullptr; + } + if (UNLIKELY(context->GetAlignedPointerFromEmbedderData( + ContextEmbedderIndex::kContextTag) != + Environment::kNodeContextTagPtr)) { + return nullptr; + } + return static_cast( + context->GetAlignedPointerFromEmbedderData( + ContextEmbedderIndex::kEnvironment)); +} + +inline Environment* Environment::GetCurrent( + const v8::FunctionCallbackInfo& info) { + return GetCurrent(info.GetIsolate()->GetCurrentContext()); +} + +template +inline Environment* Environment::GetCurrent( + const v8::PropertyCallbackInfo& info) { + return GetCurrent(info.GetIsolate()->GetCurrentContext()); +} + +template +inline T* Environment::GetBindingData(const v8::PropertyCallbackInfo& info) { + return GetBindingData(info.GetIsolate()->GetCurrentContext()); +} + +template +inline T* Environment::GetBindingData( + const v8::FunctionCallbackInfo& info) { + return GetBindingData(info.GetIsolate()->GetCurrentContext()); +} + +template +inline T* Environment::GetBindingData(v8::Local context) { + BindingDataStore* map = static_cast( + context->GetAlignedPointerFromEmbedderData( + ContextEmbedderIndex::kBindingListIndex)); + DCHECK_NOT_NULL(map); + auto it = map->find(T::type_name); + if (UNLIKELY(it == map->end())) return nullptr; + T* result = static_cast(it->second.get()); + DCHECK_NOT_NULL(result); + DCHECK_EQ(result->env(), GetCurrent(context)); + return result; +} + +template +inline T* Environment::AddBindingData( + v8::Local context, + v8::Local target) { + DCHECK_EQ(GetCurrent(context), this); + // This won't compile if T is not a BaseObject subclass. + BaseObjectPtr item = MakeDetachedBaseObject(this, target); + BindingDataStore* map = static_cast( + context->GetAlignedPointerFromEmbedderData( + ContextEmbedderIndex::kBindingListIndex)); + DCHECK_NOT_NULL(map); + auto result = map->emplace(T::type_name, item); + CHECK(result.second); + DCHECK_EQ(GetBindingData(context), item.get()); + return item.get(); +} + +inline Environment* Environment::GetThreadLocalEnv() { + return static_cast(uv_key_get(&thread_local_env)); +} + +inline v8::Isolate* Environment::isolate() const { + return isolate_; +} + +inline Environment* Environment::from_timer_handle(uv_timer_t* handle) { + return ContainerOf(&Environment::timer_handle_, handle); +} + +inline uv_timer_t* Environment::timer_handle() { + return &timer_handle_; +} + +inline Environment* Environment::from_immediate_check_handle( + uv_check_t* handle) { + return ContainerOf(&Environment::immediate_check_handle_, handle); +} + +inline uv_check_t* Environment::immediate_check_handle() { + return &immediate_check_handle_; +} + +inline uv_idle_t* Environment::immediate_idle_handle() { + return &immediate_idle_handle_; +} + +inline void Environment::RegisterHandleCleanup(uv_handle_t* handle, + HandleCleanupCb cb, + void* arg) { + handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg}); +} + +template +inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) { + handle_cleanup_waiting_++; + static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle"); + static_assert(offsetof(T, data) == offsetof(uv_handle_t, data), + "T is a libuv handle"); + static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb), + "T is a libuv handle"); + struct CloseData { + Environment* env; + OnCloseCallback callback; + void* original_data; + }; + handle->data = new CloseData { this, callback, handle->data }; + uv_close(reinterpret_cast(handle), [](uv_handle_t* handle) { + std::unique_ptr data { static_cast(handle->data) }; + data->env->handle_cleanup_waiting_--; + handle->data = data->original_data; + data->callback(reinterpret_cast(handle)); + }); +} + +void Environment::IncreaseWaitingRequestCounter() { + request_waiting_++; +} + +void Environment::DecreaseWaitingRequestCounter() { + request_waiting_--; + CHECK_GE(request_waiting_, 0); +} + +inline uv_loop_t* Environment::event_loop() const { + return isolate_data()->event_loop(); +} + +inline void Environment::TryLoadAddon( + const char* filename, + int flags, + const std::function& was_loaded) { + loaded_addons_.emplace_back(filename, flags); + if (!was_loaded(&loaded_addons_.back())) { + loaded_addons_.pop_back(); + } +} + +#if HAVE_INSPECTOR +inline bool Environment::is_in_inspector_console_call() const { + return is_in_inspector_console_call_; +} + +inline void Environment::set_is_in_inspector_console_call(bool value) { + is_in_inspector_console_call_ = value; +} +#endif + +inline AsyncHooks* Environment::async_hooks() { + return &async_hooks_; +} + +inline ImmediateInfo* Environment::immediate_info() { + return &immediate_info_; +} + +inline TickInfo* Environment::tick_info() { + return &tick_info_; +} + +inline uint64_t Environment::timer_base() const { + return timer_base_; +} + +inline std::shared_ptr Environment::env_vars() { + return env_vars_; +} + +inline void Environment::set_env_vars(std::shared_ptr env_vars) { + env_vars_ = env_vars; +} + +inline bool Environment::printed_error() const { + return printed_error_; +} + +inline void Environment::set_printed_error(bool value) { + printed_error_ = value; +} + +inline void Environment::set_trace_sync_io(bool value) { + trace_sync_io_ = value; +} + +inline bool Environment::abort_on_uncaught_exception() const { + return options_->abort_on_uncaught_exception; +} + +inline void Environment::set_force_context_aware(bool value) { + options_->force_context_aware = value; +} + +inline bool Environment::force_context_aware() const { + return options_->force_context_aware; +} + +inline void Environment::set_abort_on_uncaught_exception(bool value) { + options_->abort_on_uncaught_exception = value; +} + +inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() { + return should_abort_on_uncaught_toggle_; +} + +inline AliasedInt32Array& Environment::stream_base_state() { + return stream_base_state_; +} + +inline uint32_t Environment::get_next_module_id() { + return module_id_counter_++; +} +inline uint32_t Environment::get_next_script_id() { + return script_id_counter_++; +} +inline uint32_t Environment::get_next_function_id() { + return function_id_counter_++; +} + +ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope( + Environment* env) + : env_(env) { + env_->PushShouldNotAbortOnUncaughtScope(); +} + +ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() { + Close(); +} + +void ShouldNotAbortOnUncaughtScope::Close() { + if (env_ != nullptr) { + env_->PopShouldNotAbortOnUncaughtScope(); + env_ = nullptr; + } +} + +inline void Environment::PushShouldNotAbortOnUncaughtScope() { + should_not_abort_scope_counter_++; +} + +inline void Environment::PopShouldNotAbortOnUncaughtScope() { + should_not_abort_scope_counter_--; +} + +inline bool Environment::inside_should_not_abort_on_uncaught_scope() const { + return should_not_abort_scope_counter_ > 0; +} + +inline std::vector* Environment::destroy_async_id_list() { + return &destroy_async_id_list_; +} + +inline double Environment::new_async_id() { + async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1; + return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter]; +} + +inline double Environment::execution_async_id() { + return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId]; +} + +inline double Environment::trigger_async_id() { + return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId]; +} + +inline double Environment::get_default_trigger_async_id() { + double default_trigger_async_id = + async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; + // If defaultTriggerAsyncId isn't set, use the executionAsyncId + if (default_trigger_async_id < 0) + default_trigger_async_id = execution_async_id(); + return default_trigger_async_id; +} + +inline std::shared_ptr Environment::options() { + return options_; +} + +inline const std::vector& Environment::argv() { + return argv_; +} + +inline const std::vector& Environment::exec_argv() { + return exec_argv_; +} + +inline const std::string& Environment::exec_path() const { + return exec_path_; +} + +inline std::string Environment::GetCwd() { + char cwd[PATH_MAX_BYTES]; + size_t size = PATH_MAX_BYTES; + const int err = uv_cwd(cwd, &size); + + if (err == 0) { + CHECK_GT(size, 0); + return cwd; + } + + // This can fail if the cwd is deleted. In that case, fall back to + // exec_path. + const std::string& exec_path = exec_path_; + return exec_path.substr(0, exec_path.find_last_of(kPathSeparator)); +} + +#if HAVE_INSPECTOR +inline void Environment::set_coverage_directory(const char* dir) { + coverage_directory_ = std::string(dir); +} + +inline void Environment::set_coverage_connection( + std::unique_ptr connection) { + CHECK_NULL(coverage_connection_); + std::swap(coverage_connection_, connection); +} + +inline profiler::V8CoverageConnection* Environment::coverage_connection() { + return coverage_connection_.get(); +} + +inline const std::string& Environment::coverage_directory() const { + return coverage_directory_; +} + +inline void Environment::set_cpu_profiler_connection( + std::unique_ptr connection) { + CHECK_NULL(cpu_profiler_connection_); + std::swap(cpu_profiler_connection_, connection); +} + +inline profiler::V8CpuProfilerConnection* +Environment::cpu_profiler_connection() { + return cpu_profiler_connection_.get(); +} + +inline void Environment::set_cpu_prof_interval(uint64_t interval) { + cpu_prof_interval_ = interval; +} + +inline uint64_t Environment::cpu_prof_interval() const { + return cpu_prof_interval_; +} + +inline void Environment::set_cpu_prof_name(const std::string& name) { + cpu_prof_name_ = name; +} + +inline const std::string& Environment::cpu_prof_name() const { + return cpu_prof_name_; +} + +inline void Environment::set_cpu_prof_dir(const std::string& dir) { + cpu_prof_dir_ = dir; +} + +inline const std::string& Environment::cpu_prof_dir() const { + return cpu_prof_dir_; +} + +inline void Environment::set_heap_profiler_connection( + std::unique_ptr connection) { + CHECK_NULL(heap_profiler_connection_); + std::swap(heap_profiler_connection_, connection); +} + +inline profiler::V8HeapProfilerConnection* +Environment::heap_profiler_connection() { + return heap_profiler_connection_.get(); +} + +inline void Environment::set_heap_prof_name(const std::string& name) { + heap_prof_name_ = name; +} + +inline const std::string& Environment::heap_prof_name() const { + return heap_prof_name_; +} + +inline void Environment::set_heap_prof_dir(const std::string& dir) { + heap_prof_dir_ = dir; +} + +inline const std::string& Environment::heap_prof_dir() const { + return heap_prof_dir_; +} + +inline void Environment::set_heap_prof_interval(uint64_t interval) { + heap_prof_interval_ = interval; +} + +inline uint64_t Environment::heap_prof_interval() const { + return heap_prof_interval_; +} + +#endif // HAVE_INSPECTOR + +inline +std::shared_ptr> Environment::inspector_host_port() { + return inspector_host_port_; +} + +inline std::shared_ptr IsolateData::options() { + return options_; +} + +inline void IsolateData::set_options( + std::shared_ptr options) { + options_ = std::move(options); +} + +template +void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) { + auto callback = native_immediates_.CreateCallback(std::move(cb), flags); + native_immediates_.Push(std::move(callback)); + + if (flags & CallbackFlags::kRefed) { + if (immediate_info()->ref_count() == 0) + ToggleImmediateRef(true); + immediate_info()->ref_count_inc(1); + } +} + +template +void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) { + auto callback = native_immediates_threadsafe_.CreateCallback( + std::move(cb), flags); + { + Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); + native_immediates_threadsafe_.Push(std::move(callback)); + if (task_queues_async_initialized_) + uv_async_send(&task_queues_async_); + } +} + +template +void Environment::RequestInterrupt(Fn&& cb) { + auto callback = native_immediates_interrupts_.CreateCallback( + std::move(cb), CallbackFlags::kRefed); + { + Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); + native_immediates_interrupts_.Push(std::move(callback)); + if (task_queues_async_initialized_) + uv_async_send(&task_queues_async_); + } + RequestInterruptFromV8(); +} + +inline bool Environment::can_call_into_js() const { + return can_call_into_js_ && !is_stopping(); +} + +inline void Environment::set_can_call_into_js(bool can_call_into_js) { + can_call_into_js_ = can_call_into_js; +} + +inline bool Environment::has_run_bootstrapping_code() const { + return has_run_bootstrapping_code_; +} + +inline void Environment::set_has_run_bootstrapping_code(bool value) { + has_run_bootstrapping_code_ = value; +} + +inline bool Environment::has_serialized_options() const { + return has_serialized_options_; +} + +inline void Environment::set_has_serialized_options(bool value) { + has_serialized_options_ = value; +} + +inline bool Environment::is_main_thread() const { + return worker_context() == nullptr; +} + +inline bool Environment::no_native_addons() const { + return (flags_ & EnvironmentFlags::kNoNativeAddons) || + !options_->allow_native_addons; +} + +inline bool Environment::should_not_register_esm_loader() const { + return flags_ & EnvironmentFlags::kNoRegisterESMLoader; +} + +inline bool Environment::owns_process_state() const { + return flags_ & EnvironmentFlags::kOwnsProcessState; +} + +inline bool Environment::owns_inspector() const { + return flags_ & EnvironmentFlags::kOwnsInspector; +} + +inline bool Environment::tracks_unmanaged_fds() const { + return flags_ & EnvironmentFlags::kTrackUnmanagedFds; +} + +inline bool Environment::hide_console_windows() const { + return flags_ & EnvironmentFlags::kHideConsoleWindows; +} + +bool Environment::filehandle_close_warning() const { + return emit_filehandle_warning_; +} + +void Environment::set_filehandle_close_warning(bool on) { + emit_filehandle_warning_ = on; +} + +void Environment::set_source_maps_enabled(bool on) { + source_maps_enabled_ = on; +} + +bool Environment::source_maps_enabled() const { + return source_maps_enabled_; +} + +inline uint64_t Environment::thread_id() const { + return thread_id_; +} + +inline worker::Worker* Environment::worker_context() const { + return isolate_data()->worker_context(); +} + +inline void Environment::add_sub_worker_context(worker::Worker* context) { + sub_worker_contexts_.insert(context); +} + +inline void Environment::remove_sub_worker_context(worker::Worker* context) { + sub_worker_contexts_.erase(context); +} + +template +inline void Environment::ForEachWorker(Fn&& iterator) { + for (worker::Worker* w : sub_worker_contexts_) iterator(w); +} + +inline void Environment::add_refs(int64_t diff) { + task_queues_async_refs_ += diff; + CHECK_GE(task_queues_async_refs_, 0); + if (task_queues_async_refs_ == 0) + uv_unref(reinterpret_cast(&task_queues_async_)); + else + uv_ref(reinterpret_cast(&task_queues_async_)); +} + +inline bool Environment::is_stopping() const { + return is_stopping_.load(); +} + +inline void Environment::set_stopping(bool value) { + is_stopping_.store(value); +} + +inline std::list* Environment::extra_linked_bindings() { + return &extra_linked_bindings_; +} + +inline node_module* Environment::extra_linked_bindings_head() { + return extra_linked_bindings_.size() > 0 ? + &extra_linked_bindings_.front() : nullptr; +} + +inline node_module* Environment::extra_linked_bindings_tail() { + return extra_linked_bindings_.size() > 0 ? + &extra_linked_bindings_.back() : nullptr; +} + +inline const Mutex& Environment::extra_linked_bindings_mutex() const { + return extra_linked_bindings_mutex_; +} + +inline performance::PerformanceState* Environment::performance_state() { + return performance_state_.get(); +} + +inline std::unordered_map* + Environment::performance_marks() { + return &performance_marks_; +} + +inline IsolateData* Environment::isolate_data() const { + return isolate_data_; +} + +std::unordered_map>* + Environment::released_allocated_buffers() { + return &released_allocated_buffers_; +} + +inline void Environment::ThrowError(const char* errmsg) { + ThrowError(v8::Exception::Error, errmsg); +} + +inline void Environment::ThrowTypeError(const char* errmsg) { + ThrowError(v8::Exception::TypeError, errmsg); +} + +inline void Environment::ThrowRangeError(const char* errmsg) { + ThrowError(v8::Exception::RangeError, errmsg); +} + +inline void Environment::ThrowError( + v8::Local (*fun)(v8::Local), + const char* errmsg) { + v8::HandleScope handle_scope(isolate()); + isolate()->ThrowException(fun(OneByteString(isolate(), errmsg))); +} + +inline void Environment::ThrowErrnoException(int errorno, + const char* syscall, + const char* message, + const char* path) { + isolate()->ThrowException( + ErrnoException(isolate(), errorno, syscall, message, path)); +} + +inline void Environment::ThrowUVException(int errorno, + const char* syscall, + const char* message, + const char* path, + const char* dest) { + isolate()->ThrowException( + UVException(isolate(), errorno, syscall, message, path, dest)); +} + +inline v8::Local + Environment::NewFunctionTemplate(v8::FunctionCallback callback, + v8::Local signature, + v8::ConstructorBehavior behavior, + v8::SideEffectType side_effect_type) { + return v8::FunctionTemplate::New(isolate(), callback, v8::Local(), + signature, 0, behavior, side_effect_type); +} + +inline void Environment::SetMethod(v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local context = isolate()->GetCurrentContext(); + v8::Local function = + NewFunctionTemplate(callback, v8::Local(), + v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasSideEffect) + ->GetFunction(context) + .ToLocalChecked(); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->Set(context, name_string, function).Check(); + function->SetName(name_string); // NODE_SET_METHOD() compatibility. +} + +inline void Environment::SetMethodNoSideEffect(v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local context = isolate()->GetCurrentContext(); + v8::Local function = + NewFunctionTemplate(callback, v8::Local(), + v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasNoSideEffect) + ->GetFunction(context) + .ToLocalChecked(); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->Set(context, name_string, function).Check(); + function->SetName(name_string); // NODE_SET_METHOD() compatibility. +} + +inline void Environment::SetProtoMethod(v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local signature = v8::Signature::New(isolate(), that); + v8::Local t = + NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasSideEffect); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->PrototypeTemplate()->Set(name_string, t); + t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. +} + +inline void Environment::SetProtoMethodNoSideEffect( + v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local signature = v8::Signature::New(isolate(), that); + v8::Local t = + NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasNoSideEffect); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->PrototypeTemplate()->Set(name_string, t); + t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. +} + +inline void Environment::SetInstanceMethod(v8::Local that, + const char* name, + v8::FunctionCallback callback) { + v8::Local signature = v8::Signature::New(isolate(), that); + v8::Local t = + NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasSideEffect); + // kInternalized strings are created in the old space. + const v8::NewStringType type = v8::NewStringType::kInternalized; + v8::Local name_string = + v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); + that->InstanceTemplate()->Set(name_string, t); + t->SetClassName(name_string); +} + +inline void Environment::SetConstructorFunction( + v8::Local that, + const char* name, + v8::Local tmpl, + SetConstructorFunctionFlag flag) { + SetConstructorFunction(that, OneByteString(isolate(), name), tmpl, flag); +} + +inline void Environment::SetConstructorFunction( + v8::Local that, + v8::Local name, + v8::Local tmpl, + SetConstructorFunctionFlag flag) { + if (LIKELY(flag == SetConstructorFunctionFlag::SET_CLASS_NAME)) + tmpl->SetClassName(name); + that->Set( + context(), + name, + tmpl->GetFunction(context()).ToLocalChecked()).Check(); +} + +void Environment::AddCleanupHook(CleanupCallback fn, void* arg) { + auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback { + fn, arg, cleanup_hook_counter_++ + }); + // Make sure there was no existing element with these values. + CHECK_EQ(insertion_info.second, true); +} + +void Environment::RemoveCleanupHook(CleanupCallback fn, void* arg) { + CleanupHookCallback search { fn, arg, 0 }; + cleanup_hooks_.erase(search); +} + +size_t CleanupHookCallback::Hash::operator()( + const CleanupHookCallback& cb) const { + return std::hash()(cb.arg_); +} + +bool CleanupHookCallback::Equal::operator()( + const CleanupHookCallback& a, const CleanupHookCallback& b) const { + return a.fn_ == b.fn_ && a.arg_ == b.arg_; +} + +BaseObject* CleanupHookCallback::GetBaseObject() const { + if (fn_ == BaseObject::DeleteMe) + return static_cast(arg_); + else + return nullptr; +} + +template +void Environment::ForEachBaseObject(T&& iterator) { + for (const auto& hook : cleanup_hooks_) { + BaseObject* obj = hook.GetBaseObject(); + if (obj != nullptr) + iterator(obj); + } +} + +void Environment::modify_base_object_count(int64_t delta) { + base_object_count_ += delta; +} + +int64_t Environment::base_object_count() const { + return base_object_count_ - initial_base_object_count_; +} + +void Environment::set_main_utf16(std::unique_ptr str) { + CHECK(!main_utf16_); + main_utf16_ = std::move(str); +} + +void Environment::set_process_exit_handler( + std::function&& handler) { + process_exit_handler_ = std::move(handler); +} + +#define VP(PropertyName, StringValue) V(v8::Private, PropertyName) +#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) +#define VS(PropertyName, StringValue) V(v8::String, PropertyName) +#define V(TypeName, PropertyName) \ + inline \ + v8::Local IsolateData::PropertyName() const { \ + return PropertyName ## _ .Get(isolate_); \ + } + PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) + PER_ISOLATE_SYMBOL_PROPERTIES(VY) + PER_ISOLATE_STRING_PROPERTIES(VS) +#undef V +#undef VS +#undef VY +#undef VP + +#define VP(PropertyName, StringValue) V(v8::Private, PropertyName) +#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) +#define VS(PropertyName, StringValue) V(v8::String, PropertyName) +#define V(TypeName, PropertyName) \ + inline v8::Local Environment::PropertyName() const { \ + return isolate_data()->PropertyName(); \ + } + PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) + PER_ISOLATE_SYMBOL_PROPERTIES(VY) + PER_ISOLATE_STRING_PROPERTIES(VS) +#undef V +#undef VS +#undef VY +#undef VP + +#define V(PropertyName, TypeName) \ + inline v8::Local Environment::PropertyName() const { \ + return PersistentToLocal::Strong(PropertyName ## _); \ + } \ + inline void Environment::set_ ## PropertyName(v8::Local value) { \ + PropertyName ## _.Reset(isolate(), value); \ + } + ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V) + ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) +#undef V + +v8::Local Environment::context() const { + return PersistentToLocal::Strong(context_); +} + +} // namespace node + +// These two files depend on each other. Including base_object-inl.h after this +// file is the easiest way to avoid issues with that circular dependency. +#include "base_object-inl.h" + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_ENV_INL_H_ diff --git a/third_party/node/src/env.cc b/third_party/node/src/env.cc new file mode 100644 index 000000000..870aab0d8 --- /dev/null +++ b/third_party/node/src/env.cc @@ -0,0 +1,1342 @@ +#include "env.h" +#include "allocated_buffer-inl.h" +#include "async_wrap.h" +#include "base_object-inl.h" +#include "debug_utils-inl.h" +#include "diagnosticfilename-inl.h" +#include "memory_tracker-inl.h" +#include "node_buffer.h" +#include "node_context_data.h" +#include "node_errors.h" +#include "node_internals.h" +#include "node_options-inl.h" +#include "node_process-inl.h" +#include "node_v8_platform-inl.h" +#include "node_worker.h" +#include "req_wrap-inl.h" +#include "stream_base.h" +#include "tracing/agent.h" +#include "tracing/traced_value.h" +#include "util-inl.h" +#include "v8-profiler.h" + +#include +#include +#include +#include +#include + +namespace node { + +using errors::TryCatchScope; +using v8::Boolean; +using v8::Context; +using v8::EmbedderGraph; +using v8::Function; +using v8::FunctionTemplate; +using v8::HandleScope; +using v8::Integer; +using v8::Isolate; +using v8::Local; +using v8::MaybeLocal; +using v8::NewStringType; +using v8::Number; +using v8::Object; +using v8::Private; +using v8::Script; +using v8::SnapshotCreator; +using v8::StackTrace; +using v8::String; +using v8::Symbol; +using v8::TracingController; +using v8::TryCatch; +using v8::Undefined; +using v8::Value; +using worker::Worker; + +int const Environment::kNodeContextTag = 0x6e6f64; +void* const Environment::kNodeContextTagPtr = const_cast( + static_cast(&Environment::kNodeContextTag)); + +std::vector IsolateData::Serialize(SnapshotCreator* creator) { + Isolate* isolate = creator->GetIsolate(); + std::vector indexes; + HandleScope handle_scope(isolate); + // XXX(joyeecheung): technically speaking, the indexes here should be + // consecutive and we could just return a range instead of an array, + // but that's not part of the V8 API contract so we use an array + // just to be safe. + +#define VP(PropertyName, StringValue) V(Private, PropertyName) +#define VY(PropertyName, StringValue) V(Symbol, PropertyName) +#define VS(PropertyName, StringValue) V(String, PropertyName) +#define V(TypeName, PropertyName) \ + indexes.push_back(creator->AddData(PropertyName##_.Get(isolate))); + PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) + PER_ISOLATE_SYMBOL_PROPERTIES(VY) + PER_ISOLATE_STRING_PROPERTIES(VS) +#undef V +#undef VY +#undef VS +#undef VP + for (size_t i = 0; i < AsyncWrap::PROVIDERS_LENGTH; i++) + indexes.push_back(creator->AddData(async_wrap_provider(i))); + + return indexes; +} + +void IsolateData::DeserializeProperties(const std::vector* indexes) { + size_t i = 0; + HandleScope handle_scope(isolate_); + +#define VP(PropertyName, StringValue) V(Private, PropertyName) +#define VY(PropertyName, StringValue) V(Symbol, PropertyName) +#define VS(PropertyName, StringValue) V(String, PropertyName) +#define V(TypeName, PropertyName) \ + do { \ + MaybeLocal maybe_field = \ + isolate_->GetDataFromSnapshotOnce((*indexes)[i++]); \ + Local field; \ + if (!maybe_field.ToLocal(&field)) { \ + fprintf(stderr, "Failed to deserialize " #PropertyName "\n"); \ + } \ + PropertyName##_.Set(isolate_, field); \ + } while (0); + PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) + PER_ISOLATE_SYMBOL_PROPERTIES(VY) + PER_ISOLATE_STRING_PROPERTIES(VS) +#undef V +#undef VY +#undef VS +#undef VP + + for (size_t j = 0; j < AsyncWrap::PROVIDERS_LENGTH; j++) { + MaybeLocal maybe_field = + isolate_->GetDataFromSnapshotOnce((*indexes)[i++]); + Local field; + if (!maybe_field.ToLocal(&field)) { + fprintf(stderr, "Failed to deserialize AsyncWrap provider %zu\n", j); + } + async_wrap_providers_[j].Set(isolate_, field); + } +} + +void IsolateData::CreateProperties() { + // Create string and private symbol properties as internalized one byte + // strings after the platform is properly initialized. + // + // Internalized because it makes property lookups a little faster and + // because the string is created in the old space straight away. It's going + // to end up in the old space sooner or later anyway but now it doesn't go + // through v8::Eternal's new space handling first. + // + // One byte because our strings are ASCII and we can safely skip V8's UTF-8 + // decoding step. + + HandleScope handle_scope(isolate_); + +#define V(PropertyName, StringValue) \ + PropertyName##_.Set( \ + isolate_, \ + Private::New(isolate_, \ + String::NewFromOneByte( \ + isolate_, \ + reinterpret_cast(StringValue), \ + NewStringType::kInternalized, \ + sizeof(StringValue) - 1) \ + .ToLocalChecked())); + PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) +#undef V +#define V(PropertyName, StringValue) \ + PropertyName##_.Set( \ + isolate_, \ + Symbol::New(isolate_, \ + String::NewFromOneByte( \ + isolate_, \ + reinterpret_cast(StringValue), \ + NewStringType::kInternalized, \ + sizeof(StringValue) - 1) \ + .ToLocalChecked())); + PER_ISOLATE_SYMBOL_PROPERTIES(V) +#undef V +#define V(PropertyName, StringValue) \ + PropertyName##_.Set( \ + isolate_, \ + String::NewFromOneByte(isolate_, \ + reinterpret_cast(StringValue), \ + NewStringType::kInternalized, \ + sizeof(StringValue) - 1) \ + .ToLocalChecked()); + PER_ISOLATE_STRING_PROPERTIES(V) +#undef V + + // Create all the provider strings that will be passed to JS. Place them in + // an array so the array index matches the PROVIDER id offset. This way the + // strings can be retrieved quickly. +#define V(Provider) \ + async_wrap_providers_[AsyncWrap::PROVIDER_ ## Provider].Set( \ + isolate_, \ + String::NewFromOneByte( \ + isolate_, \ + reinterpret_cast(#Provider), \ + NewStringType::kInternalized, \ + sizeof(#Provider) - 1).ToLocalChecked()); + NODE_ASYNC_PROVIDER_TYPES(V) +#undef V +} + +IsolateData::IsolateData(Isolate* isolate, + uv_loop_t* event_loop, + MultiIsolatePlatform* platform, + ArrayBufferAllocator* node_allocator, + const std::vector* indexes) + : isolate_(isolate), + event_loop_(event_loop), + node_allocator_(node_allocator == nullptr ? nullptr + : node_allocator->GetImpl()), + platform_(platform) { + options_.reset( + new PerIsolateOptions(*(per_process::cli_options->per_isolate))); + + if (indexes == nullptr) { + CreateProperties(); + } else { + DeserializeProperties(indexes); + } +} + +void IsolateData::MemoryInfo(MemoryTracker* tracker) const { +#define V(PropertyName, StringValue) \ + tracker->TrackField(#PropertyName, PropertyName()); + PER_ISOLATE_SYMBOL_PROPERTIES(V) + + PER_ISOLATE_STRING_PROPERTIES(V) +#undef V + + tracker->TrackField("async_wrap_providers", async_wrap_providers_); + + if (node_allocator_ != nullptr) { + tracker->TrackFieldWithSize( + "node_allocator", sizeof(*node_allocator_), "NodeArrayBufferAllocator"); + } + tracker->TrackFieldWithSize( + "platform", sizeof(*platform_), "MultiIsolatePlatform"); + // TODO(joyeecheung): implement MemoryRetainer in the option classes. +} + +void InitThreadLocalOnce() { + CHECK_EQ(0, uv_key_create(&Environment::thread_local_env)); +} + +void TrackingTraceStateObserver::UpdateTraceCategoryState() { + if (!env_->owns_process_state() || !env_->can_call_into_js()) { + // Ideally, we’d have a consistent story that treats all threads/Environment + // instances equally here. However, tracing is essentially global, and this + // callback is called from whichever thread calls `StartTracing()` or + // `StopTracing()`. The only way to do this in a threadsafe fashion + // seems to be only tracking this from the main thread, and only allowing + // these state modifications from the main thread. + return; + } + + bool async_hooks_enabled = (*(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( + TRACING_CATEGORY_NODE1(async_hooks)))) != 0; + + Isolate* isolate = env_->isolate(); + HandleScope handle_scope(isolate); + Local cb = env_->trace_category_state_function(); + if (cb.IsEmpty()) + return; + TryCatchScope try_catch(env_); + try_catch.SetVerbose(true); + Local args[] = {Boolean::New(isolate, async_hooks_enabled)}; + USE(cb->Call(env_->context(), Undefined(isolate), arraysize(args), args)); +} + +void Environment::CreateProperties() { + HandleScope handle_scope(isolate_); + Local ctx = context(); + + { + Context::Scope context_scope(ctx); + Local templ = FunctionTemplate::New(isolate()); + templ->InstanceTemplate()->SetInternalFieldCount( + BaseObject::kInternalFieldCount); + templ->Inherit(BaseObject::GetConstructorTemplate(this)); + + set_binding_data_ctor_template(templ); + } + + // Store primordials setup by the per-context script in the environment. + Local per_context_bindings = + GetPerContextExports(ctx).ToLocalChecked(); + Local primordials = + per_context_bindings->Get(ctx, primordials_string()).ToLocalChecked(); + CHECK(primordials->IsObject()); + set_primordials(primordials.As()); + + Local prototype_string = + FIXED_ONE_BYTE_STRING(isolate(), "prototype"); + +#define V(EnvPropertyName, PrimordialsPropertyName) \ + { \ + Local ctor = \ + primordials.As() \ + ->Get(ctx, \ + FIXED_ONE_BYTE_STRING(isolate(), PrimordialsPropertyName)) \ + .ToLocalChecked(); \ + CHECK(ctor->IsObject()); \ + Local prototype = \ + ctor.As()->Get(ctx, prototype_string).ToLocalChecked(); \ + CHECK(prototype->IsObject()); \ + set_##EnvPropertyName(prototype.As()); \ + } + + V(primordials_safe_map_prototype_object, "SafeMap"); + V(primordials_safe_set_prototype_object, "SafeSet"); + V(primordials_safe_weak_map_prototype_object, "SafeWeakMap"); + V(primordials_safe_weak_set_prototype_object, "SafeWeakSet"); +#undef V + + Local process_object = + node::CreateProcessObject(this).FromMaybe(Local()); + set_process_object(process_object); +} + +std::string GetExecPath(const std::vector& argv) { + char exec_path_buf[2 * PATH_MAX]; + size_t exec_path_len = sizeof(exec_path_buf); + std::string exec_path; + if (uv_exepath(exec_path_buf, &exec_path_len) == 0) { + exec_path = std::string(exec_path_buf, exec_path_len); + } else { + exec_path = argv[0]; + } + + // On OpenBSD process.execPath will be relative unless we + // get the full path before process.execPath is used. +#if defined(__OpenBSD__) + uv_fs_t req; + req.ptr = nullptr; + if (0 == + uv_fs_realpath(nullptr, &req, exec_path.c_str(), nullptr)) { + CHECK_NOT_NULL(req.ptr); + exec_path = std::string(static_cast(req.ptr)); + } + uv_fs_req_cleanup(&req); +#endif + + return exec_path; +} + +Environment::Environment(IsolateData* isolate_data, + Local context, + const std::vector& args, + const std::vector& exec_args, + EnvironmentFlags::Flags flags, + ThreadId thread_id) + : isolate_(context->GetIsolate()), + isolate_data_(isolate_data), + immediate_info_(context->GetIsolate()), + tick_info_(context->GetIsolate()), + timer_base_(uv_now(isolate_data->event_loop())), + exec_argv_(exec_args), + argv_(args), + exec_path_(GetExecPath(args)), + should_abort_on_uncaught_toggle_(isolate_, 1), + stream_base_state_(isolate_, StreamBase::kNumStreamBaseStateFields), + flags_(flags), + thread_id_(thread_id.id == static_cast(-1) ? + AllocateEnvironmentThreadId().id : thread_id.id), + context_(context->GetIsolate(), context) { + // We'll be creating new objects so make sure we've entered the context. + HandleScope handle_scope(isolate()); + Context::Scope context_scope(context); + + // Set some flags if only kDefaultFlags was passed. This can make API version + // transitions easier for embedders. + if (flags_ & EnvironmentFlags::kDefaultFlags) { + flags_ = flags_ | + EnvironmentFlags::kOwnsProcessState | + EnvironmentFlags::kOwnsInspector; + } + + set_env_vars(per_process::system_environment); + enabled_debug_list_.Parse(this); + + // We create new copies of the per-Environment option sets, so that it is + // easier to modify them after Environment creation. The defaults are + // part of the per-Isolate option set, for which in turn the defaults are + // part of the per-process option set. + options_ = std::make_shared( + *isolate_data->options()->per_env); + inspector_host_port_ = std::make_shared>( + options_->debug_options().host_port); + + if (!(flags_ & EnvironmentFlags::kOwnsProcessState)) { + set_abort_on_uncaught_exception(false); + } + +#if HAVE_INSPECTOR + // We can only create the inspector agent after having cloned the options. + inspector_agent_ = std::make_unique(this); +#endif + + AssignToContext(context, ContextInfo("")); + + static uv_once_t init_once = UV_ONCE_INIT; + uv_once(&init_once, InitThreadLocalOnce); + uv_key_set(&thread_local_env, this); + + if (tracing::AgentWriterHandle* writer = GetTracingAgentWriter()) { + trace_state_observer_ = std::make_unique(this); + if (TracingController* tracing_controller = writer->GetTracingController()) + tracing_controller->AddTraceStateObserver(trace_state_observer_.get()); + } + + destroy_async_id_list_.reserve(512); + + performance_state_ = + std::make_unique(isolate()); + performance_state_->Mark( + performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT); + performance_state_->Mark(performance::NODE_PERFORMANCE_MILESTONE_NODE_START, + per_process::node_start_time); + performance_state_->Mark( + performance::NODE_PERFORMANCE_MILESTONE_V8_START, + performance::performance_v8_start); + + if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( + TRACING_CATEGORY_NODE1(environment)) != 0) { + auto traced_value = tracing::TracedValue::Create(); + traced_value->BeginArray("args"); + for (const std::string& arg : args) traced_value->AppendString(arg); + traced_value->EndArray(); + traced_value->BeginArray("exec_args"); + for (const std::string& arg : exec_args) traced_value->AppendString(arg); + traced_value->EndArray(); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(TRACING_CATEGORY_NODE1(environment), + "Environment", + this, + "args", + std::move(traced_value)); + } + + // By default, always abort when --abort-on-uncaught-exception was passed. + should_abort_on_uncaught_toggle_[0] = 1; + + if (!options_->force_async_hooks_checks) { + async_hooks_.no_force_checks(); + } + + // TODO(joyeecheung): deserialize when the snapshot covers the environment + // properties. + CreateProperties(); + + // This adjusts the return value of base_object_count() so that tests that + // check the count do not have to account for internally created BaseObjects. + initial_base_object_count_ = base_object_count(); +} + +Environment::~Environment() { + if (Environment** interrupt_data = interrupt_data_.load()) { + // There are pending RequestInterrupt() callbacks. Tell them not to run, + // then force V8 to run interrupts by compiling and running an empty script + // so as not to leak memory. + *interrupt_data = nullptr; + + Isolate::AllowJavascriptExecutionScope allow_js_here(isolate()); + HandleScope handle_scope(isolate()); + TryCatch try_catch(isolate()); + Context::Scope context_scope(context()); + +#ifdef DEBUG + bool consistency_check = false; + isolate()->RequestInterrupt([](Isolate*, void* data) { + *static_cast(data) = true; + }, &consistency_check); +#endif + + Local