Add Performance Support for Swift Package Manager (#8412)

* Create NanoPb code generation scripts (#8336)

* Create NanoPb code generation scripts

* Fix style and add README

* Fix copyright

* Update proto_generator.py

* Update README.md

* Create nanopb options file. (#8371)

* Create NanoPb code generation scripts

* Fix style and add README

* Fix copyright

* Update perf_metrics.options

* Update options with map

* Add generated proto files.

* Update imports.

* Convert Objective-C Classes to Nanopb (#8387)

* Convert all traces to nanopb

* Refactor for loop.

* Add set has_application_info to true.

* Incorporated comments.

* Fix style

* Create NanoPb code generation scripts (#8336)

* Create NanoPb code generation scripts

* Fix style and add README

* Fix copyright

* Update proto_generator.py

* Update README.md

* Create nanopb options file. (#8371)

* Create NanoPb code generation scripts

* Fix style and add README

* Fix copyright

* Update perf_metrics.options

* Update options with map

* Add generated proto files.

* Update imports.

* Convert Objective-C Classes to Nanopb (#8387)

* Convert all traces to nanopb

* Refactor for loop.

* Add set has_application_info to true.

* Incorporated comments.

* Fix style

* Fix style

* Convert nanopb struct to GDTCOREventDataObject and update the source code to use nanopb struct. (#8439)

* Convert all traces to nanopb

* Refactor for loop.

* WIP: nanopb conversion in FPRClient and FPREvent

* Update FPRClientTest.m

* Update FPRClient.m

* Update FPRClientTest.m

* Add set has_application_info to true.

* Remove proto imports.

* Set has_fields to be true in FPRTestUtils.m

* Completed GDTEvent conversion.

* Fix sampler tests.

* Fix style

* Refactor nanopb struct setter

* Fix style

* Fix pod-lib-lint failures.

* Update FPRClient with decoded string

* Set some "_has" fields to true.

* Add prefix to extern methods.

* Fix style.

* Update FPRClient to use trace.name without FPRDecodeString

* Fix style

* Incorporate comments.

* Integrate Performance with SPM (#8476)

* Convert all traces to nanopb

* Refactor for loop.

* WIP: nanopb conversion in FPRClient and FPREvent

* Update FPRClientTest.m

* Update FPRClient.m

* Update FPRClientTest.m

* Add set has_application_info to true.

* Remove proto imports.

* Set has_fields to be true in FPRTestUtils.m

* Completed GDTEvent conversion.

* Fix sampler tests.

* Fix style

* Refactor nanopb struct setter

* Fix style

* Fix pod-lib-lint failures.

* Update FPRClient with decoded string

* Set some "_has" fields to true.

* Add prefix to extern methods.

* Fix style.

* Update FPRClient to use trace.name without FPRDecodeString

* Fix style

* Update Package.swift

* Update Package.swift

* Update Package.swift

* Made SDK and unit tests buildable.

* Made all unit tests passing.

* Update keyWindow style.

* Add Performance to workflow.

* Update FPRUIViewControllerInstrument.h

* Incorporate comments.

* Add Performance to SwiftPMTests.

* Update style.

* Fix Unit tests and update workflow.

* Add FirebasePerformance wrapper

* Update import statement.

* Update style.

* Update performance.yml

* Create PerformanceUnit.xcscheme

* Update objc-module.m

* Update objc-module.m

* Updae objc-header.m

* Update objc-header.m

* Incorporate feedback.

* Update objc-header.m

* Organize folder structure to fix the spm tests.

* Update public import path

* Delete xcodebuild.log

* Update workflow files

* Fix failing swift-test for Perf SPM (#8507)

* Fix UIKit import

* Update FPRNetworkTraceTest.m

* Exclude TARGET_OS_MACCATALYST from objc header test

* Update main.swift

* Update main.swift

Co-authored-by: Paul Beusterien <paulbeusterien@google.com>

* Remove Protobuf dependency  (#8511)

* Remove protobuf dependency

* Update FirebasePerformance.podspec

* Incorporate comments.

* Update UIKit import

Co-authored-by: Paul Beusterien <paulbeusterien@google.com>
This commit is contained in:
Jeremy JiangandPaul Beusterien authored and GitHub committed 2021-08-10 13:41:18 -04:00
1 parent ad1cd17723
commit ec193d0150
81 files changed
+2870 -3813

No files matched your search

+48
View File
@@ -74,6 +74,34 @@ jobs:
- name: Test objc quickstart
run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/test_quickstart.sh Performance)
spm:
# Don't run on private repo unless it is a PR.
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
runs-on: macOS-latest
strategy:
matrix:
target: [iOS]
steps:
- uses: actions/checkout@v2
- name: Initialize xcodebuild
run: scripts/setup_spm_tests.sh
- name: Unit Tests
run: scripts/third_party/travis/retry.sh ./scripts/build.sh PerformanceUnit ${{ matrix.target }} spm
spm-cron:
# Don't run on private repo.
if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk'
runs-on: macOS-latest
strategy:
matrix:
target: [tvOS]
steps:
- uses: actions/checkout@v2
- name: Initialize xcodebuild
run: scripts/setup_spm_tests.sh
- name: Unit Tests
run: scripts/third_party/travis/retry.sh ./scripts/build.sh PerformanceUnit ${{ matrix.target }} spm
catalyst:
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
runs-on: macOS-latest
@@ -94,3 +122,23 @@ jobs:
run: scripts/setup_bundler.sh
- name: Build and test
run: scripts/third_party/travis/retry.sh pod spec lint FirebasePerformance.podspec --skip-tests --sources='https://github.com/firebase/SpecsTesting','https://github.com/firebase/SpecsDev.git','https://github.com/firebase/SpecsStaging.git','https://cdn.cocoapods.org/'
performance-cron-only:
# Don't run on private repo.
if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk'
runs-on: macos-latest
strategy:
matrix:
target: [ios, tvos]
flags: [
'--skip-tests --use-static-frameworks',
'--skip-tests --use-libraries'
]
needs: pod-lib-lint
steps:
- uses: actions/checkout@v2
- name: Setup Bundler
run: scripts/setup_bundler.sh
- name: PodLibLint Performance Cron
run: |
scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebasePerformance.podspec --platforms=${{ matrix.target }} ${{ matrix.flags }}
+6 -6
View File
@@ -28,8 +28,7 @@ Firebase Performance library to measure performance of Mobile and Web Apps.
base_dir = "FirebasePerformance/"
s.source_files = [
base_dir + 'Sources/**/*.[mh]',
base_dir + 'ProtoSupport/**/*.[mh]',
base_dir + 'Sources/**/*.[cmh]',
'FirebaseCore/Sources/Private/*.h',
'FirebaseInstallations/Source/Library/Private/*.h',
'FirebaseRemoteConfig/Sources/Private/*.h',
@@ -40,9 +39,10 @@ Firebase Performance library to measure performance of Mobile and Web Apps.
base_dir + 'Public/**/*.h',
]
s.public_header_files = base_dir + 'Sources/Public/*.h'
s.public_header_files = base_dir + 'Sources/Public/FirebasePerformance/*.h'
preprocessor_definitions = 'GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1 ' + 'FIRPerformance_LIB_VERSION=' + String(s.version)
preprocessor_definitions = 'FIRPerformance_LIB_VERSION=' + String(s.version)
preprocessor_definitions += ' PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1'
if ENV['FPR_UNSWIZZLE_AVAILABLE'] && ENV['FPR_UNSWIZZLE_AVAILABLE'] == '1' then
preprocessor_definitions += ' UNSWIZZLE_AVAILABLE=1'
end
@@ -64,14 +64,14 @@ Firebase Performance library to measure performance of Mobile and Web Apps.
s.dependency 'GoogleUtilities/Environment', '~> 7.4'
s.dependency 'GoogleUtilities/ISASwizzler', '~> 7.4'
s.dependency 'GoogleUtilities/MethodSwizzler', '~> 7.4'
s.dependency 'Protobuf', '~> 3.15'
s.dependency 'nanopb', '~> 2.30908.0'
s.test_spec 'unit' do |unit_tests|
unit_tests.platforms = {:ios => ios_deployment_target, :tvos => tvos_deployment_target}
unit_tests.scheme = { :code_coverage => true }
unit_tests.source_files = [
'FirebasePerformance/Tests/Unit/**/*.{m,h,plist}',
'GoogleDataTransport/GDTCORTests/Common/**/*.[hm]',
'SharedTestUtilities/*.[hm]',
]
unit_tests.resources = ['FirebasePerformance/Tests/Unit/Server/*File']
unit_tests.requires_arc = true
+3
View File
@@ -1,3 +1,6 @@
# Version 8.6.0
* Add Firebase Performance support for Swift Package Manager. (#6528)
# Version 8.2.0
* Update log messages with proper log levels.
* Fix empty values in `network_info.request_completed_time_us` field from the [data schema](https://firebase.google.com/docs/perf-mon/bigquery-export#detailed_data_schema).
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,59 @@
# Copyright 2021 Google
#
# 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.
#
# Options for perf_metric.proto
firebase.perf.v1.TraceMetric.name type:FT_POINTER
firebase.perf.v1.TraceMetric.counters type:FT_POINTER
firebase.perf.v1.TraceMetric.CountersEntry.key type:FT_POINTER
firebase.perf.v1.TraceMetric.subtraces type:FT_POINTER
firebase.perf.v1.TraceMetric.custom_attributes type:FT_POINTER
firebase.perf.v1.TraceMetric.CustomAttributesEntry.key type:FT_POINTER
firebase.perf.v1.TraceMetric.CustomAttributesEntry.value type:FT_POINTER
firebase.perf.v1.TraceMetric.perf_sessions type:FT_POINTER
firebase.perf.v1.NetworkRequestMetric.url type:FT_POINTER
firebase.perf.v1.NetworkRequestMetric.response_content_type type:FT_POINTER
firebase.perf.v1.NetworkRequestMetric.custom_attributes type:FT_POINTER
firebase.perf.v1.NetworkRequestMetric.CustomAttributesEntry.key type:FT_POINTER
firebase.perf.v1.NetworkRequestMetric.CustomAttributesEntry.value type:FT_POINTER
firebase.perf.v1.NetworkRequestMetric.perf_sessions type:FT_POINTER
firebase.perf.v1.PerfSession.session_id type:FT_POINTER
firebase.perf.v1.PerfSession.session_verbosity type:FT_POINTER
firebase.perf.v1.GaugeMetric.session_id type:FT_POINTER
firebase.perf.v1.GaugeMetric.cpu_metric_readings type:FT_POINTER
firebase.perf.v1.GaugeMetric.android_memory_readings type:FT_POINTER
firebase.perf.v1.GaugeMetric.ios_memory_readings type:FT_POINTER
firebase.perf.v1.GaugeMetadata.process_name type:FT_POINTER
firebase.perf.v1.ApplicationInfo.google_app_id type:FT_POINTER
firebase.perf.v1.ApplicationInfo.app_instance_id type:FT_POINTER
firebase.perf.v1.ApplicationInfo.custom_attributes type:FT_POINTER
firebase.perf.v1.ApplicationInfo.CustomAttributesEntry.key type:FT_POINTER
firebase.perf.v1.ApplicationInfo.CustomAttributesEntry.value type:FT_POINTER
firebase.perf.v1.WebApplicationInfo.sdk_version type:FT_POINTER
firebase.perf.v1.WebApplicationInfo.page_url type:FT_POINTER
firebase.perf.v1.AndroidApplicationInfo.package_name type:FT_POINTER
firebase.perf.v1.AndroidApplicationInfo.sdk_version type:FT_POINTER
firebase.perf.v1.AndroidApplicationInfo.version_name type:FT_POINTER
firebase.perf.v1.IosApplicationInfo.sdk_version type:FT_POINTER
firebase.perf.v1.IosApplicationInfo.bundle_short_version type:FT_POINTER
firebase.perf.v1.IosApplicationInfo.mcc_mnc type:FT_POINTER
@@ -0,0 +1,6 @@
To build the protos:
- `brew install protobuf`
- Verify version in generate_protos.sh
- `./generate_protos.sh`
Make sure to [re-generate the project](https://github.com/firebase/firebase-ios-sdk/blob/master/FirebasePerformance#to-develop-on-firebase-performance) after protos are built.
@@ -0,0 +1,56 @@
#!/bin/bash
# Copyright 2021 Google LLC
#
# 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.
#
# Example usage:
# ./generate_protos.sh <path to nanopb>
# Dependencies: git, protobuf, python-protobuf, pyinstaller
readonly DIR="$( git rev-parse --show-toplevel )"
# Current release of nanopb being used to build the CCT protos
readonly NANOPB_VERSION="0.3.9.8"
readonly NANOPB_TEMPDIR="${DIR}/FirebasePerformance/nanopb_temp"
readonly LIBRARY_DIR="${DIR}/FirebasePerformance/Sources/"
readonly PROTO_DIR="${DIR}/FirebasePerformance/ProtoSupport/Protos/"
readonly PROTOGEN_DIR="${LIBRARY_DIR}/Protogen/"
rm -rf "${NANOPB_TEMPDIR}"
echo "Downloading nanopb..."
git clone --branch "${NANOPB_VERSION}" https://github.com/nanopb/nanopb.git "${NANOPB_TEMPDIR}"
echo "Building nanopb..."
pushd "${NANOPB_TEMPDIR}"
./tools/make_mac_package.sh
GIT_DESCRIPTION=`git describe --always`-macosx-x86
NANOPB_BIN_DIR="dist/${GIT_DESCRIPTION}"
popd
echo "Removing existing generated proto files..."
rm -rf "${PROTOGEN_DIR}/*"
echo "Generating Perf_metric protos..."
python "${DIR}/FirebasePerformance/ProtoSupport/proto_generator.py" \
--nanopb \
--protos_dir="${PROTO_DIR}" \
--pythonpath="${NANOPB_TEMPDIR}/${NANOPB_BIN_DIR}/generator" \
--output_dir="${PROTOGEN_DIR}" \
--include="${PROTO_DIR}"
rm -rf "${NANOPB_TEMPDIR}"
+221
View File
@@ -0,0 +1,221 @@
#!/usr/bin/env python
# Copyright 2021 Google LLC
#
# 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.
"""Generates and massages protocol buffer outputs.
"""
from __future__ import print_function
import sys
import io
import nanopb_generator as nanopb
import os
import os.path
import shlex
from google.protobuf.descriptor_pb2 import FieldDescriptorProto
# The plugin_pb2 package loads descriptors on import, but doesn't defend
# against multiple imports. Reuse the plugin package as loaded by the
# nanopb_generator.
plugin_pb2 = nanopb.plugin_pb2
nanopb_pb2 = nanopb.nanopb_pb2
def main():
# Parse request
data = io.open(sys.stdin.fileno(), 'rb').read()
request = plugin_pb2.CodeGeneratorRequest.FromString(data)
# Preprocess inputs, changing types and nanopb defaults
options = nanopb_parse_options(request)
use_anonymous_oneof(request)
use_bytes_for_strings(request)
# Generate code
parsed_files = nanopb_parse_files(request, options)
results = nanopb_generate(request, options, parsed_files)
response = nanopb_write(results)
# Write to stdout
io.open(sys.stdout.fileno(), 'wb').write(response.SerializeToString())
def use_anonymous_oneof(request):
"""Use anonymous unions for oneofs if they're the only one in a message.
Equivalent to setting this option on messages where it applies:
option (nanopb).anonymous_oneof = true;
Args:
request: A CodeGeneratorRequest from protoc. The descriptors are modified
in place.
"""
for _, message_type in iterate_messages(request):
if len(message_type.oneof_decl) == 1:
ext = message_type.options.Extensions[nanopb_pb2.nanopb_msgopt]
ext.anonymous_oneof = True
def use_bytes_for_strings(request):
"""Always use the bytes type instead of string.
By default, nanopb renders proto strings as having the C type char* and does
not include a separate size field, getting the length of the string via
strlen(). Unfortunately this prevents using strings with embedded nulls,
which is something the wire format supports.
Fortunately, string and bytes proto fields are identical on the wire and
nanopb's bytes representation does have an explicit length, so this function
changes the types of all string fields to bytes. The generated code will now
contain pb_bytes_array_t.
There's no nanopb or proto option to control this behavior. The equivalent
would be to hand edit all the .proto files :-(.
Args:
request: A CodeGeneratorRequest from protoc. The descriptors are modified
in place.
"""
for names, message_type in iterate_messages(request):
for field in message_type.field:
if field.type == FieldDescriptorProto.TYPE_STRING:
field.type = FieldDescriptorProto.TYPE_BYTES
def iterate_messages(request):
"""Iterates over all messages in all files in the request.
Args:
request: A CodeGeneratorRequest passed by protoc.
Yields:
names: a nanopb.Names object giving a qualified name for the message
message_type: a DescriptorProto for the message.
"""
for fdesc in request.proto_file:
for names, message_type in nanopb.iterate_messages(fdesc):
yield names, message_type
def nanopb_parse_options(request):
"""Parses nanopb_generator command-line options from the given request.
Args:
request: A CodeGeneratorRequest passed by protoc.
Returns:
Nanopb's options object, obtained via optparser.
"""
# Parse options the same as nanopb_generator.main_plugin() does.
args = shlex.split(request.parameter)
options, _ = nanopb.optparser.parse_args(args)
# Force certain options
options.extension = '.nanopb'
options.verbose = True
# Replicate options setup from nanopb_generator.main_plugin.
nanopb.Globals.verbose_options = options.verbose
# Google's protoc does not currently indicate the full path of proto files.
# Instead always add the main file path to the search dirs, that works for
# the common case.
options.options_path.append(os.path.dirname(request.file_to_generate[0]))
return options
def nanopb_parse_files(request, options):
"""Parses the files in the given request into nanopb ProtoFile objects.
Args:
request: A CodeGeneratorRequest, as passed by protoc.
options: The command-line options from nanopb_parse_options.
Returns:
A dictionary of filename to nanopb.ProtoFile objects, each one representing
the parsed form of a FileDescriptor in the request.
"""
# Process any include files first, in order to have them
# available as dependencies
parsed_files = {}
for fdesc in request.proto_file:
parsed_files[fdesc.name] = nanopb.parse_file(fdesc.name, fdesc, options)
return parsed_files
def nanopb_generate(request, options, parsed_files):
"""Generates C sources from the given parsed files.
Args:
request: A CodeGeneratorRequest, as passed by protoc.
options: The command-line options from nanopb_parse_options.
parsed_files: A dictionary of filename to nanopb.ProtoFile, as returned by
nanopb_parse_files().
Returns:
A list of nanopb output dictionaries, each one representing the code
generation result for each file to generate. The output dictionaries have
the following form:
{
'headername': Name of header file, ending in .h,
'headerdata': Contents of the header file,
'sourcename': Name of the source code file, ending in .c,
'sourcedata': Contents of the source code file
}
"""
output = []
for filename in request.file_to_generate:
for fdesc in request.proto_file:
if fdesc.name == filename:
results = nanopb.process_file(filename, fdesc, options, parsed_files)
output.append(results)
return output
def nanopb_write(results):
"""Translates nanopb output dictionaries to a CodeGeneratorResponse.
Args:
results: A list of generated source dictionaries, as returned by
nanopb_generate().
Returns:
A CodeGeneratorResponse describing the result of the code generation
process to protoc.
"""
response = plugin_pb2.CodeGeneratorResponse()
for result in results:
f = response.file.add()
f.name = result['headername']
f.content = result['headerdata']
f = response.file.add()
f.name = result['sourcename']
f.content = result['sourcedata']
return response
if __name__ == '__main__':
main()
@@ -0,0 +1,324 @@
#! /usr/bin/env python
# Copyright 2021 Google LLC
#
# 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.
"""Generates and massages protocol buffer outputs.
Example usage:
python FirebasePerformance/ProtoSupport/proto_generator.py \
--nanopb \
--protos_dir=FirebasePerformance/ProtoSupport/Protos/ \
--pythonpath=~/Downloads/nanopb-0.3.9.8-macosx-x86/generator/ \
--output_dir=FirebasePerformance/Sources//Protogen/ \
--include=FirebasePerformance/ProtoSupport/Protos/
"""
from __future__ import print_function
import sys
import argparse
import os
import os.path
import re
import subprocess
OBJC_GENERATOR='nanopb_objc_generator.py'
COPYRIGHT_NOTICE = '''
/*
* Copyright 2021 Google LLC
*
* 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.
*/
'''.lstrip()
def main():
parser = argparse.ArgumentParser(
description='Generates proto messages.')
parser.add_argument(
'--nanopb', action='store_true',
help='Generates nanopb messages.')
parser.add_argument(
'--objc', action='store_true',
help='Generates Objective-C messages.')
parser.add_argument(
'--protos_dir',
help='Source directory containing .proto files.')
parser.add_argument(
'--output_dir', '-d',
help='Directory to write files; subdirectories will be created.')
parser.add_argument(
'--protoc', default='protoc',
help='Location of the protoc executable')
parser.add_argument(
'--pythonpath',
help='Location of the protoc python library.')
parser.add_argument(
'--include', '-I', action='append', default=[],
help='Adds INCLUDE to the proto path.')
args = parser.parse_args()
if args.nanopb is None and args.objc is None:
parser.print_help()
sys.exit(1)
if args.protos_dir is None:
root_dir = os.path.abspath(os.path.dirname(__file__))
args.protos_dir = os.path.join(root_dir, 'protos')
if args.output_dir is None:
root_dir = os.path.abspath(os.path.dirname(__file__))
args.output_dir = os.path.join(root_dir, 'protogen-please-supply-an-outputdir')
all_proto_files = collect_files(args.protos_dir, '.proto')
if args.nanopb:
NanopbGenerator(args, all_proto_files).run()
proto_files = remove_well_known_protos(all_proto_files)
if args.objc:
ObjcProtobufGenerator(args, proto_files).run()
class NanopbGenerator(object):
"""Builds and runs the nanopb plugin to protoc."""
def __init__(self, args, proto_files):
self.args = args
self.proto_files = proto_files
def run(self):
"""Performs the action of the generator."""
nanopb_out = os.path.join(self.args.output_dir, 'nanopb')
mkdir(nanopb_out)
self.__run_generator(nanopb_out)
sources = collect_files(nanopb_out, '.nanopb.h', '.nanopb.c')
post_process_files(
sources,
add_copyright,
nanopb_remove_extern_c,
nanopb_rename_delete,
nanopb_use_module_import
)
def __run_generator(self, out_dir):
"""Invokes protoc using the nanopb plugin."""
cmd = protoc_command(self.args)
gen = os.path.join(os.path.dirname(__file__), OBJC_GENERATOR)
cmd.append('--plugin=protoc-gen-nanopb=%s' % gen)
nanopb_flags = [
'--extension=.nanopb',
'--source-extension=.c',
'--no-timestamp'
]
nanopb_flags.extend(['-I%s' % path for path in self.args.include])
cmd.append('--nanopb_out=%s:%s' % (' '.join(nanopb_flags), out_dir))
cmd.extend(self.proto_files)
run_protoc(self.args, cmd)
def protoc_command(args):
"""Composes the initial protoc command-line including its include path."""
cmd = [args.protoc]
if args.include is not None:
cmd.extend(['-I=%s' % path for path in args.include])
return cmd
def run_protoc(args, cmd):
"""Actually runs the given protoc command.
Args:
args: The command-line args (including pythonpath)
cmd: The command to run expressed as a list of strings
"""
kwargs = {}
if args.pythonpath:
env = os.environ.copy()
old_path = env.get('PYTHONPATH')
env['PYTHONPATH'] = os.path.expanduser(args.pythonpath)
if old_path is not None:
env['PYTHONPATH'] += os.pathsep + old_path
kwargs['env'] = env
try:
print(subprocess.check_output(cmd, stderr=subprocess.STDOUT, **kwargs))
except subprocess.CalledProcessError as error:
print('command failed: ', ' '.join(cmd), '\nerror: ', error.output)
def remove_well_known_protos(filenames):
"""Remove "well-known" protos for objc.
On those platforms we get these for free as a part of the protobuf runtime.
We only need them for nanopb.
Args:
filenames: A list of filenames, each naming a .proto file.
Returns:
The filenames with members of google/protobuf removed.
"""
return [f for f in filenames if 'protos/google/protobuf/' not in f]
def post_process_files(filenames, *processors):
for filename in filenames:
lines = []
with open(filename, 'r') as fd:
lines = fd.readlines()
for processor in processors:
lines = processor(lines)
write_file(filename, lines)
def write_file(filename, lines):
mkdir(os.path.dirname(filename))
with open(filename, 'w') as fd:
fd.write(''.join(lines))
def add_copyright(lines):
"""Adds a copyright notice to the lines."""
result = [COPYRIGHT_NOTICE, '\n']
result.extend(lines)
return result
def nanopb_remove_extern_c(lines):
"""Removes extern "C" directives from nanopb code.
Args:
lines: A nanobp-generated source file, split into lines.
Returns:
A list of strings, similar to the input but modified to remove extern "C".
"""
result = []
state = 'initial'
for line in lines:
if state == 'initial':
if '#ifdef __cplusplus' in line:
state = 'in-ifdef'
continue
result.append(line)
elif state == 'in-ifdef':
if '#endif' in line:
state = 'initial'
return result
def nanopb_rename_delete(lines):
"""Renames a delete symbol to delete_.
If a proto uses a field named 'delete', nanopb happily uses that in the
message definition. Works fine for C; not so much for C++.
Args:
lines: The lines to fix.
Returns:
The lines, fixed.
"""
delete_keyword = re.compile(r'\bdelete\b')
return [delete_keyword.sub('delete_', line) for line in lines]
def nanopb_use_module_import(lines):
"""Changes #include <pb.h> to include <nanopb/pb.h>""" # Don't let Copybara alter these lines.
return [line.replace('#include <pb.h>', '{}include <nanopb/pb.h>'.format("#")) for line in lines]
def strip_trailing_whitespace(lines):
"""Removes trailing whitespace from the given lines."""
return [line.rstrip() + '\n' for line in lines]
def objc_flatten_imports(lines):
"""Flattens the import statements for compatibility with CocoaPods."""
long_import = re.compile(r'#import ".*/')
return [long_import.sub('#import "', line) for line in lines]
def objc_strip_extension_registry(lines):
"""Removes extensionRegistry methods from the classes."""
skip = False
result = []
for line in lines:
if '+ (GPBExtensionRegistry*)extensionRegistry {' in line:
skip = True
if not skip:
result.append(line)
elif line == '}\n':
skip = False
return result
def collect_files(root_dir, *extensions):
"""Finds files with the given extensions in the root_dir.
Args:
root_dir: The directory from which to start traversing.
*extensions: Filename extensions (including the leading dot) to find.
Returns:
A list of filenames, all starting with root_dir, that have one of the given
extensions.
"""
result = []
for root, _, files in os.walk(root_dir):
for basename in files:
for ext in extensions:
if basename.endswith(ext):
filename = os.path.join(root, basename)
result.append(filename)
return result
def mkdir(dirname):
if not os.path.isdir(dirname):
os.makedirs(dirname)
if __name__ == '__main__':
main()
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
FOUNDATION_EXTERN NSString *__nonnull const kFPRAppStartTraceName;
FOUNDATION_EXTERN NSString *__nonnull const kFPRAppStartStageNameTimeToUI;
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FIRPerformanceAttributable.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformanceAttributable.h"
/**
* Extension that is added on top of the class FIRPerformance to make certain methods used
+1 -1
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
#import "FirebasePerformance/Sources/FIRPerformance_Private.h"
@@ -13,7 +13,7 @@
// limitations under the License.
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
/**
* Extension that is added on top of the class FIRPerformances to make the private properties
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
@class FPRGDTLogger;
@class FPRConfigurations;
@@ -62,9 +62,9 @@
*/
+ (void)cleanupClearcutCacheDirectory;
/** Performs post processing and logs a FPRMSGPerfMetric object to Google Data Transport.
* @param event Reference to a FPRMSGPerfMetric proto object.
/** Performs post processing and logs a firebase_perf_v1_PerfMetric object to Google Data Transport.
* @param event Reference to a firebase_perf_v1_PerfMetric proto object.
*/
- (void)processAndLogEvent:(FPRMSGPerfMetric *)event;
- (void)processAndLogEvent:(firebase_perf_v1_PerfMetric)event;
@end
+1 -1
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
#import "FirebasePerformance/Sources/FPRConfiguration.h"
#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager.h"
+30 -26
View File
@@ -25,18 +25,16 @@
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags.h"
#import "FirebasePerformance/Sources/FPRConsoleLogger.h"
#import "FirebasePerformance/Sources/FPRProtoUtils.h"
#import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRInstrumentation.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTLogger.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
@interface FPRClient ()
/** The original configuration object used to initialize the client. */
@@ -172,17 +170,17 @@
}
if ([trace isCompleteAndValid]) {
dispatch_group_async(self.eventsQueueGroup, self.eventsQueue, ^{
FPRMSGPerfMetric *metric = FPRGetPerfMetricMessage(self.config.appID);
metric.traceMetric = FPRGetTraceMetric(trace);
metric.applicationInfo.applicationProcessState =
FPRApplicationProcessState(trace.backgroundTraceState);
firebase_perf_v1_PerfMetric metric = FPRGetPerfMetricMessage(self.config.appID);
FPRSetTraceMetric(&metric, FPRGetTraceMetric(trace));
FPRSetApplicationProcessState(&metric,
FPRApplicationProcessState(trace.backgroundTraceState));
// Log the trace metric with its console URL.
if ([trace.name hasPrefix:kFPRPrefixForScreenTraceName]) {
FPRLogInfo(kFPRClientMetricLogged,
@"Logging trace metric - %@ %.4fms. In a minute, visit the Firebase console to "
@"view your data: %@",
metric.traceMetric.name, metric.traceMetric.durationUs / 1000.0,
trace.name, metric.trace_metric.duration_us / 1000.0,
[FPRConsoleURLGenerator generateScreenTraceURLWithProjectID:self.projectID
bundleID:self.bundleID
traceName:trace.name]);
@@ -190,7 +188,7 @@
FPRLogInfo(kFPRClientMetricLogged,
@"Logging trace metric - %@ %.4fms. In a minute, visit the Firebase console to "
@"view your data: %@",
metric.traceMetric.name, metric.traceMetric.durationUs / 1000.0,
trace.name, metric.trace_metric.duration_us / 1000.0,
[FPRConsoleURLGenerator generateCustomTraceURLWithProjectID:self.projectID
bundleID:self.bundleID
traceName:trace.name]);
@@ -209,22 +207,24 @@
return;
}
dispatch_group_async(self.eventsQueueGroup, self.eventsQueue, ^{
FPRMSGNetworkRequestMetric *networkRequestMetric = FPRGetNetworkRequestMetric(trace);
if (networkRequestMetric) {
int64_t duration = networkRequestMetric.hasTimeToResponseCompletedUs
? networkRequestMetric.timeToResponseCompletedUs
if ([trace isValid]) {
firebase_perf_v1_NetworkRequestMetric networkRequestMetric =
FPRGetNetworkRequestMetric(trace);
int64_t duration = networkRequestMetric.has_time_to_response_completed_us
? networkRequestMetric.time_to_response_completed_us
: 0;
NSString *responseCode = networkRequestMetric.hasHTTPResponseCode
? [@(networkRequestMetric.HTTPResponseCode) stringValue]
NSString *responseCode = networkRequestMetric.has_http_response_code
? [@(networkRequestMetric.http_response_code) stringValue]
: @"UNKNOWN";
FPRLogInfo(kFPRClientMetricLogged,
@"Logging network request trace - %@, Response code: %@, %.4fms",
networkRequestMetric.URL, responseCode, duration / 1000.0);
FPRMSGPerfMetric *metric = FPRGetPerfMetricMessage(self.config.appID);
metric.networkRequestMetric = networkRequestMetric;
metric.applicationInfo.applicationProcessState =
FPRApplicationProcessState(trace.backgroundTraceState);
FPRDecodeString(networkRequestMetric.url), responseCode, duration / 1000.0);
firebase_perf_v1_PerfMetric metric = FPRGetPerfMetricMessage(self.config.appID);
FPRSetNetworkRequestMetric(&metric, networkRequestMetric);
FPRSetApplicationProcessState(&metric,
FPRApplicationProcessState(trace.backgroundTraceState));
[self processAndLogEvent:metric];
}
});
@@ -236,9 +236,12 @@
return;
}
dispatch_group_async(self.eventsQueueGroup, self.eventsQueue, ^{
FPRMSGPerfMetric *metric = FPRGetPerfMetricMessage(self.config.appID);
FPRMSGGaugeMetric *gaugeMetric = FPRGetGaugeMetric(gaugeData, sessionId);
metric.gaugeMetric = gaugeMetric;
firebase_perf_v1_PerfMetric metric = FPRGetPerfMetricMessage(self.config.appID);
firebase_perf_v1_GaugeMetric gaugeMetric = firebase_perf_v1_GaugeMetric_init_default;
if ((gaugeData != nil && gaugeData.count != 0) && (sessionId != nil && sessionId.length != 0)) {
gaugeMetric = FPRGetGaugeMetric(gaugeData, sessionId);
}
FPRSetGaugeMetric(&metric, gaugeMetric);
[self processAndLogEvent:metric];
});
@@ -246,7 +249,7 @@
[[FPRSessionManager sharedInstance] renewSessionIdIfRunningTooLong];
}
- (void)processAndLogEvent:(FPRMSGPerfMetric *)event {
- (void)processAndLogEvent:(firebase_perf_v1_PerfMetric)event {
BOOL tracingEnabled = self.configuration.isDataCollectionEnabled;
if (!tracingEnabled) {
FPRLogError(kFPRClientPerfNotConfigured, @"Dropping event since data collection is disabled.");
@@ -268,6 +271,7 @@
});
// Attempts to dispatch events if successfully retrieve installation ID.
__block firebase_perf_v1_PerfMetric curEvent = event;
[self.installations
installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) {
if (error) {
@@ -275,7 +279,7 @@
error.description);
} else {
dispatch_group_async(self.eventsQueueGroup, self.eventsQueue, ^{
event.applicationInfo.appInstanceId = identifier;
curEvent.application_info.app_instance_id = FPREncodeString(identifier);
[self.gdtLogger logEvent:event];
});
}
@@ -89,4 +89,7 @@ FOUNDATION_EXTERN NSString* const kFPRMemoryCollection;
// FPRSDKConfiguration message codes.
FOUNDATION_EXTERN NSString* const kFPRSDKFeaturesBlock;
// FPRGDTEvent message codes.
FOUNDATION_EXTERN NSString* const kFPRTransportBytesError;
NS_ASSUME_NONNULL_END
@@ -81,3 +81,6 @@ NSString* const kFPRMemoryCollection = @"I-PRF900004";
// FPRSDKConfiguration message codes.
NSString* const kFPRSDKFeaturesBlock = @"I-PRF910001";
// FPRGDTEvent message codes.
NSString* const kFPRTransportBytesError = @"I-PRF920001";
@@ -0,0 +1,191 @@
// Copyright 2021 Google LLC
//
// 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 <TargetConditionals.h>
#if __has_include("CoreTelephony/CTTelephonyNetworkInfo.h") && !TARGET_OS_MACCATALYST
#define TARGET_HAS_MOBILE_CONNECTIVITY
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#endif
#import "FirebasePerformance/Sources/AppActivity/FPRTraceBackgroundActivityTracker.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
/**nanopb struct of encoded NSDictionary<NSString *, NSString *>.*/
typedef struct {
pb_bytes_array_t* _Nonnull key;
pb_bytes_array_t* _Nonnull value;
} StringToStringMap;
/**nanopb struct of encoded NSDictionary<NSString *, NSNumber *>.*/
typedef struct {
pb_bytes_array_t* _Nonnull key;
bool has_value;
int64_t value;
} StringToNumberMap;
/** Callocs a pb_bytes_array and copies the given NSData bytes into the bytes array.
*
* @note Memory needs to be free manually, through pb_free or pb_release.
* @param data The data to copy into the new bytes array.
* @return pb_byte array
*/
extern pb_bytes_array_t* _Nullable FPREncodeData(NSData* _Nonnull data);
/** Callocs a pb_bytes_array and copies the given NSString's bytes into the bytes array.
*
* @note Memory needs to be free manually, through pb_free or pb_release.
* @param string The string to encode as pb_bytes.
* @return pb_byte array
*/
extern pb_bytes_array_t* _Nullable FPREncodeString(NSString* _Nonnull string);
/** Creates a NSData object by copying the given bytes array and returns the reference.
*
* @param pbData The pbData to dedoded as NSData
* @return A reference to NSData
*/
extern NSData* _Nullable FPRDecodeData(pb_bytes_array_t* _Nonnull pbData);
/** Creates a NSString object by copying the given bytes array and returns the reference.
*
* @param pbData The pbData to dedoded as NSString
* @return A reference to the NSString
*/
extern NSString* _Nullable FPRDecodeString(pb_bytes_array_t* _Nonnull pbData);
/** Creates a NSDictionary by copying the given bytes from the StringToStringMap object and returns
* the reference.
*
* @param map The reference to a StringToStringMap object to be decoded.
* @param count The number of entries in the dictionary.
* @return A reference to the dictionary
*/
extern NSDictionary<NSString*, NSString*>* _Nullable FPRDecodeStringToStringMap(
StringToStringMap* _Nullable map, NSInteger count);
/** Callocs a nanopb StringToStringMap and copies the given NSDictionary bytes into the
* StringToStringMap.
*
* @param dict The dict to copy into the new StringToStringMap.
* @return A reference to StringToStringMap
*/
extern StringToStringMap* _Nullable FPREncodeStringToStringMap(NSDictionary* _Nullable dict);
/** Creates a NSDictionary by copying the given bytes from the StringToNumberMap object and returns
* the reference.
*
* @param map The reference to a StringToNumberMap object to be decoded.
* @param count The number of entries in the dictionary.
* @return A reference to the dictionary
*/
extern NSDictionary<NSString*, NSNumber*>* _Nullable FPRDecodeStringToNumberMap(
StringToNumberMap* _Nullable map, NSInteger count);
/** Callocs a nanopb StringToNumberMap and copies the given NSDictionary bytes into the
* StringToStringMap.
*
* @param dict The dict to copy into the new StringToNumberMap.
* @return A reference to StringToNumberMap
*/
extern StringToNumberMap* _Nullable FPREncodeStringToNumberMap(NSDictionary* _Nullable dict);
/** Creates a new firebase_perf_v1_PerfMetric struct populated with system metadata.
* @param appID The Google app id to put into the message
* @return A firebase_perf_v1_PerfMetric struct.
*/
extern firebase_perf_v1_PerfMetric FPRGetPerfMetricMessage(NSString* _Nonnull appID);
/** Creates a new firebase_perf_v1_ApplicationInfo struct populated with system metadata.
* @return A firebase_perf_v1_ApplicationInfo struct.
*/
extern firebase_perf_v1_ApplicationInfo FPRGetApplicationInfoMessage(void);
/** Converts the FIRTrace object to a firebase_perf_v1_TraceMetric struct.
* @return A firebase_perf_v1_TraceMetric struct.
*/
extern firebase_perf_v1_TraceMetric FPRGetTraceMetric(FIRTrace* _Nonnull trace);
/** Converts the FPRNetworkTrace object to a firebase_perf_v1_NetworkRequestMetric struct.
* @return A firebase_perf_v1_NetworkRequestMetric struct.
*/
extern firebase_perf_v1_NetworkRequestMetric FPRGetNetworkRequestMetric(
FPRNetworkTrace* _Nonnull trace);
/** Converts the gaugeData array object to a firebase_perf_v1_GaugeMetric struct.
* @return A firebase_perf_v1_GaugeMetric struct.
*/
extern firebase_perf_v1_GaugeMetric FPRGetGaugeMetric(NSArray* _Nonnull gaugeData,
NSString* _Nonnull sessionId);
/** Converts the FPRTraceState to a firebase_perf_v1_ApplicationProcessState struct.
* @return A firebase_perf_v1_ApplicationProcessState struct.
*/
extern firebase_perf_v1_ApplicationProcessState FPRApplicationProcessState(FPRTraceState state);
/** Populate a firebase_perf_v1_PerfMetric object with the given firebase_perf_v1_ApplicationInfo.
*
* @param perfMetric The reference to a firebase_perf_v1_PerfMetric object to be populated.
* @param appInfo The firebase_perf_v1_ApplicationInfo object that will be added to
* firebase_perf_v1_PerfMetric.
*/
extern void FPRSetApplicationInfo(firebase_perf_v1_PerfMetric* _Nonnull perfMetric,
firebase_perf_v1_ApplicationInfo appInfo);
/** Populate a firebase_perf_v1_PerfMetric object with the given firebase_perf_v1_TraceMetric.
*
* @param perfMetric The reference to firebase_perf_v1_PerfMetric to be populated.
* @param traceMetric The firebase_perf_v1_TraceMetric object that will be added to
* firebase_perf_v1_PerfMetric.
*/
extern void FPRSetTraceMetric(firebase_perf_v1_PerfMetric* _Nonnull perfMetric,
firebase_perf_v1_TraceMetric traceMetric);
/** Populate a firebase_perf_v1_PerfMetric object with the given
* firebase_perf_v1_NetworkRequestMetric.
*
* @param perfMetric The reference to a firebase_perf_v1_PerfMetric object to be populated.
* @param networkMetric The firebase_perf_v1_NetworkRequestMetric object that will be added to
* firebase_perf_v1_PerfMetric.
*/
extern void FPRSetNetworkRequestMetric(firebase_perf_v1_PerfMetric* _Nonnull perfMetric,
firebase_perf_v1_NetworkRequestMetric networkMetric);
/** Populate a firebase_perf_v1_PerfMetric object with the given firebase_perf_v1_GaugeMetric.
*
* @param perfMetric The reference to a firebase_perf_v1_PerfMetric object to be populated.
* @param gaugeMetric The firebase_perf_v1_GaugeMetric object that will be added to
* firebase_perf_v1_PerfMetric.
*/
extern void FPRSetGaugeMetric(firebase_perf_v1_PerfMetric* _Nonnull perfMetric,
firebase_perf_v1_GaugeMetric gaugeMetric);
/** Populate a firebase_perf_v1_PerfMetric object with the given
* firebase_perf_v1_ApplicationProcessState.
*
* @param perfMetric The reference to a firebase_perf_v1_PerfMetric object to be populated.
* @param state The firebase_perf_v1_ApplicationProcessState object that will be added to
* firebase_perf_v1_PerfMetric.
*/
extern void FPRSetApplicationProcessState(firebase_perf_v1_PerfMetric* _Nonnull perfMetric,
firebase_perf_v1_ApplicationProcessState state);
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
/** Obtain a CTTelephonyNetworkInfo object to determine device network attributes.
* @return CTTelephonyNetworkInfo object.
*/
extern CTTelephonyNetworkInfo* _Nullable FPRNetworkInfo(void);
#endif
@@ -0,0 +1,535 @@
// Copyright 2021 Google LLC
//
// 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 "FirebasePerformance/Sources/FPRNanoPbUtils.h"
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#endif
#import <SystemConfiguration/SystemConfiguration.h>
#import "FirebasePerformance/Sources/Common/FPRConstants.h"
#import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
#import "FirebasePerformance/Sources/FPRDataUtils.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
#import "FirebasePerformance/Sources/Gauges/CPU/FPRCPUGaugeData.h"
#import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeData.h"
#define BYTES_TO_KB(x) (x / 1024)
static firebase_perf_v1_NetworkRequestMetric_HttpMethod FPRHTTPMethodForString(
NSString *methodString);
static firebase_perf_v1_NetworkConnectionInfo_NetworkType FPRNetworkConnectionInfoNetworkType(void);
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
static firebase_perf_v1_NetworkConnectionInfo_MobileSubtype FPRCellularNetworkType(void);
#endif
NSArray<FPRSessionDetails *> *FPRMakeFirstSessionVerbose(NSArray<FPRSessionDetails *> *sessions);
#pragma mark - Nanopb creation utilities
/** Converts the network method string to a value defined in the enum
* firebase_perf_v1_NetworkRequestMetric_HttpMethod.
* @return Enum value of the method string. If there is no mapping value defined for the method
* firebase_perf_v1_NetworkRequestMetric_HttpMethod_HTTP_METHOD_UNKNOWN is returned.
*/
static firebase_perf_v1_NetworkRequestMetric_HttpMethod FPRHTTPMethodForString(
NSString *methodString) {
static NSDictionary<NSString *, NSNumber *> *HTTPToFPRNetworkTraceMethod;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
HTTPToFPRNetworkTraceMethod = @{
@"GET" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_GET),
@"POST" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_POST),
@"PUT" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_PUT),
@"DELETE" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_DELETE),
@"HEAD" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_HEAD),
@"PATCH" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_PATCH),
@"OPTIONS" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_OPTIONS),
@"TRACE" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_TRACE),
@"CONNECT" : @(firebase_perf_v1_NetworkRequestMetric_HttpMethod_CONNECT),
};
});
NSNumber *HTTPMethod = HTTPToFPRNetworkTraceMethod[methodString];
if (HTTPMethod == nil) {
return firebase_perf_v1_NetworkRequestMetric_HttpMethod_HTTP_METHOD_UNKNOWN;
}
return HTTPMethod.intValue;
}
/** Get the current network connection type in firebase_perf_v1_NetworkConnectionInfo_NetworkType
* format.
* @return Current network connection type.
*/
static firebase_perf_v1_NetworkConnectionInfo_NetworkType FPRNetworkConnectionInfoNetworkType() {
firebase_perf_v1_NetworkConnectionInfo_NetworkType networkType =
firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE;
static SCNetworkReachabilityRef reachabilityRef = 0;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorSystemDefault, "google.com");
});
SCNetworkReachabilityFlags reachabilityFlags = 0;
SCNetworkReachabilityGetFlags(reachabilityRef, &reachabilityFlags);
// Parse the network flags to set the network type.
if (reachabilityFlags & kSCNetworkReachabilityFlagsReachable) {
if (reachabilityFlags & kSCNetworkReachabilityFlagsIsWWAN) {
networkType = firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE;
} else {
networkType = firebase_perf_v1_NetworkConnectionInfo_NetworkType_WIFI;
}
}
return networkType;
}
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
/** Get the current cellular network connection type in
* firebase_perf_v1_NetworkConnectionInfo_MobileSubtype format.
* @return Current cellular network connection type.
*/
static firebase_perf_v1_NetworkConnectionInfo_MobileSubtype FPRCellularNetworkType() {
static NSDictionary<NSString *, NSNumber *> *cellularNetworkToMobileSubtype;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
cellularNetworkToMobileSubtype = @{
CTRadioAccessTechnologyGPRS : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_GPRS),
CTRadioAccessTechnologyEdge : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EDGE),
CTRadioAccessTechnologyWCDMA : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_CDMA),
CTRadioAccessTechnologyHSDPA : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_HSDPA),
CTRadioAccessTechnologyHSUPA : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_HSUPA),
CTRadioAccessTechnologyCDMA1x : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_CDMA),
CTRadioAccessTechnologyCDMAEVDORev0 :
@(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EVDO_0),
CTRadioAccessTechnologyCDMAEVDORevA :
@(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EVDO_A),
CTRadioAccessTechnologyCDMAEVDORevB :
@(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EVDO_B),
CTRadioAccessTechnologyeHRPD : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EHRPD),
CTRadioAccessTechnologyLTE : @(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_LTE)
};
});
NSString *networkString = FPRNetworkInfo().currentRadioAccessTechnology;
NSNumber *cellularNetworkType = cellularNetworkToMobileSubtype[networkString];
return cellularNetworkType.intValue;
}
#endif
#pragma mark - Nanopb decode and encode helper methods
pb_bytes_array_t *FPREncodeData(NSData *data) {
pb_bytes_array_t *pbBytesArray = calloc(1, PB_BYTES_ARRAY_T_ALLOCSIZE(data.length));
if (pbBytesArray != NULL) {
[data getBytes:pbBytesArray->bytes length:data.length];
pbBytesArray->size = (pb_size_t)data.length;
}
return pbBytesArray;
}
pb_bytes_array_t *FPREncodeString(NSString *string) {
NSData *stringBytes = [string dataUsingEncoding:NSUTF8StringEncoding];
return FPREncodeData(stringBytes);
}
NSData *FPRDecodeData(pb_bytes_array_t *pbData) {
NSData *data = [NSData dataWithBytes:&(pbData->bytes) length:pbData->size];
return data;
}
NSString *FPRDecodeString(pb_bytes_array_t *pbData) {
NSData *data = FPRDecodeData(pbData);
return [NSString stringWithCString:[data bytes] encoding:NSUTF8StringEncoding];
}
StringToStringMap *_Nullable FPREncodeStringToStringMap(NSDictionary *_Nullable dict) {
StringToStringMap *map = calloc(dict.count, sizeof(StringToStringMap));
__block NSUInteger index = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) {
map[index].key = FPREncodeString(key);
map[index].value = FPREncodeString(value);
index++;
}];
return map;
}
NSDictionary<NSString *, NSString *> *FPRDecodeStringToStringMap(StringToStringMap *map,
NSInteger count) {
NSMutableDictionary<NSString *, NSString *> *dict = [[NSMutableDictionary alloc] init];
for (int i = 0; i < count; i++) {
NSString *key = FPRDecodeString(map[i].key);
NSString *value = FPRDecodeString(map[i].value);
dict[key] = value;
}
return [dict copy];
}
StringToNumberMap *_Nullable FPREncodeStringToNumberMap(NSDictionary *_Nullable dict) {
StringToNumberMap *map = calloc(dict.count, sizeof(StringToNumberMap));
__block NSUInteger index = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSNumber *value, BOOL *stop) {
map[index].key = FPREncodeString(key);
map[index].value = [value longLongValue];
map[index].has_value = true;
index++;
}];
return map;
}
NSDictionary<NSString *, NSNumber *> *_Nullable FPRDecodeStringToNumberMap(
StringToNumberMap *_Nullable map, NSInteger count) {
NSMutableDictionary<NSString *, NSNumber *> *dict = [[NSMutableDictionary alloc] init];
for (int i = 0; i < count; i++) {
if (map[i].has_value) {
NSString *key = FPRDecodeString(map[i].key);
NSNumber *value = [NSNumber numberWithLongLong:map[i].value];
dict[key] = value;
}
}
return [dict copy];
}
firebase_perf_v1_PerfSession *FPREncodePerfSessions(NSArray<FPRSessionDetails *> *sessions,
NSInteger count) {
firebase_perf_v1_PerfSession *perfSessions = calloc(count, sizeof(firebase_perf_v1_PerfSession));
__block NSUInteger perfSessionIndex = 0;
[sessions enumerateObjectsUsingBlock:^(FPRSessionDetails *_Nonnull session, NSUInteger index,
BOOL *_Nonnull stop) {
perfSessions[perfSessionIndex].session_id = FPREncodeString(session.sessionId);
perfSessions[perfSessionIndex].session_verbosity_count = 0;
if ((session.options & FPRSessionOptionsEvents) ||
(session.options & FPRSessionOptionsGauges)) {
perfSessions[perfSessionIndex].session_verbosity =
calloc(perfSessions[perfSessionIndex].session_verbosity_count,
sizeof(firebase_perf_v1_SessionVerbosity));
perfSessions[perfSessionIndex].session_verbosity[0] =
firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS;
perfSessions[perfSessionIndex].session_verbosity_count = 1;
}
perfSessionIndex++;
}];
return perfSessions;
}
#pragma mark - Public methods
firebase_perf_v1_PerfMetric FPRGetPerfMetricMessage(NSString *appID) {
firebase_perf_v1_PerfMetric perfMetricMessage = firebase_perf_v1_PerfMetric_init_default;
FPRSetApplicationInfo(&perfMetricMessage, FPRGetApplicationInfoMessage());
perfMetricMessage.application_info.google_app_id = FPREncodeString(appID);
return perfMetricMessage;
}
firebase_perf_v1_ApplicationInfo FPRGetApplicationInfoMessage() {
firebase_perf_v1_ApplicationInfo appInfoMessage = firebase_perf_v1_ApplicationInfo_init_default;
firebase_perf_v1_IosApplicationInfo iosAppInfo = firebase_perf_v1_IosApplicationInfo_init_default;
NSBundle *mainBundle = [NSBundle mainBundle];
iosAppInfo.bundle_short_version =
FPREncodeString([mainBundle infoDictionary][@"CFBundleShortVersionString"]);
iosAppInfo.sdk_version = FPREncodeString([NSString stringWithUTF8String:kFPRSDKVersion]);
iosAppInfo.network_connection_info.network_type = FPRNetworkConnectionInfoNetworkType();
iosAppInfo.has_network_connection_info = true;
iosAppInfo.network_connection_info.has_network_type = true;
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
CTTelephonyNetworkInfo *networkInfo = FPRNetworkInfo();
CTCarrier *provider = networkInfo.subscriberCellularProvider;
NSString *mccMnc = FPRValidatedMccMnc(provider.mobileCountryCode, provider.mobileNetworkCode);
if (mccMnc) {
iosAppInfo.mcc_mnc = FPREncodeString(mccMnc);
}
if (iosAppInfo.network_connection_info.network_type ==
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE) {
iosAppInfo.network_connection_info.mobile_subtype = FPRCellularNetworkType();
iosAppInfo.network_connection_info.has_mobile_subtype = true;
}
#endif
appInfoMessage.ios_app_info = iosAppInfo;
appInfoMessage.has_ios_app_info = true;
NSDictionary<NSString *, NSString *> *attributes =
[[FIRPerformance sharedInstance].attributes mutableCopy];
appInfoMessage.custom_attributes_count = (pb_size_t)attributes.count;
appInfoMessage.custom_attributes =
(firebase_perf_v1_ApplicationInfo_CustomAttributesEntry *)FPREncodeStringToStringMap(
attributes);
return appInfoMessage;
}
firebase_perf_v1_TraceMetric FPRGetTraceMetric(FIRTrace *trace) {
firebase_perf_v1_TraceMetric traceMetric = firebase_perf_v1_TraceMetric_init_default;
traceMetric.name = FPREncodeString(trace.name);
// Set if the trace is an internally created trace.
traceMetric.is_auto = trace.isInternal;
traceMetric.has_is_auto = true;
// Convert the trace duration from seconds to microseconds.
traceMetric.duration_us = trace.totalTraceTimeInterval * USEC_PER_SEC;
traceMetric.has_duration_us = true;
// Convert the start time from seconds to microseconds.
traceMetric.client_start_time_us = trace.startTimeSinceEpoch * USEC_PER_SEC;
traceMetric.has_client_start_time_us = true;
// Filling counters
NSDictionary<NSString *, NSNumber *> *counters = trace.counters;
traceMetric.counters_count = (pb_size_t)counters.count;
traceMetric.counters =
(firebase_perf_v1_TraceMetric_CountersEntry *)FPREncodeStringToNumberMap(counters);
// Filling subtraces
traceMetric.subtraces_count = (pb_size_t)[trace.stages count];
firebase_perf_v1_TraceMetric *subtraces =
calloc(traceMetric.subtraces_count, sizeof(firebase_perf_v1_TraceMetric));
__block NSUInteger subtraceIndex = 0;
[trace.stages
enumerateObjectsUsingBlock:^(FIRTrace *_Nonnull stage, NSUInteger idx, BOOL *_Nonnull stop) {
subtraces[subtraceIndex] = FPRGetTraceMetric(stage);
subtraceIndex++;
}];
traceMetric.subtraces = subtraces;
// Filling custom attributes
NSDictionary<NSString *, NSString *> *attributes = [trace.attributes mutableCopy];
traceMetric.custom_attributes_count = (pb_size_t)attributes.count;
traceMetric.custom_attributes =
(firebase_perf_v1_TraceMetric_CustomAttributesEntry *)FPREncodeStringToStringMap(attributes);
// Filling session details
NSArray<FPRSessionDetails *> *orderedSessions = FPRMakeFirstSessionVerbose(trace.sessions);
traceMetric.perf_sessions_count = (pb_size_t)[orderedSessions count];
traceMetric.perf_sessions =
FPREncodePerfSessions(orderedSessions, traceMetric.perf_sessions_count);
return traceMetric;
}
firebase_perf_v1_NetworkRequestMetric FPRGetNetworkRequestMetric(FPRNetworkTrace *trace) {
firebase_perf_v1_NetworkRequestMetric networkMetric =
firebase_perf_v1_NetworkRequestMetric_init_default;
networkMetric.url = FPREncodeString(trace.trimmedURLString);
networkMetric.http_method = FPRHTTPMethodForString(trace.URLRequest.HTTPMethod);
networkMetric.has_http_method = true;
// Convert the start time from seconds to microseconds.
networkMetric.client_start_time_us = trace.startTimeSinceEpoch * USEC_PER_SEC;
networkMetric.has_client_start_time_us = true;
networkMetric.request_payload_bytes = trace.requestSize;
networkMetric.has_request_payload_bytes = true;
networkMetric.response_payload_bytes = trace.responseSize;
networkMetric.has_response_payload_bytes = true;
networkMetric.http_response_code = trace.responseCode;
networkMetric.has_http_response_code = true;
networkMetric.response_content_type = FPREncodeString(trace.responseContentType);
if (trace.responseError) {
networkMetric.network_client_error_reason =
firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_GENERIC_CLIENT_ERROR;
networkMetric.has_network_client_error_reason = true;
}
NSTimeInterval requestTimeUs =
USEC_PER_SEC *
[trace timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
andState:FPRNetworkTraceCheckpointStateRequestCompleted];
if (requestTimeUs > 0) {
networkMetric.time_to_request_completed_us = requestTimeUs;
networkMetric.has_time_to_request_completed_us = true;
}
NSTimeInterval responseIntiationTimeUs =
USEC_PER_SEC *
[trace timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
andState:FPRNetworkTraceCheckpointStateResponseReceived];
if (responseIntiationTimeUs > 0) {
networkMetric.time_to_response_initiated_us = responseIntiationTimeUs;
networkMetric.has_time_to_response_initiated_us = true;
}
NSTimeInterval responseCompletedUs =
USEC_PER_SEC *
[trace timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
andState:FPRNetworkTraceCheckpointStateResponseCompleted];
if (responseCompletedUs > 0) {
networkMetric.time_to_response_completed_us = responseCompletedUs;
networkMetric.has_time_to_response_completed_us = true;
}
// Filling custom attributes
NSDictionary<NSString *, NSString *> *attributes = [trace.attributes mutableCopy];
networkMetric.custom_attributes_count = (pb_size_t)attributes.count;
networkMetric.custom_attributes =
(firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry *)FPREncodeStringToStringMap(
attributes);
// Filling session details
NSArray<FPRSessionDetails *> *orderedSessions = FPRMakeFirstSessionVerbose(trace.sessions);
networkMetric.perf_sessions_count = (pb_size_t)[orderedSessions count];
networkMetric.perf_sessions =
FPREncodePerfSessions(orderedSessions, networkMetric.perf_sessions_count);
return networkMetric;
}
firebase_perf_v1_GaugeMetric FPRGetGaugeMetric(NSArray *gaugeData, NSString *sessionId) {
firebase_perf_v1_GaugeMetric gaugeMetric = firebase_perf_v1_GaugeMetric_init_default;
gaugeMetric.session_id = FPREncodeString(sessionId);
__block NSInteger cpuReadingsCount = 0;
__block NSInteger memoryReadingsCount = 0;
firebase_perf_v1_CpuMetricReading *cpuReadings =
calloc([gaugeData count], sizeof(firebase_perf_v1_CpuMetricReading));
firebase_perf_v1_IosMemoryReading *memoryReadings =
calloc([gaugeData count], sizeof(firebase_perf_v1_IosMemoryReading));
[gaugeData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[FPRCPUGaugeData class]]) {
FPRCPUGaugeData *gaugeData = (FPRCPUGaugeData *)obj;
cpuReadings[cpuReadingsCount].client_time_us =
gaugeData.collectionTime.timeIntervalSince1970 * USEC_PER_SEC;
cpuReadings[cpuReadingsCount].has_client_time_us = true;
cpuReadings[cpuReadingsCount].system_time_us = gaugeData.systemTime;
cpuReadings[cpuReadingsCount].has_system_time_us = true;
cpuReadings[cpuReadingsCount].user_time_us = gaugeData.userTime;
cpuReadings[cpuReadingsCount].has_user_time_us = true;
cpuReadingsCount++;
}
if ([obj isKindOfClass:[FPRMemoryGaugeData class]]) {
FPRMemoryGaugeData *gaugeData = (FPRMemoryGaugeData *)obj;
memoryReadings[memoryReadingsCount].client_time_us =
gaugeData.collectionTime.timeIntervalSince1970 * USEC_PER_SEC;
memoryReadings[memoryReadingsCount].has_client_time_us = true;
memoryReadings[memoryReadingsCount].used_app_heap_memory_kb =
(int32_t)BYTES_TO_KB(gaugeData.heapUsed);
memoryReadings[memoryReadingsCount].has_used_app_heap_memory_kb = true;
memoryReadings[memoryReadingsCount].free_app_heap_memory_kb =
(int32_t)BYTES_TO_KB(gaugeData.heapAvailable);
memoryReadings[memoryReadingsCount].has_free_app_heap_memory_kb = true;
memoryReadingsCount++;
}
}];
cpuReadings = realloc(cpuReadings, cpuReadingsCount * sizeof(firebase_perf_v1_CpuMetricReading));
memoryReadings =
realloc(memoryReadings, memoryReadingsCount * sizeof(firebase_perf_v1_IosMemoryReading));
gaugeMetric.cpu_metric_readings = cpuReadings;
gaugeMetric.cpu_metric_readings_count = (pb_size_t)cpuReadingsCount;
gaugeMetric.ios_memory_readings = memoryReadings;
gaugeMetric.ios_memory_readings_count = (pb_size_t)memoryReadingsCount;
return gaugeMetric;
}
firebase_perf_v1_ApplicationProcessState FPRApplicationProcessState(FPRTraceState state) {
firebase_perf_v1_ApplicationProcessState processState =
firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN;
switch (state) {
case FPRTraceStateForegroundOnly:
processState = firebase_perf_v1_ApplicationProcessState_FOREGROUND;
break;
case FPRTraceStateBackgroundOnly:
processState = firebase_perf_v1_ApplicationProcessState_BACKGROUND;
break;
case FPRTraceStateBackgroundAndForeground:
processState = firebase_perf_v1_ApplicationProcessState_FOREGROUND_BACKGROUND;
break;
default:
break;
}
return processState;
}
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
CTTelephonyNetworkInfo *FPRNetworkInfo() {
static CTTelephonyNetworkInfo *networkInfo;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
networkInfo = [[CTTelephonyNetworkInfo alloc] init];
});
return networkInfo;
}
#endif
/** Reorders the list of sessions to make sure the first session is verbose if at least one session
* in the list is verbose.
* @return Ordered list of sessions.
*/
NSArray<FPRSessionDetails *> *FPRMakeFirstSessionVerbose(NSArray<FPRSessionDetails *> *sessions) {
NSMutableArray<FPRSessionDetails *> *orderedSessions =
[[NSMutableArray<FPRSessionDetails *> alloc] initWithArray:sessions];
NSInteger firstVerboseSessionIndex = -1;
for (int i = 0; i < [sessions count]; i++) {
if ([sessions[i] isVerbose]) {
firstVerboseSessionIndex = i;
break;
}
}
if (firstVerboseSessionIndex > 0) {
FPRSessionDetails *verboseSession = orderedSessions[firstVerboseSessionIndex];
[orderedSessions removeObjectAtIndex:firstVerboseSessionIndex];
[orderedSessions insertObject:verboseSession atIndex:0];
}
return [orderedSessions copy];
}
#pragma mark - Nanopb struct fields populating helper methods
void FPRSetApplicationInfo(firebase_perf_v1_PerfMetric *perfMetric,
firebase_perf_v1_ApplicationInfo appInfo) {
perfMetric->application_info = appInfo;
perfMetric->has_application_info = true;
}
void FPRSetTraceMetric(firebase_perf_v1_PerfMetric *perfMetric,
firebase_perf_v1_TraceMetric traceMetric) {
perfMetric->trace_metric = traceMetric;
perfMetric->has_trace_metric = true;
}
void FPRSetNetworkRequestMetric(firebase_perf_v1_PerfMetric *perfMetric,
firebase_perf_v1_NetworkRequestMetric networkMetric) {
perfMetric->network_request_metric = networkMetric;
perfMetric->has_network_request_metric = true;
}
void FPRSetGaugeMetric(firebase_perf_v1_PerfMetric *perfMetric,
firebase_perf_v1_GaugeMetric gaugeMetric) {
perfMetric->gauge_metric = gaugeMetric;
perfMetric->has_gauge_metric = true;
}
void FPRSetApplicationProcessState(firebase_perf_v1_PerfMetric *perfMetric,
firebase_perf_v1_ApplicationProcessState state) {
perfMetric->application_info.application_process_state = state;
perfMetric->application_info.has_application_process_state = true;
}
@@ -1,65 +0,0 @@
// Copyright 2020 Google LLC
//
// 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 <TargetConditionals.h>
#if __has_include("CoreTelephony/CTTelephonyNetworkInfo.h") && !TARGET_OS_MACCATALYST
#define TARGET_HAS_MOBILE_CONNECTIVITY
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#endif
#import "FirebasePerformance/Sources/AppActivity/FPRTraceBackgroundActivityTracker.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
/** Creates a new FPRMSGPerfMetric proto object populated with system metadata.
* @param appID The Google app id to put into the message
* @return Reference to a FPRMSGPerfMetric object.
*/
extern FPRMSGPerfMetric* _Nullable FPRGetPerfMetricMessage(NSString* _Nonnull appID);
/** Creates a new FPRMSGApplicationInfo proto object populated with system metadata.
* @return Reference to a FPRMSGApplicationInfo object.
*/
extern FPRMSGApplicationInfo* _Nullable FPRGetApplicationInfoMessage(void);
/** Converts the FIRTrace object to a FPRMSGTraceMetric proto object.
* @return Reference to a FPRMSGTraceMetric object.
*/
extern FPRMSGTraceMetric* _Nullable FPRGetTraceMetric(FIRTrace* _Nonnull trace);
/** Converts the FPRNetworkTrace object to a FPRMSGNetworkRequestMetric proto object.
* @return Reference to a FPRMSGNetworkRequestMetric object.
*/
extern FPRMSGNetworkRequestMetric* _Nullable FPRGetNetworkRequestMetric(
FPRNetworkTrace* _Nonnull trace);
/** Converts the gaugeData array object to a FPRMSGGaugeMetric proto object.
* @return Reference to a FPRMSGGaugeMetric object.
*/
extern FPRMSGGaugeMetric* _Nullable FPRGetGaugeMetric(NSArray* _Nonnull gaugeData,
NSString* _Nonnull sessionId);
/** Converts the FPRTraceState to a FPRMSGApplicationProcessState proto value.
* @return FPRMSGApplicationProcessState value.
*/
extern FPRMSGApplicationProcessState FPRApplicationProcessState(FPRTraceState state);
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
/** Obtain a CTTelephonyNetworkInfo object to determine device network attributes.
* @return CTTelephonyNetworkInfo object.
*/
extern CTTelephonyNetworkInfo* _Nullable FPRNetworkInfo(void);
#endif
-395
View File
@@ -1,395 +0,0 @@
// Copyright 2020 Google LLC
//
// 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 "FirebasePerformance/Sources/FPRProtoUtils.h"
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#endif
#import <SystemConfiguration/SystemConfiguration.h>
#import "FirebasePerformance/Sources/Common/FPRConstants.h"
#import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
#import "FirebasePerformance/Sources/FPRDataUtils.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
#import "FirebasePerformance/Sources/Gauges/CPU/FPRCPUGaugeData.h"
#import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeData.h"
#define BYTES_TO_KB(x) (x / 1024)
static GPBStringInt64Dictionary *FPRGetProtoCounterForDictionary(
NSDictionary<NSString *, NSNumber *> *dictionary);
static FPRMSGNetworkRequestMetric_HttpMethod FPRHTTPMethodForString(NSString *methodString);
static FPRMSGNetworkConnectionInfo_NetworkType FPRNetworkConnectionInfoNetworkType(void);
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
static FPRMSGNetworkConnectionInfo_MobileSubtype FPRCellularNetworkType(void);
#endif
NSArray<FPRSessionDetails *> *FPRMakeFirstSessionVerbose(NSArray<FPRSessionDetails *> *sessions);
#pragma mark - Public methods
FPRMSGPerfMetric *FPRGetPerfMetricMessage(NSString *appID) {
FPRMSGPerfMetric *perfMetricMessage = [FPRMSGPerfMetric message];
perfMetricMessage.applicationInfo = FPRGetApplicationInfoMessage();
perfMetricMessage.applicationInfo.googleAppId = appID;
return perfMetricMessage;
}
FPRMSGApplicationInfo *FPRGetApplicationInfoMessage() {
FPRMSGApplicationInfo *appInfoMessage = [FPRMSGApplicationInfo message];
FPRMSGIosApplicationInfo *iosAppInfo = [FPRMSGIosApplicationInfo message];
NSBundle *mainBundle = [NSBundle mainBundle];
iosAppInfo.bundleShortVersion = [mainBundle infoDictionary][@"CFBundleShortVersionString"];
iosAppInfo.sdkVersion = [NSString stringWithUTF8String:kFPRSDKVersion];
iosAppInfo.networkConnectionInfo.networkType = FPRNetworkConnectionInfoNetworkType();
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
CTTelephonyNetworkInfo *networkInfo = FPRNetworkInfo();
CTCarrier *provider = networkInfo.subscriberCellularProvider;
NSString *mccMnc = FPRValidatedMccMnc(provider.mobileCountryCode, provider.mobileNetworkCode);
if (mccMnc) {
iosAppInfo.mccMnc = mccMnc;
}
if (iosAppInfo.networkConnectionInfo.networkType ==
FPRMSGNetworkConnectionInfo_NetworkType_Mobile) {
iosAppInfo.networkConnectionInfo.mobileSubtype = FPRCellularNetworkType();
}
#endif
appInfoMessage.iosAppInfo = iosAppInfo;
appInfoMessage.customAttributes = [[FIRPerformance sharedInstance].attributes mutableCopy];
return appInfoMessage;
}
FPRMSGTraceMetric *FPRGetTraceMetric(FIRTrace *trace) {
if (trace == nil) {
return nil;
}
FPRMSGTraceMetric *traceMetric = [FPRMSGTraceMetric message];
traceMetric.name = trace.name;
// Set if the trace is an internally created trace.
traceMetric.isAuto = trace.isInternal;
// Convert the trace duration from seconds to microseconds.
traceMetric.durationUs = trace.totalTraceTimeInterval * USEC_PER_SEC;
// Convert the start time from seconds to microseconds.
traceMetric.clientStartTimeUs = trace.startTimeSinceEpoch * USEC_PER_SEC;
traceMetric.counters = FPRGetProtoCounterForDictionary(trace.counters);
NSMutableArray<FPRMSGTraceMetric *> *subtraces = [[NSMutableArray alloc] init];
[trace.stages
enumerateObjectsUsingBlock:^(FIRTrace *_Nonnull stage, NSUInteger idx, BOOL *_Nonnull stop) {
[subtraces addObject:FPRGetTraceMetric(stage)];
}];
traceMetric.subtracesArray = subtraces;
traceMetric.customAttributes = [trace.attributes mutableCopy];
// Fillin session details
traceMetric.perfSessionsArray = [[NSMutableArray<FPRMSGPerfSession *> alloc] init];
NSArray<FPRSessionDetails *> *orderedSessions = FPRMakeFirstSessionVerbose(trace.sessions);
[orderedSessions enumerateObjectsUsingBlock:^(FPRSessionDetails *_Nonnull session,
NSUInteger index, BOOL *_Nonnull stop) {
FPRMSGPerfSession *perfSession = [FPRMSGPerfSession message];
perfSession.sessionId = session.sessionId;
perfSession.sessionVerbosityArray = [GPBEnumArray array];
if ((session.options & FPRSessionOptionsEvents) ||
(session.options & FPRSessionOptionsGauges)) {
[perfSession.sessionVerbosityArray addValue:FPRMSGSessionVerbosity_GaugesAndSystemEvents];
}
[traceMetric.perfSessionsArray addObject:perfSession];
}];
return traceMetric;
}
FPRMSGNetworkRequestMetric *FPRGetNetworkRequestMetric(FPRNetworkTrace *trace) {
if (trace == nil) {
return nil;
}
// If there is no valid status code, do not send the event to backend.
if (!trace.hasValidResponseCode) {
return nil;
}
FPRMSGNetworkRequestMetric *networkMetric = [FPRMSGNetworkRequestMetric message];
networkMetric.URL = trace.trimmedURLString;
networkMetric.HTTPMethod = FPRHTTPMethodForString(trace.URLRequest.HTTPMethod);
// Convert the start time from seconds to microseconds.
networkMetric.clientStartTimeUs = trace.startTimeSinceEpoch * USEC_PER_SEC;
networkMetric.requestPayloadBytes = trace.requestSize;
networkMetric.responsePayloadBytes = trace.responseSize;
networkMetric.HTTPResponseCode = trace.responseCode;
networkMetric.responseContentType = trace.responseContentType;
if (trace.responseError) {
networkMetric.networkClientErrorReason =
FPRMSGNetworkRequestMetric_NetworkClientErrorReason_GenericClientError;
}
NSTimeInterval requestTimeUs =
USEC_PER_SEC *
[trace timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
andState:FPRNetworkTraceCheckpointStateRequestCompleted];
if (requestTimeUs > 0) {
networkMetric.timeToRequestCompletedUs = requestTimeUs;
}
NSTimeInterval responseIntiationTimeUs =
USEC_PER_SEC *
[trace timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
andState:FPRNetworkTraceCheckpointStateResponseReceived];
if (responseIntiationTimeUs > 0) {
networkMetric.timeToResponseInitiatedUs = responseIntiationTimeUs;
}
NSTimeInterval responseCompletedUs =
USEC_PER_SEC *
[trace timeIntervalBetweenCheckpointState:FPRNetworkTraceCheckpointStateInitiated
andState:FPRNetworkTraceCheckpointStateResponseCompleted];
if (responseCompletedUs > 0) {
networkMetric.timeToResponseCompletedUs = responseCompletedUs;
}
networkMetric.customAttributes = [trace.attributes mutableCopy];
// Fillin session details
NSArray<FPRSessionDetails *> *orderedSessions = FPRMakeFirstSessionVerbose(trace.sessions);
networkMetric.perfSessionsArray = [[NSMutableArray<FPRMSGPerfSession *> alloc] init];
[orderedSessions enumerateObjectsUsingBlock:^(FPRSessionDetails *_Nonnull session,
NSUInteger index, BOOL *_Nonnull stop) {
FPRMSGPerfSession *perfSession = [FPRMSGPerfSession message];
perfSession.sessionId = session.sessionId;
perfSession.sessionVerbosityArray = [GPBEnumArray array];
if ((session.options & FPRSessionOptionsEvents) ||
(session.options & FPRSessionOptionsGauges)) {
[perfSession.sessionVerbosityArray addValue:FPRMSGSessionVerbosity_GaugesAndSystemEvents];
}
[networkMetric.perfSessionsArray addObject:perfSession];
}];
return networkMetric;
}
FPRMSGGaugeMetric *FPRGetGaugeMetric(NSArray *gaugeData, NSString *sessionId) {
if (gaugeData == nil || gaugeData.count == 0) {
return nil;
}
if (sessionId == nil || sessionId.length == 0) {
return nil;
}
FPRMSGGaugeMetric *gaugeMetric = [FPRMSGGaugeMetric message];
gaugeMetric.sessionId = sessionId;
NSMutableArray<FPRMSGCpuMetricReading *> *cpuReadings =
[[NSMutableArray<FPRMSGCpuMetricReading *> alloc] init];
NSMutableArray<FPRMSGIosMemoryReading *> *memoryReadings =
[[NSMutableArray<FPRMSGIosMemoryReading *> alloc] init];
[gaugeData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[FPRCPUGaugeData class]]) {
FPRCPUGaugeData *gaugeData = (FPRCPUGaugeData *)obj;
FPRMSGCpuMetricReading *cpuReading = [FPRMSGCpuMetricReading message];
cpuReading.clientTimeUs = gaugeData.collectionTime.timeIntervalSince1970 * USEC_PER_SEC;
cpuReading.systemTimeUs = gaugeData.systemTime;
cpuReading.userTimeUs = gaugeData.userTime;
[cpuReadings addObject:cpuReading];
}
if ([obj isKindOfClass:[FPRMemoryGaugeData class]]) {
FPRMemoryGaugeData *gaugeData = (FPRMemoryGaugeData *)obj;
FPRMSGIosMemoryReading *memoryReading = [FPRMSGIosMemoryReading message];
memoryReading.clientTimeUs = gaugeData.collectionTime.timeIntervalSince1970 * USEC_PER_SEC;
memoryReading.usedAppHeapMemoryKb = (int32_t)BYTES_TO_KB(gaugeData.heapUsed);
memoryReading.freeAppHeapMemoryKb = (int32_t)BYTES_TO_KB(gaugeData.heapAvailable);
[memoryReadings addObject:memoryReading];
}
}];
gaugeMetric.cpuMetricReadingsArray = cpuReadings;
gaugeMetric.iosMemoryReadingsArray = memoryReadings;
return gaugeMetric;
}
FPRMSGApplicationProcessState FPRApplicationProcessState(FPRTraceState state) {
FPRMSGApplicationProcessState processState =
FPRMSGApplicationProcessState_ApplicationProcessStateUnknown;
switch (state) {
case FPRTraceStateForegroundOnly:
processState = FPRMSGApplicationProcessState_Foreground;
break;
case FPRTraceStateBackgroundOnly:
processState = FPRMSGApplicationProcessState_Background;
break;
case FPRTraceStateBackgroundAndForeground:
processState = FPRMSGApplicationProcessState_ForegroundBackground;
break;
default:
break;
}
return processState;
}
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
CTTelephonyNetworkInfo *FPRNetworkInfo() {
static CTTelephonyNetworkInfo *networkInfo;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
networkInfo = [[CTTelephonyNetworkInfo alloc] init];
});
return networkInfo;
}
#endif
#pragma mark - Proto creation utilities
/** Converts a dictionary of <NSString *, NSNumber *> to a GPBStringInt64Dictionary proto object.
* @return Reference to a GPBStringInt64Dictionary object.
*/
static GPBStringInt64Dictionary *FPRGetProtoCounterForDictionary(
NSDictionary<NSString *, NSNumber *> *dictionary) {
GPBStringInt64Dictionary *counterDictionary = [[GPBStringInt64Dictionary alloc] init];
[dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, NSNumber *_Nonnull value,
BOOL *_Nonnull stop) {
[counterDictionary setInt64:[value longLongValue] forKey:key];
}];
return counterDictionary;
}
/** Converts the network method string to a value defined in the enum
* FPRMSGNetworkRequestMetric_HttpMethod.
* @return Enum value of the method string. If there is no mapping value defined for the method
* string FPRMSGNetworkRequestMetric_HttpMethod_HTTPMethodUnknown is returned.
*/
static FPRMSGNetworkRequestMetric_HttpMethod FPRHTTPMethodForString(NSString *methodString) {
static NSDictionary<NSString *, NSNumber *> *HTTPToFPRNetworkTraceMethod;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
HTTPToFPRNetworkTraceMethod = @{
@"GET" : @(FPRMSGNetworkRequestMetric_HttpMethod_Get),
@"POST" : @(FPRMSGNetworkRequestMetric_HttpMethod_Post),
@"PUT" : @(FPRMSGNetworkRequestMetric_HttpMethod_Put),
@"DELETE" : @(FPRMSGNetworkRequestMetric_HttpMethod_Delete),
@"HEAD" : @(FPRMSGNetworkRequestMetric_HttpMethod_Head),
@"PATCH" : @(FPRMSGNetworkRequestMetric_HttpMethod_Patch),
@"OPTIONS" : @(FPRMSGNetworkRequestMetric_HttpMethod_Options),
@"TRACE" : @(FPRMSGNetworkRequestMetric_HttpMethod_Trace),
@"CONNECT" : @(FPRMSGNetworkRequestMetric_HttpMethod_Connect),
};
});
NSNumber *HTTPMethod = HTTPToFPRNetworkTraceMethod[methodString];
if (HTTPMethod == nil) {
return FPRMSGNetworkRequestMetric_HttpMethod_HTTPMethodUnknown;
}
return HTTPMethod.intValue;
}
/** Get the current network connection type in NetworkConnectionInfo_NetworkType format.
* @return Current network connection type.
*/
static FPRMSGNetworkConnectionInfo_NetworkType FPRNetworkConnectionInfoNetworkType() {
FPRMSGNetworkConnectionInfo_NetworkType networkType =
FPRMSGNetworkConnectionInfo_NetworkType_None;
static SCNetworkReachabilityRef reachabilityRef = 0;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorSystemDefault, "google.com");
});
SCNetworkReachabilityFlags reachabilityFlags = 0;
SCNetworkReachabilityGetFlags(reachabilityRef, &reachabilityFlags);
// Parse the network flags to set the network type.
if (reachabilityFlags & kSCNetworkReachabilityFlagsReachable) {
if (reachabilityFlags & kSCNetworkReachabilityFlagsIsWWAN) {
networkType = FPRMSGNetworkConnectionInfo_NetworkType_Mobile;
} else {
networkType = FPRMSGNetworkConnectionInfo_NetworkType_Wifi;
}
}
return networkType;
}
#ifdef TARGET_HAS_MOBILE_CONNECTIVITY
/** Get the current cellular network connection type in NetworkConnectionInfo_MobileSubtype format.
* @return Current cellular network connection type.
*/
static FPRMSGNetworkConnectionInfo_MobileSubtype FPRCellularNetworkType() {
static NSDictionary<NSString *, NSNumber *> *cellularNetworkToMobileSubtype;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
cellularNetworkToMobileSubtype = @{
CTRadioAccessTechnologyGPRS : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Gprs),
CTRadioAccessTechnologyEdge : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Edge),
CTRadioAccessTechnologyWCDMA : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Cdma),
CTRadioAccessTechnologyHSDPA : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Hsdpa),
CTRadioAccessTechnologyHSUPA : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Hsupa),
CTRadioAccessTechnologyCDMA1x : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Cdma),
CTRadioAccessTechnologyCDMAEVDORev0 : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Evdo0),
CTRadioAccessTechnologyCDMAEVDORevA : @(FPRMSGNetworkConnectionInfo_MobileSubtype_EvdoA),
CTRadioAccessTechnologyCDMAEVDORevB : @(FPRMSGNetworkConnectionInfo_MobileSubtype_EvdoB),
CTRadioAccessTechnologyeHRPD : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Ehrpd),
CTRadioAccessTechnologyLTE : @(FPRMSGNetworkConnectionInfo_MobileSubtype_Lte)
};
});
NSString *networkString = FPRNetworkInfo().currentRadioAccessTechnology;
NSNumber *cellularNetworkType = cellularNetworkToMobileSubtype[networkString];
return cellularNetworkType.intValue;
}
#endif
/** Reorders the list of sessions to make sure the first session is verbose if at least one session
* in the list is verbose.
* @return Ordered list of sessions.
*/
NSArray<FPRSessionDetails *> *FPRMakeFirstSessionVerbose(NSArray<FPRSessionDetails *> *sessions) {
NSMutableArray<FPRSessionDetails *> *orderedSessions =
[[NSMutableArray<FPRSessionDetails *> alloc] initWithArray:sessions];
__block NSInteger firstVerboseSessionIndex = -1;
[sessions enumerateObjectsUsingBlock:^(FPRSessionDetails *session, NSUInteger idx, BOOL *stop) {
if ([session isVerbose]) {
firstVerboseSessionIndex = idx;
*stop = YES;
}
}];
if (firstVerboseSessionIndex > 0) {
FPRSessionDetails *verboseSession = orderedSessions[firstVerboseSessionIndex];
[orderedSessions removeObjectAtIndex:firstVerboseSessionIndex];
[orderedSessions insertObject:verboseSession atIndex:0];
}
return [orderedSessions copy];
}
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Public/FIRHTTPMetric.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRHTTPMetric.h"
#import "FirebasePerformance/Sources/Instrumentation/FIRHTTPMetric+Private.h"
#import "FirebasePerformance/Sources/Common/FPRConstants.h"
@@ -184,5 +184,11 @@ typedef NS_ENUM(NSInteger, FPRNetworkTraceCheckpointState) {
*/
- (NSTimeInterval)timeIntervalBetweenCheckpointState:(FPRNetworkTraceCheckpointState)startState
andState:(FPRNetworkTraceCheckpointState)endState;
/**
* Checks if the network trace is valid.
*
* @return true if the network trace is valid.
*/
- (BOOL)isValid;
@end
@@ -443,4 +443,8 @@ NSString *const kFPRNetworkTracePropertyName = @"fpr_networkTrace";
}
}
- (BOOL)isValid {
return _hasValidResponseCode;
}
@end
@@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Instrumentation/UIKit/FPRUIViewControllerInstrument.h"
#import <UIKit/UIKit.h>
#import "FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker+Private.h"
@@ -23,6 +21,7 @@
#import "FirebasePerformance/Sources/Instrumentation/FPRInstrument_Private.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRSelectorInstrumentor.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNetworkInstrumentHelpers.h"
#import "FirebasePerformance/Sources/Instrumentation/UIKit/FPRUIViewControllerInstrument.h"
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
#import <GoogleUtilities/GULOriginalIMPConvenienceMacros.h>
@@ -15,24 +15,23 @@
#import <Foundation/Foundation.h>
#import <GoogleDataTransport/GoogleDataTransport.h>
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
NS_ASSUME_NONNULL_BEGIN
@class FPRMSGPerfMetric;
/**
* Google Data Transport event wrapper used for converting Fireperf Proto object to
* Google Data Transport event wrapper used for converting Fireperf nanopb object to
* GDTEvent object.
*/
@interface FPRGDTEvent : NSObject <GDTCOREventDataObject>
/** Perf metric that is going to be converted. */
@property(nonatomic, readonly) FPRMSGPerfMetric *metric;
/** firebase_perf_v1_PerfMetric that is going to be converted. */
@property(nonatomic, readonly) firebase_perf_v1_PerfMetric metric;
- (instancetype)init NS_UNAVAILABLE;
/** Converts a PerfMetric event to a GDTEvent. */
+ (instancetype)gdtEventForPerfMetric:(FPRMSGPerfMetric *)perfMetric;
/** Converts a firebase_perf_v1_PerfMetric object to a GDTEvent. */
+ (instancetype)gdtEventForPerfMetric:(firebase_perf_v1_PerfMetric)perfMetric;
@end
@@ -12,14 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import <nanopb/pb.h>
#import <nanopb/pb_decode.h>
#import <nanopb/pb_encode.h>
#import "FirebasePerformance/Sources/FPRConsoleLogger.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTEvent.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
@interface FPRGDTEvent ()
/** Perf metric that is going to be converted. */
@property(nonatomic) FPRMSGPerfMetric *metric;
@property(nonatomic) firebase_perf_v1_PerfMetric metric;
/**
* Creates an instance of FPRGDTEvent.
@@ -27,18 +32,18 @@
* @param perfMetric Performance Event proto object that needs to be converted to FPRGDTEvent.
* @return Instance of FPRGDTEvent.
*/
- (instancetype)initForPerfMetric:(FPRMSGPerfMetric *)perfMetric;
- (instancetype)initForPerfMetric:(firebase_perf_v1_PerfMetric)perfMetric;
@end
@implementation FPRGDTEvent
+ (instancetype)gdtEventForPerfMetric:(FPRMSGPerfMetric *)perfMetric {
+ (instancetype)gdtEventForPerfMetric:(firebase_perf_v1_PerfMetric)perfMetric {
FPRGDTEvent *event = [[FPRGDTEvent alloc] initForPerfMetric:perfMetric];
return event;
}
- (instancetype)initForPerfMetric:(FPRMSGPerfMetric *)perfMetric {
- (instancetype)initForPerfMetric:(firebase_perf_v1_PerfMetric)perfMetric {
if (self = [super init]) {
_metric = perfMetric;
}
@@ -49,7 +54,30 @@
#pragma mark - GDTCOREventDataObject protocol methods
- (NSData *)transportBytes {
return [self.metric data];
pb_ostream_t sizestream = PB_OSTREAM_SIZING;
// Encode 1 time to determine the size.
if (!pb_encode(&sizestream, firebase_perf_v1_PerfMetric_fields, &_metric)) {
FPRLogError(kFPRTransportBytesError, @"Error in nanopb encoding for size: %s",
PB_GET_ERROR(&sizestream));
}
// Encode a 2nd time to actually get the bytes from it.
size_t bufferSize = sizestream.bytes_written;
CFMutableDataRef dataRef = CFDataCreateMutable(CFAllocatorGetDefault(), bufferSize);
CFDataSetLength(dataRef, bufferSize);
pb_ostream_t ostream = pb_ostream_from_buffer((void *)CFDataGetBytePtr(dataRef), bufferSize);
if (!pb_encode(&ostream, firebase_perf_v1_PerfMetric_fields, &_metric)) {
FPRLogError(kFPRTransportBytesError, @"Error in nanopb encoding for bytes: %s",
PB_GET_ERROR(&ostream));
}
CFDataSetLength(dataRef, ostream.bytes_written);
return CFBridgingRelease(dataRef);
}
- (void)dealloc {
pb_release(firebase_perf_v1_PerfMetric_fields, &_metric);
}
@end
@@ -22,8 +22,6 @@
#import "FirebasePerformance/Sources/FPRConsoleLogger.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTEvent.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
@class FPRGDTEvent;
@interface FPRGDTLogSampler ()
@@ -73,23 +71,22 @@
}
FPRGDTEvent *gdtEvent = (FPRGDTEvent *)event.dataObject;
FPRMSGPerfMetric *perfMetric = gdtEvent.metric;
firebase_perf_v1_PerfMetric perfMetric = gdtEvent.metric;
// If it is a gaugeEvent, do not sample.
if (perfMetric.hasGaugeMetric) {
if (perfMetric.has_gauge_metric) {
return event;
}
// If the traceMetric contains a verbose session, do not sample.
if (perfMetric.hasTraceMetric) {
FPRMSGTraceMetric *traceMetric = perfMetric.traceMetric;
if (perfMetric.has_trace_metric) {
firebase_perf_v1_TraceMetric traceMetric = perfMetric.trace_metric;
// Sessions are ordered so that the first session is the most verbose one.
if (traceMetric.perfSessionsArray.count > 0) {
FPRMSGPerfSession *firstSession = traceMetric.perfSessionsArray[0];
if (firstSession.sessionVerbosityArray.count > 0) {
FPRMSGSessionVerbosity firstVerbosity =
(FPRMSGSessionVerbosity)[firstSession.sessionVerbosityArray valueAtIndex:0];
if (firstVerbosity == FPRMSGSessionVerbosity_GaugesAndSystemEvents) {
if (traceMetric.perf_sessions_count > 0) {
firebase_perf_v1_PerfSession firstSession = traceMetric.perf_sessions[0];
if (firstSession.session_verbosity_count > 0) {
firebase_perf_v1_SessionVerbosity firstVerbosity = firstSession.session_verbosity[0];
if (firstVerbosity == firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS) {
return event;
}
}
@@ -97,15 +94,14 @@
}
// If the networkMetric contains a verbose session, do not sample.
if (perfMetric.hasNetworkRequestMetric) {
FPRMSGNetworkRequestMetric *networkMetric = perfMetric.networkRequestMetric;
if (perfMetric.has_network_request_metric) {
firebase_perf_v1_NetworkRequestMetric networkMetric = perfMetric.network_request_metric;
// Sessions are ordered so that the first session is the most verbose one.
if (networkMetric.perfSessionsArray.count > 0) {
FPRMSGPerfSession *firstSession = networkMetric.perfSessionsArray[0];
if (firstSession.sessionVerbosityArray.count > 0) {
FPRMSGSessionVerbosity firstVerbosity =
(FPRMSGSessionVerbosity)[firstSession.sessionVerbosityArray valueAtIndex:0];
if (firstVerbosity == FPRMSGSessionVerbosity_GaugesAndSystemEvents) {
if (networkMetric.perf_sessions_count > 0) {
firebase_perf_v1_PerfSession firstSession = networkMetric.perf_sessions[0];
if (firstSession.session_verbosity_count > 0) {
firebase_perf_v1_SessionVerbosity firstVerbosity = firstSession.session_verbosity[0];
if (firstVerbosity == firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS) {
return event;
}
}
@@ -126,10 +122,10 @@
* @param event The event on which the decision would be made.
* @return Boolean value of YES if the log should be dropped/sampled out. Otherwise, NO.
*/
- (BOOL)shouldDropEvent:(FPRMSGPerfMetric *)event {
- (BOOL)shouldDropEvent:(firebase_perf_v1_PerfMetric)event {
// Find the correct sampling rate and make the decision to drop or log the event.
float samplingRate = [self.flags logTraceSamplingRate];
if (event.hasNetworkRequestMetric) {
if (event.has_network_request_metric) {
samplingRate = [self.flags logNetworkSamplingRate];
}
@@ -13,11 +13,10 @@
// limitations under the License.
#import <Foundation/Foundation.h>
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
NS_ASSUME_NONNULL_BEGIN
@class FPRMSGPerfMetric;
/** Logger used to dispatch events to Google Data Transport layer. */
@interface FPRGDTLogger : NSObject
@@ -41,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
* @remark Events are logged/dispatched asynchrounously using a serial dispatch queue.
* @param event The event to log.
*/
- (void)logEvent:(FPRMSGPerfMetric *)event;
- (void)logEvent:(firebase_perf_v1_PerfMetric)event;
@end
@@ -23,7 +23,7 @@
#import <GoogleDataTransport/GoogleDataTransport.h>
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
@implementation FPRGDTLogger
@@ -54,7 +54,7 @@
return self;
}
- (void)logEvent:(FPRMSGPerfMetric *)event {
- (void)logEvent:(firebase_perf_v1_PerfMetric)event {
GDTCORTransport *eventTransporter = self.gdtfllTransport;
dispatch_async(self.queue, ^{
@@ -24,8 +24,6 @@
#import <GoogleDataTransport/GoogleDataTransport.h>
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
@interface FPRGDTRateLimiter ()
/**
@@ -78,12 +76,12 @@
- (GDTCOREvent *)transformGDTEvent:(nonnull GDTCOREvent *)logEvent {
if ([logEvent.dataObject isKindOfClass:[FPRGDTEvent class]]) {
FPRGDTEvent *gdtEvent = (FPRGDTEvent *)logEvent.dataObject;
FPRMSGPerfMetric *perfMetric = gdtEvent.metric;
firebase_perf_v1_PerfMetric perfMetric = gdtEvent.metric;
if (perfMetric.hasTraceMetric) {
FPRMSGTraceMetric *traceMetric = perfMetric.traceMetric;
if (perfMetric.has_trace_metric) {
firebase_perf_v1_TraceMetric traceMetric = perfMetric.trace_metric;
// If it is an internal trace event, skip rate limiting.
if (traceMetric.isAuto) {
if (traceMetric.is_auto) {
return logEvent;
}
}
@@ -210,8 +208,8 @@
- (BOOL)isNetworkEvent:(GDTCOREvent *)logEvent {
if ([logEvent.dataObject isKindOfClass:[FPRGDTEvent class]]) {
FPRGDTEvent *gdtEvent = (FPRGDTEvent *)logEvent.dataObject;
FPRMSGPerfMetric *perfMetric = gdtEvent.metric;
if (perfMetric.hasNetworkRequestMetric) {
firebase_perf_v1_PerfMetric perfMetric = gdtEvent.metric;
if (perfMetric.has_network_request_metric) {
return YES;
}
}
@@ -0,0 +1,219 @@
/*
* Copyright 2021 Google LLC
*
* 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.
*/
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.9.8 */
#include "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const firebase_perf_v1_NetworkConnectionInfo_NetworkType firebase_perf_v1_NetworkConnectionInfo_network_type_default = firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE;
const firebase_perf_v1_NetworkConnectionInfo_MobileSubtype firebase_perf_v1_NetworkConnectionInfo_mobile_subtype_default = firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE;
const pb_field_t firebase_perf_v1_PerfMetric_fields[6] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, firebase_perf_v1_PerfMetric, application_info, application_info, &firebase_perf_v1_ApplicationInfo_fields),
PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_PerfMetric, trace_metric, application_info, &firebase_perf_v1_TraceMetric_fields),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_PerfMetric, network_request_metric, trace_metric, &firebase_perf_v1_NetworkRequestMetric_fields),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_PerfMetric, gauge_metric, network_request_metric, &firebase_perf_v1_GaugeMetric_fields),
PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_PerfMetric, transport_info, gauge_metric, &firebase_perf_v1_TransportInfo_fields),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_TraceMetric_fields[9] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_TraceMetric, name, name, 0),
PB_FIELD( 2, BOOL , OPTIONAL, STATIC , OTHER, firebase_perf_v1_TraceMetric, is_auto, name, 0),
PB_FIELD( 4, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_TraceMetric, client_start_time_us, is_auto, 0),
PB_FIELD( 5, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_TraceMetric, duration_us, client_start_time_us, 0),
PB_FIELD( 6, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_TraceMetric, counters, duration_us, &firebase_perf_v1_TraceMetric_CountersEntry_fields),
PB_FIELD( 7, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_TraceMetric, subtraces, counters, &firebase_perf_v1_TraceMetric_fields),
PB_FIELD( 8, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_TraceMetric, custom_attributes, subtraces, &firebase_perf_v1_TraceMetric_CustomAttributesEntry_fields),
PB_FIELD( 9, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_TraceMetric, perf_sessions, custom_attributes, &firebase_perf_v1_PerfSession_fields),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_TraceMetric_CountersEntry_fields[3] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_TraceMetric_CountersEntry, key, key, 0),
PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_TraceMetric_CountersEntry, value, key, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_TraceMetric_CustomAttributesEntry_fields[3] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_TraceMetric_CustomAttributesEntry, key, key, 0),
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_TraceMetric_CustomAttributesEntry, value, key, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_NetworkRequestMetric_fields[14] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_NetworkRequestMetric, url, url, 0),
PB_FIELD( 2, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, http_method, url, 0),
PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, request_payload_bytes, http_method, 0),
PB_FIELD( 4, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, response_payload_bytes, request_payload_bytes, 0),
PB_FIELD( 5, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, http_response_code, response_payload_bytes, 0),
PB_FIELD( 6, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_NetworkRequestMetric, response_content_type, http_response_code, 0),
PB_FIELD( 7, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, client_start_time_us, response_content_type, 0),
PB_FIELD( 8, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, time_to_request_completed_us, client_start_time_us, 0),
PB_FIELD( 9, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, time_to_response_initiated_us, time_to_request_completed_us, 0),
PB_FIELD( 10, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, time_to_response_completed_us, time_to_response_initiated_us, 0),
PB_FIELD( 11, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkRequestMetric, network_client_error_reason, time_to_response_completed_us, 0),
PB_FIELD( 12, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_NetworkRequestMetric, custom_attributes, network_client_error_reason, &firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_fields),
PB_FIELD( 13, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_NetworkRequestMetric, perf_sessions, custom_attributes, &firebase_perf_v1_PerfSession_fields),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_fields[3] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry, key, key, 0),
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry, value, key, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_PerfSession_fields[3] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_PerfSession, session_id, session_id, 0),
PB_FIELD( 2, UENUM , REPEATED, POINTER , OTHER, firebase_perf_v1_PerfSession, session_verbosity, session_id, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_GaugeMetric_fields[6] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_GaugeMetric, session_id, session_id, 0),
PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_GaugeMetric, cpu_metric_readings, session_id, &firebase_perf_v1_CpuMetricReading_fields),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_GaugeMetric, gauge_metadata, cpu_metric_readings, &firebase_perf_v1_GaugeMetadata_fields),
PB_FIELD( 4, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_GaugeMetric, android_memory_readings, gauge_metadata, &firebase_perf_v1_AndroidMemoryReading_fields),
PB_FIELD( 5, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_GaugeMetric, ios_memory_readings, android_memory_readings, &firebase_perf_v1_IosMemoryReading_fields),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_CpuMetricReading_fields[4] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, firebase_perf_v1_CpuMetricReading, client_time_us, client_time_us, 0),
PB_FIELD( 2, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_CpuMetricReading, user_time_us, client_time_us, 0),
PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_CpuMetricReading, system_time_us, user_time_us, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_IosMemoryReading_fields[4] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, firebase_perf_v1_IosMemoryReading, client_time_us, client_time_us, 0),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_IosMemoryReading, used_app_heap_memory_kb, client_time_us, 0),
PB_FIELD( 3, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_IosMemoryReading, free_app_heap_memory_kb, used_app_heap_memory_kb, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_AndroidMemoryReading_fields[3] = {
PB_FIELD( 1, INT64 , OPTIONAL, STATIC , FIRST, firebase_perf_v1_AndroidMemoryReading, client_time_us, client_time_us, 0),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_AndroidMemoryReading, used_app_java_heap_memory_kb, client_time_us, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_GaugeMetadata_fields[7] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_GaugeMetadata, process_name, process_name, 0),
PB_FIELD( 2, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_GaugeMetadata, cpu_clock_rate_khz, process_name, 0),
PB_FIELD( 3, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_GaugeMetadata, device_ram_size_kb, cpu_clock_rate_khz, 0),
PB_FIELD( 4, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_GaugeMetadata, max_app_java_heap_memory_kb, device_ram_size_kb, 0),
PB_FIELD( 5, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_GaugeMetadata, max_encouraged_app_java_heap_memory_kb, max_app_java_heap_memory_kb, 0),
PB_FIELD( 6, INT32 , OPTIONAL, STATIC , OTHER, firebase_perf_v1_GaugeMetadata, cpu_processor_count, max_encouraged_app_java_heap_memory_kb, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_ApplicationInfo_fields[8] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_ApplicationInfo, google_app_id, google_app_id, 0),
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_ApplicationInfo, app_instance_id, google_app_id, 0),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_ApplicationInfo, android_app_info, app_instance_id, &firebase_perf_v1_AndroidApplicationInfo_fields),
PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_ApplicationInfo, ios_app_info, android_app_info, &firebase_perf_v1_IosApplicationInfo_fields),
PB_FIELD( 5, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_ApplicationInfo, application_process_state, ios_app_info, 0),
PB_FIELD( 6, MESSAGE , REPEATED, POINTER , OTHER, firebase_perf_v1_ApplicationInfo, custom_attributes, application_process_state, &firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_fields),
PB_FIELD( 7, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_ApplicationInfo, web_app_info, custom_attributes, &firebase_perf_v1_WebApplicationInfo_fields),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_fields[3] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_ApplicationInfo_CustomAttributesEntry, key, key, 0),
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_ApplicationInfo_CustomAttributesEntry, value, key, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_WebApplicationInfo_fields[6] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_WebApplicationInfo, sdk_version, sdk_version, 0),
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_WebApplicationInfo, page_url, sdk_version, 0),
PB_FIELD( 3, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_WebApplicationInfo, service_worker_status, page_url, 0),
PB_FIELD( 4, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_WebApplicationInfo, visibility_state, service_worker_status, 0),
PB_FIELD( 5, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_WebApplicationInfo, effective_connection_type, visibility_state, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_AndroidApplicationInfo_fields[4] = {
PB_FIELD( 1, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_AndroidApplicationInfo, package_name, package_name, 0),
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_AndroidApplicationInfo, sdk_version, package_name, 0),
PB_FIELD( 3, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_AndroidApplicationInfo, version_name, sdk_version, 0),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_NetworkConnectionInfo_fields[3] = {
PB_FIELD( 1, ENUM , OPTIONAL, STATIC , FIRST, firebase_perf_v1_NetworkConnectionInfo, network_type, network_type, &firebase_perf_v1_NetworkConnectionInfo_network_type_default),
PB_FIELD( 2, UENUM , OPTIONAL, STATIC , OTHER, firebase_perf_v1_NetworkConnectionInfo, mobile_subtype, network_type, &firebase_perf_v1_NetworkConnectionInfo_mobile_subtype_default),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_IosApplicationInfo_fields[5] = {
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , FIRST, firebase_perf_v1_IosApplicationInfo, sdk_version, sdk_version, 0),
PB_FIELD( 3, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_IosApplicationInfo, bundle_short_version, sdk_version, 0),
PB_FIELD( 4, BYTES , OPTIONAL, POINTER , OTHER, firebase_perf_v1_IosApplicationInfo, mcc_mnc, bundle_short_version, 0),
PB_FIELD( 5, MESSAGE , OPTIONAL, STATIC , OTHER, firebase_perf_v1_IosApplicationInfo, network_connection_info, mcc_mnc, &firebase_perf_v1_NetworkConnectionInfo_fields),
PB_LAST_FIELD
};
const pb_field_t firebase_perf_v1_TransportInfo_fields[2] = {
PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, firebase_perf_v1_TransportInfo, dispatch_destination, dispatch_destination, 0),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(firebase_perf_v1_PerfMetric, application_info) < 65536 && pb_membersize(firebase_perf_v1_PerfMetric, trace_metric) < 65536 && pb_membersize(firebase_perf_v1_PerfMetric, network_request_metric) < 65536 && pb_membersize(firebase_perf_v1_PerfMetric, gauge_metric) < 65536 && pb_membersize(firebase_perf_v1_PerfMetric, transport_info) < 65536 && pb_membersize(firebase_perf_v1_GaugeMetric, gauge_metadata) < 65536 && pb_membersize(firebase_perf_v1_ApplicationInfo, android_app_info) < 65536 && pb_membersize(firebase_perf_v1_ApplicationInfo, ios_app_info) < 65536 && pb_membersize(firebase_perf_v1_ApplicationInfo, web_app_info) < 65536 && pb_membersize(firebase_perf_v1_IosApplicationInfo, network_connection_info) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_firebase_perf_v1_PerfMetric_firebase_perf_v1_TraceMetric_firebase_perf_v1_TraceMetric_CountersEntry_firebase_perf_v1_TraceMetric_CustomAttributesEntry_firebase_perf_v1_NetworkRequestMetric_firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_firebase_perf_v1_PerfSession_firebase_perf_v1_GaugeMetric_firebase_perf_v1_CpuMetricReading_firebase_perf_v1_IosMemoryReading_firebase_perf_v1_AndroidMemoryReading_firebase_perf_v1_GaugeMetadata_firebase_perf_v1_ApplicationInfo_firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_firebase_perf_v1_WebApplicationInfo_firebase_perf_v1_AndroidApplicationInfo_firebase_perf_v1_NetworkConnectionInfo_firebase_perf_v1_IosApplicationInfo_firebase_perf_v1_TransportInfo)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(firebase_perf_v1_PerfMetric, application_info) < 256 && pb_membersize(firebase_perf_v1_PerfMetric, trace_metric) < 256 && pb_membersize(firebase_perf_v1_PerfMetric, network_request_metric) < 256 && pb_membersize(firebase_perf_v1_PerfMetric, gauge_metric) < 256 && pb_membersize(firebase_perf_v1_PerfMetric, transport_info) < 256 && pb_membersize(firebase_perf_v1_GaugeMetric, gauge_metadata) < 256 && pb_membersize(firebase_perf_v1_ApplicationInfo, android_app_info) < 256 && pb_membersize(firebase_perf_v1_ApplicationInfo, ios_app_info) < 256 && pb_membersize(firebase_perf_v1_ApplicationInfo, web_app_info) < 256 && pb_membersize(firebase_perf_v1_IosApplicationInfo, network_connection_info) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_firebase_perf_v1_PerfMetric_firebase_perf_v1_TraceMetric_firebase_perf_v1_TraceMetric_CountersEntry_firebase_perf_v1_TraceMetric_CustomAttributesEntry_firebase_perf_v1_NetworkRequestMetric_firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_firebase_perf_v1_PerfSession_firebase_perf_v1_GaugeMetric_firebase_perf_v1_CpuMetricReading_firebase_perf_v1_IosMemoryReading_firebase_perf_v1_AndroidMemoryReading_firebase_perf_v1_GaugeMetadata_firebase_perf_v1_ApplicationInfo_firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_firebase_perf_v1_WebApplicationInfo_firebase_perf_v1_AndroidApplicationInfo_firebase_perf_v1_NetworkConnectionInfo_firebase_perf_v1_IosApplicationInfo_firebase_perf_v1_TransportInfo)
#endif
/* @@protoc_insertion_point(eof) */
@@ -0,0 +1,548 @@
/*
* Copyright 2021 Google LLC
*
* 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.
*/
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.9.8 */
#ifndef PB_FIREBASE_PERF_V1_PERF_METRIC_NANOPB_H_INCLUDED
#define PB_FIREBASE_PERF_V1_PERF_METRIC_NANOPB_H_INCLUDED
#include <nanopb/pb.h>
/* @@protoc_insertion_point(includes) */
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
/* Enum definitions */
typedef enum _firebase_perf_v1_ApplicationProcessState {
firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN = 0,
firebase_perf_v1_ApplicationProcessState_FOREGROUND = 1,
firebase_perf_v1_ApplicationProcessState_BACKGROUND = 2,
firebase_perf_v1_ApplicationProcessState_FOREGROUND_BACKGROUND = 3
} firebase_perf_v1_ApplicationProcessState;
#define _firebase_perf_v1_ApplicationProcessState_MIN firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN
#define _firebase_perf_v1_ApplicationProcessState_MAX firebase_perf_v1_ApplicationProcessState_FOREGROUND_BACKGROUND
#define _firebase_perf_v1_ApplicationProcessState_ARRAYSIZE ((firebase_perf_v1_ApplicationProcessState)(firebase_perf_v1_ApplicationProcessState_FOREGROUND_BACKGROUND+1))
typedef enum _firebase_perf_v1_SessionVerbosity {
firebase_perf_v1_SessionVerbosity_SESSION_VERBOSITY_NONE = 0,
firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS = 1
} firebase_perf_v1_SessionVerbosity;
#define _firebase_perf_v1_SessionVerbosity_MIN firebase_perf_v1_SessionVerbosity_SESSION_VERBOSITY_NONE
#define _firebase_perf_v1_SessionVerbosity_MAX firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS
#define _firebase_perf_v1_SessionVerbosity_ARRAYSIZE ((firebase_perf_v1_SessionVerbosity)(firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS+1))
typedef enum _firebase_perf_v1_VisibilityState {
firebase_perf_v1_VisibilityState_VISIBILITY_STATE_UNKNOWN = 0,
firebase_perf_v1_VisibilityState_VISIBLE = 1,
firebase_perf_v1_VisibilityState_HIDDEN = 2,
firebase_perf_v1_VisibilityState_PRERENDER = 3,
firebase_perf_v1_VisibilityState_UNLOADED = 4
} firebase_perf_v1_VisibilityState;
#define _firebase_perf_v1_VisibilityState_MIN firebase_perf_v1_VisibilityState_VISIBILITY_STATE_UNKNOWN
#define _firebase_perf_v1_VisibilityState_MAX firebase_perf_v1_VisibilityState_UNLOADED
#define _firebase_perf_v1_VisibilityState_ARRAYSIZE ((firebase_perf_v1_VisibilityState)(firebase_perf_v1_VisibilityState_UNLOADED+1))
typedef enum _firebase_perf_v1_ServiceWorkerStatus {
firebase_perf_v1_ServiceWorkerStatus_SERVICE_WORKER_STATUS_UNKNOWN = 0,
firebase_perf_v1_ServiceWorkerStatus_UNSUPPORTED = 1,
firebase_perf_v1_ServiceWorkerStatus_CONTROLLED = 2,
firebase_perf_v1_ServiceWorkerStatus_UNCONTROLLED = 3
} firebase_perf_v1_ServiceWorkerStatus;
#define _firebase_perf_v1_ServiceWorkerStatus_MIN firebase_perf_v1_ServiceWorkerStatus_SERVICE_WORKER_STATUS_UNKNOWN
#define _firebase_perf_v1_ServiceWorkerStatus_MAX firebase_perf_v1_ServiceWorkerStatus_UNCONTROLLED
#define _firebase_perf_v1_ServiceWorkerStatus_ARRAYSIZE ((firebase_perf_v1_ServiceWorkerStatus)(firebase_perf_v1_ServiceWorkerStatus_UNCONTROLLED+1))
typedef enum _firebase_perf_v1_EffectiveConnectionType {
firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0,
firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_SLOW_2G = 1,
firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_2G = 2,
firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_3G = 3,
firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_4G = 4
} firebase_perf_v1_EffectiveConnectionType;
#define _firebase_perf_v1_EffectiveConnectionType_MIN firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_UNKNOWN
#define _firebase_perf_v1_EffectiveConnectionType_MAX firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_4G
#define _firebase_perf_v1_EffectiveConnectionType_ARRAYSIZE ((firebase_perf_v1_EffectiveConnectionType)(firebase_perf_v1_EffectiveConnectionType_EFFECTIVE_CONNECTION_TYPE_4G+1))
typedef enum _firebase_perf_v1_NetworkRequestMetric_HttpMethod {
firebase_perf_v1_NetworkRequestMetric_HttpMethod_HTTP_METHOD_UNKNOWN = 0,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_GET = 1,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_PUT = 2,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_POST = 3,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_DELETE = 4,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_HEAD = 5,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_PATCH = 6,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_OPTIONS = 7,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_TRACE = 8,
firebase_perf_v1_NetworkRequestMetric_HttpMethod_CONNECT = 9
} firebase_perf_v1_NetworkRequestMetric_HttpMethod;
#define _firebase_perf_v1_NetworkRequestMetric_HttpMethod_MIN firebase_perf_v1_NetworkRequestMetric_HttpMethod_HTTP_METHOD_UNKNOWN
#define _firebase_perf_v1_NetworkRequestMetric_HttpMethod_MAX firebase_perf_v1_NetworkRequestMetric_HttpMethod_CONNECT
#define _firebase_perf_v1_NetworkRequestMetric_HttpMethod_ARRAYSIZE ((firebase_perf_v1_NetworkRequestMetric_HttpMethod)(firebase_perf_v1_NetworkRequestMetric_HttpMethod_CONNECT+1))
typedef enum _firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason {
firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_NETWORK_CLIENT_ERROR_REASON_UNKNOWN = 0,
firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_GENERIC_CLIENT_ERROR = 1
} firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason;
#define _firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_MIN firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_NETWORK_CLIENT_ERROR_REASON_UNKNOWN
#define _firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_MAX firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_GENERIC_CLIENT_ERROR
#define _firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_ARRAYSIZE ((firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason)(firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_GENERIC_CLIENT_ERROR+1))
typedef enum _firebase_perf_v1_NetworkConnectionInfo_NetworkType {
firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE = -1,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE = 0,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_WIFI = 1,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_MMS = 2,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_SUPL = 3,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_DUN = 4,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_HIPRI = 5,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_WIMAX = 6,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_BLUETOOTH = 7,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_DUMMY = 8,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_ETHERNET = 9,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_FOTA = 10,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_IMS = 11,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_CBS = 12,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_WIFI_P2P = 13,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_IA = 14,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE_EMERGENCY = 15,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_PROXY = 16,
firebase_perf_v1_NetworkConnectionInfo_NetworkType_VPN = 17
} firebase_perf_v1_NetworkConnectionInfo_NetworkType;
#define _firebase_perf_v1_NetworkConnectionInfo_NetworkType_MIN firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE
#define _firebase_perf_v1_NetworkConnectionInfo_NetworkType_MAX firebase_perf_v1_NetworkConnectionInfo_NetworkType_VPN
#define _firebase_perf_v1_NetworkConnectionInfo_NetworkType_ARRAYSIZE ((firebase_perf_v1_NetworkConnectionInfo_NetworkType)(firebase_perf_v1_NetworkConnectionInfo_NetworkType_VPN+1))
typedef enum _firebase_perf_v1_NetworkConnectionInfo_MobileSubtype {
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE = 0,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_GPRS = 1,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EDGE = 2,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UMTS = 3,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_CDMA = 4,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EVDO_0 = 5,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EVDO_A = 6,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_RTT = 7,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_HSDPA = 8,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_HSUPA = 9,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_HSPA = 10,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_IDEN = 11,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EVDO_B = 12,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_LTE = 13,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_EHRPD = 14,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_HSPAP = 15,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_GSM = 16,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_TD_SCDMA = 17,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_IWLAN = 18,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_LTE_CA = 19,
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_COMBINED = 100
} firebase_perf_v1_NetworkConnectionInfo_MobileSubtype;
#define _firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_MIN firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE
#define _firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_MAX firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_COMBINED
#define _firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_ARRAYSIZE ((firebase_perf_v1_NetworkConnectionInfo_MobileSubtype)(firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_COMBINED+1))
typedef enum _firebase_perf_v1_TransportInfo_DispatchDestination {
firebase_perf_v1_TransportInfo_DispatchDestination_SOURCE_UNKNOWN = 0,
firebase_perf_v1_TransportInfo_DispatchDestination_FL_LEGACY_V1 = 1
} firebase_perf_v1_TransportInfo_DispatchDestination;
#define _firebase_perf_v1_TransportInfo_DispatchDestination_MIN firebase_perf_v1_TransportInfo_DispatchDestination_SOURCE_UNKNOWN
#define _firebase_perf_v1_TransportInfo_DispatchDestination_MAX firebase_perf_v1_TransportInfo_DispatchDestination_FL_LEGACY_V1
#define _firebase_perf_v1_TransportInfo_DispatchDestination_ARRAYSIZE ((firebase_perf_v1_TransportInfo_DispatchDestination)(firebase_perf_v1_TransportInfo_DispatchDestination_FL_LEGACY_V1+1))
/* Struct definitions */
typedef struct _firebase_perf_v1_AndroidApplicationInfo {
pb_bytes_array_t *package_name;
pb_bytes_array_t *sdk_version;
pb_bytes_array_t *version_name;
/* @@protoc_insertion_point(struct:firebase_perf_v1_AndroidApplicationInfo) */
} firebase_perf_v1_AndroidApplicationInfo;
typedef struct _firebase_perf_v1_ApplicationInfo_CustomAttributesEntry {
pb_bytes_array_t *key;
pb_bytes_array_t *value;
/* @@protoc_insertion_point(struct:firebase_perf_v1_ApplicationInfo_CustomAttributesEntry) */
} firebase_perf_v1_ApplicationInfo_CustomAttributesEntry;
typedef struct _firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry {
pb_bytes_array_t *key;
pb_bytes_array_t *value;
/* @@protoc_insertion_point(struct:firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry) */
} firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry;
typedef struct _firebase_perf_v1_PerfSession {
pb_bytes_array_t *session_id;
pb_size_t session_verbosity_count;
firebase_perf_v1_SessionVerbosity *session_verbosity;
/* @@protoc_insertion_point(struct:firebase_perf_v1_PerfSession) */
} firebase_perf_v1_PerfSession;
typedef struct _firebase_perf_v1_TraceMetric_CustomAttributesEntry {
pb_bytes_array_t *key;
pb_bytes_array_t *value;
/* @@protoc_insertion_point(struct:firebase_perf_v1_TraceMetric_CustomAttributesEntry) */
} firebase_perf_v1_TraceMetric_CustomAttributesEntry;
typedef struct _firebase_perf_v1_AndroidMemoryReading {
bool has_client_time_us;
int64_t client_time_us;
bool has_used_app_java_heap_memory_kb;
int32_t used_app_java_heap_memory_kb;
/* @@protoc_insertion_point(struct:firebase_perf_v1_AndroidMemoryReading) */
} firebase_perf_v1_AndroidMemoryReading;
typedef struct _firebase_perf_v1_CpuMetricReading {
bool has_client_time_us;
int64_t client_time_us;
bool has_user_time_us;
int64_t user_time_us;
bool has_system_time_us;
int64_t system_time_us;
/* @@protoc_insertion_point(struct:firebase_perf_v1_CpuMetricReading) */
} firebase_perf_v1_CpuMetricReading;
typedef struct _firebase_perf_v1_GaugeMetadata {
pb_bytes_array_t *process_name;
bool has_cpu_clock_rate_khz;
int32_t cpu_clock_rate_khz;
bool has_device_ram_size_kb;
int32_t device_ram_size_kb;
bool has_max_app_java_heap_memory_kb;
int32_t max_app_java_heap_memory_kb;
bool has_max_encouraged_app_java_heap_memory_kb;
int32_t max_encouraged_app_java_heap_memory_kb;
bool has_cpu_processor_count;
int32_t cpu_processor_count;
/* @@protoc_insertion_point(struct:firebase_perf_v1_GaugeMetadata) */
} firebase_perf_v1_GaugeMetadata;
typedef struct _firebase_perf_v1_IosMemoryReading {
bool has_client_time_us;
int64_t client_time_us;
bool has_used_app_heap_memory_kb;
int32_t used_app_heap_memory_kb;
bool has_free_app_heap_memory_kb;
int32_t free_app_heap_memory_kb;
/* @@protoc_insertion_point(struct:firebase_perf_v1_IosMemoryReading) */
} firebase_perf_v1_IosMemoryReading;
typedef struct _firebase_perf_v1_NetworkConnectionInfo {
bool has_network_type;
firebase_perf_v1_NetworkConnectionInfo_NetworkType network_type;
bool has_mobile_subtype;
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype mobile_subtype;
/* @@protoc_insertion_point(struct:firebase_perf_v1_NetworkConnectionInfo) */
} firebase_perf_v1_NetworkConnectionInfo;
typedef struct _firebase_perf_v1_NetworkRequestMetric {
pb_bytes_array_t *url;
bool has_http_method;
firebase_perf_v1_NetworkRequestMetric_HttpMethod http_method;
bool has_request_payload_bytes;
int64_t request_payload_bytes;
bool has_response_payload_bytes;
int64_t response_payload_bytes;
bool has_http_response_code;
int32_t http_response_code;
pb_bytes_array_t *response_content_type;
bool has_client_start_time_us;
int64_t client_start_time_us;
bool has_time_to_request_completed_us;
int64_t time_to_request_completed_us;
bool has_time_to_response_initiated_us;
int64_t time_to_response_initiated_us;
bool has_time_to_response_completed_us;
int64_t time_to_response_completed_us;
bool has_network_client_error_reason;
firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason network_client_error_reason;
pb_size_t custom_attributes_count;
struct _firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry *custom_attributes;
pb_size_t perf_sessions_count;
struct _firebase_perf_v1_PerfSession *perf_sessions;
/* @@protoc_insertion_point(struct:firebase_perf_v1_NetworkRequestMetric) */
} firebase_perf_v1_NetworkRequestMetric;
typedef struct _firebase_perf_v1_TraceMetric {
pb_bytes_array_t *name;
bool has_is_auto;
bool is_auto;
bool has_client_start_time_us;
int64_t client_start_time_us;
bool has_duration_us;
int64_t duration_us;
pb_size_t counters_count;
struct _firebase_perf_v1_TraceMetric_CountersEntry *counters;
pb_size_t subtraces_count;
struct _firebase_perf_v1_TraceMetric *subtraces;
pb_size_t custom_attributes_count;
struct _firebase_perf_v1_TraceMetric_CustomAttributesEntry *custom_attributes;
pb_size_t perf_sessions_count;
struct _firebase_perf_v1_PerfSession *perf_sessions;
/* @@protoc_insertion_point(struct:firebase_perf_v1_TraceMetric) */
} firebase_perf_v1_TraceMetric;
typedef struct _firebase_perf_v1_TraceMetric_CountersEntry {
pb_bytes_array_t *key;
bool has_value;
int64_t value;
/* @@protoc_insertion_point(struct:firebase_perf_v1_TraceMetric_CountersEntry) */
} firebase_perf_v1_TraceMetric_CountersEntry;
typedef struct _firebase_perf_v1_TransportInfo {
bool has_dispatch_destination;
firebase_perf_v1_TransportInfo_DispatchDestination dispatch_destination;
/* @@protoc_insertion_point(struct:firebase_perf_v1_TransportInfo) */
} firebase_perf_v1_TransportInfo;
typedef struct _firebase_perf_v1_WebApplicationInfo {
pb_bytes_array_t *sdk_version;
pb_bytes_array_t *page_url;
bool has_service_worker_status;
firebase_perf_v1_ServiceWorkerStatus service_worker_status;
bool has_visibility_state;
firebase_perf_v1_VisibilityState visibility_state;
bool has_effective_connection_type;
firebase_perf_v1_EffectiveConnectionType effective_connection_type;
/* @@protoc_insertion_point(struct:firebase_perf_v1_WebApplicationInfo) */
} firebase_perf_v1_WebApplicationInfo;
typedef struct _firebase_perf_v1_GaugeMetric {
pb_bytes_array_t *session_id;
pb_size_t cpu_metric_readings_count;
struct _firebase_perf_v1_CpuMetricReading *cpu_metric_readings;
bool has_gauge_metadata;
firebase_perf_v1_GaugeMetadata gauge_metadata;
pb_size_t android_memory_readings_count;
struct _firebase_perf_v1_AndroidMemoryReading *android_memory_readings;
pb_size_t ios_memory_readings_count;
struct _firebase_perf_v1_IosMemoryReading *ios_memory_readings;
/* @@protoc_insertion_point(struct:firebase_perf_v1_GaugeMetric) */
} firebase_perf_v1_GaugeMetric;
typedef struct _firebase_perf_v1_IosApplicationInfo {
pb_bytes_array_t *sdk_version;
pb_bytes_array_t *bundle_short_version;
pb_bytes_array_t *mcc_mnc;
bool has_network_connection_info;
firebase_perf_v1_NetworkConnectionInfo network_connection_info;
/* @@protoc_insertion_point(struct:firebase_perf_v1_IosApplicationInfo) */
} firebase_perf_v1_IosApplicationInfo;
typedef struct _firebase_perf_v1_ApplicationInfo {
pb_bytes_array_t *google_app_id;
pb_bytes_array_t *app_instance_id;
bool has_android_app_info;
firebase_perf_v1_AndroidApplicationInfo android_app_info;
bool has_ios_app_info;
firebase_perf_v1_IosApplicationInfo ios_app_info;
bool has_application_process_state;
firebase_perf_v1_ApplicationProcessState application_process_state;
pb_size_t custom_attributes_count;
struct _firebase_perf_v1_ApplicationInfo_CustomAttributesEntry *custom_attributes;
bool has_web_app_info;
firebase_perf_v1_WebApplicationInfo web_app_info;
/* @@protoc_insertion_point(struct:firebase_perf_v1_ApplicationInfo) */
} firebase_perf_v1_ApplicationInfo;
typedef struct _firebase_perf_v1_PerfMetric {
bool has_application_info;
firebase_perf_v1_ApplicationInfo application_info;
bool has_trace_metric;
firebase_perf_v1_TraceMetric trace_metric;
bool has_network_request_metric;
firebase_perf_v1_NetworkRequestMetric network_request_metric;
bool has_gauge_metric;
firebase_perf_v1_GaugeMetric gauge_metric;
bool has_transport_info;
firebase_perf_v1_TransportInfo transport_info;
/* @@protoc_insertion_point(struct:firebase_perf_v1_PerfMetric) */
} firebase_perf_v1_PerfMetric;
/* Default values for struct fields */
extern const firebase_perf_v1_NetworkConnectionInfo_NetworkType firebase_perf_v1_NetworkConnectionInfo_network_type_default;
extern const firebase_perf_v1_NetworkConnectionInfo_MobileSubtype firebase_perf_v1_NetworkConnectionInfo_mobile_subtype_default;
/* Initializer values for message structs */
#define firebase_perf_v1_PerfMetric_init_default {false, firebase_perf_v1_ApplicationInfo_init_default, false, firebase_perf_v1_TraceMetric_init_default, false, firebase_perf_v1_NetworkRequestMetric_init_default, false, firebase_perf_v1_GaugeMetric_init_default, false, firebase_perf_v1_TransportInfo_init_default}
#define firebase_perf_v1_TraceMetric_init_default {NULL, false, 0, false, 0, false, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL}
#define firebase_perf_v1_TraceMetric_CountersEntry_init_default {NULL, false, 0}
#define firebase_perf_v1_TraceMetric_CustomAttributesEntry_init_default {NULL, NULL}
#define firebase_perf_v1_NetworkRequestMetric_init_default {NULL, false, _firebase_perf_v1_NetworkRequestMetric_HttpMethod_MIN, false, 0, false, 0, false, 0, NULL, false, 0, false, 0, false, 0, false, 0, false, _firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_MIN, 0, NULL, 0, NULL}
#define firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_init_default {NULL, NULL}
#define firebase_perf_v1_PerfSession_init_default {NULL, 0, NULL}
#define firebase_perf_v1_GaugeMetric_init_default {NULL, 0, NULL, false, firebase_perf_v1_GaugeMetadata_init_default, 0, NULL, 0, NULL}
#define firebase_perf_v1_CpuMetricReading_init_default {false, 0, false, 0, false, 0}
#define firebase_perf_v1_IosMemoryReading_init_default {false, 0, false, 0, false, 0}
#define firebase_perf_v1_AndroidMemoryReading_init_default {false, 0, false, 0}
#define firebase_perf_v1_GaugeMetadata_init_default {NULL, false, 0, false, 0, false, 0, false, 0, false, 0}
#define firebase_perf_v1_ApplicationInfo_init_default {NULL, NULL, false, firebase_perf_v1_AndroidApplicationInfo_init_default, false, firebase_perf_v1_IosApplicationInfo_init_default, false, _firebase_perf_v1_ApplicationProcessState_MIN, 0, NULL, false, firebase_perf_v1_WebApplicationInfo_init_default}
#define firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_init_default {NULL, NULL}
#define firebase_perf_v1_WebApplicationInfo_init_default {NULL, NULL, false, _firebase_perf_v1_ServiceWorkerStatus_MIN, false, _firebase_perf_v1_VisibilityState_MIN, false, _firebase_perf_v1_EffectiveConnectionType_MIN}
#define firebase_perf_v1_AndroidApplicationInfo_init_default {NULL, NULL, NULL}
#define firebase_perf_v1_NetworkConnectionInfo_init_default {false, firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE, false, firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE}
#define firebase_perf_v1_IosApplicationInfo_init_default {NULL, NULL, NULL, false, firebase_perf_v1_NetworkConnectionInfo_init_default}
#define firebase_perf_v1_TransportInfo_init_default {false, _firebase_perf_v1_TransportInfo_DispatchDestination_MIN}
#define firebase_perf_v1_PerfMetric_init_zero {false, firebase_perf_v1_ApplicationInfo_init_zero, false, firebase_perf_v1_TraceMetric_init_zero, false, firebase_perf_v1_NetworkRequestMetric_init_zero, false, firebase_perf_v1_GaugeMetric_init_zero, false, firebase_perf_v1_TransportInfo_init_zero}
#define firebase_perf_v1_TraceMetric_init_zero {NULL, false, 0, false, 0, false, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL}
#define firebase_perf_v1_TraceMetric_CountersEntry_init_zero {NULL, false, 0}
#define firebase_perf_v1_TraceMetric_CustomAttributesEntry_init_zero {NULL, NULL}
#define firebase_perf_v1_NetworkRequestMetric_init_zero {NULL, false, _firebase_perf_v1_NetworkRequestMetric_HttpMethod_MIN, false, 0, false, 0, false, 0, NULL, false, 0, false, 0, false, 0, false, 0, false, _firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_MIN, 0, NULL, 0, NULL}
#define firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_init_zero {NULL, NULL}
#define firebase_perf_v1_PerfSession_init_zero {NULL, 0, NULL}
#define firebase_perf_v1_GaugeMetric_init_zero {NULL, 0, NULL, false, firebase_perf_v1_GaugeMetadata_init_zero, 0, NULL, 0, NULL}
#define firebase_perf_v1_CpuMetricReading_init_zero {false, 0, false, 0, false, 0}
#define firebase_perf_v1_IosMemoryReading_init_zero {false, 0, false, 0, false, 0}
#define firebase_perf_v1_AndroidMemoryReading_init_zero {false, 0, false, 0}
#define firebase_perf_v1_GaugeMetadata_init_zero {NULL, false, 0, false, 0, false, 0, false, 0, false, 0}
#define firebase_perf_v1_ApplicationInfo_init_zero {NULL, NULL, false, firebase_perf_v1_AndroidApplicationInfo_init_zero, false, firebase_perf_v1_IosApplicationInfo_init_zero, false, _firebase_perf_v1_ApplicationProcessState_MIN, 0, NULL, false, firebase_perf_v1_WebApplicationInfo_init_zero}
#define firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_init_zero {NULL, NULL}
#define firebase_perf_v1_WebApplicationInfo_init_zero {NULL, NULL, false, _firebase_perf_v1_ServiceWorkerStatus_MIN, false, _firebase_perf_v1_VisibilityState_MIN, false, _firebase_perf_v1_EffectiveConnectionType_MIN}
#define firebase_perf_v1_AndroidApplicationInfo_init_zero {NULL, NULL, NULL}
#define firebase_perf_v1_NetworkConnectionInfo_init_zero {false, _firebase_perf_v1_NetworkConnectionInfo_NetworkType_MIN, false, _firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_MIN}
#define firebase_perf_v1_IosApplicationInfo_init_zero {NULL, NULL, NULL, false, firebase_perf_v1_NetworkConnectionInfo_init_zero}
#define firebase_perf_v1_TransportInfo_init_zero {false, _firebase_perf_v1_TransportInfo_DispatchDestination_MIN}
/* Field tags (for use in manual encoding/decoding) */
#define firebase_perf_v1_AndroidApplicationInfo_package_name_tag 1
#define firebase_perf_v1_AndroidApplicationInfo_sdk_version_tag 2
#define firebase_perf_v1_AndroidApplicationInfo_version_name_tag 3
#define firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_key_tag 1
#define firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_value_tag 2
#define firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_key_tag 1
#define firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_value_tag 2
#define firebase_perf_v1_PerfSession_session_id_tag 1
#define firebase_perf_v1_PerfSession_session_verbosity_tag 2
#define firebase_perf_v1_TraceMetric_CustomAttributesEntry_key_tag 1
#define firebase_perf_v1_TraceMetric_CustomAttributesEntry_value_tag 2
#define firebase_perf_v1_AndroidMemoryReading_client_time_us_tag 1
#define firebase_perf_v1_AndroidMemoryReading_used_app_java_heap_memory_kb_tag 2
#define firebase_perf_v1_CpuMetricReading_client_time_us_tag 1
#define firebase_perf_v1_CpuMetricReading_user_time_us_tag 2
#define firebase_perf_v1_CpuMetricReading_system_time_us_tag 3
#define firebase_perf_v1_GaugeMetadata_process_name_tag 1
#define firebase_perf_v1_GaugeMetadata_cpu_clock_rate_khz_tag 2
#define firebase_perf_v1_GaugeMetadata_cpu_processor_count_tag 6
#define firebase_perf_v1_GaugeMetadata_device_ram_size_kb_tag 3
#define firebase_perf_v1_GaugeMetadata_max_app_java_heap_memory_kb_tag 4
#define firebase_perf_v1_GaugeMetadata_max_encouraged_app_java_heap_memory_kb_tag 5
#define firebase_perf_v1_IosMemoryReading_client_time_us_tag 1
#define firebase_perf_v1_IosMemoryReading_used_app_heap_memory_kb_tag 2
#define firebase_perf_v1_IosMemoryReading_free_app_heap_memory_kb_tag 3
#define firebase_perf_v1_NetworkConnectionInfo_network_type_tag 1
#define firebase_perf_v1_NetworkConnectionInfo_mobile_subtype_tag 2
#define firebase_perf_v1_NetworkRequestMetric_url_tag 1
#define firebase_perf_v1_NetworkRequestMetric_http_method_tag 2
#define firebase_perf_v1_NetworkRequestMetric_request_payload_bytes_tag 3
#define firebase_perf_v1_NetworkRequestMetric_response_payload_bytes_tag 4
#define firebase_perf_v1_NetworkRequestMetric_network_client_error_reason_tag 11
#define firebase_perf_v1_NetworkRequestMetric_http_response_code_tag 5
#define firebase_perf_v1_NetworkRequestMetric_response_content_type_tag 6
#define firebase_perf_v1_NetworkRequestMetric_client_start_time_us_tag 7
#define firebase_perf_v1_NetworkRequestMetric_time_to_request_completed_us_tag 8
#define firebase_perf_v1_NetworkRequestMetric_time_to_response_initiated_us_tag 9
#define firebase_perf_v1_NetworkRequestMetric_time_to_response_completed_us_tag 10
#define firebase_perf_v1_NetworkRequestMetric_custom_attributes_tag 12
#define firebase_perf_v1_NetworkRequestMetric_perf_sessions_tag 13
#define firebase_perf_v1_TraceMetric_name_tag 1
#define firebase_perf_v1_TraceMetric_is_auto_tag 2
#define firebase_perf_v1_TraceMetric_client_start_time_us_tag 4
#define firebase_perf_v1_TraceMetric_duration_us_tag 5
#define firebase_perf_v1_TraceMetric_counters_tag 6
#define firebase_perf_v1_TraceMetric_subtraces_tag 7
#define firebase_perf_v1_TraceMetric_custom_attributes_tag 8
#define firebase_perf_v1_TraceMetric_perf_sessions_tag 9
#define firebase_perf_v1_TraceMetric_CountersEntry_key_tag 1
#define firebase_perf_v1_TraceMetric_CountersEntry_value_tag 2
#define firebase_perf_v1_TransportInfo_dispatch_destination_tag 1
#define firebase_perf_v1_WebApplicationInfo_sdk_version_tag 1
#define firebase_perf_v1_WebApplicationInfo_page_url_tag 2
#define firebase_perf_v1_WebApplicationInfo_service_worker_status_tag 3
#define firebase_perf_v1_WebApplicationInfo_visibility_state_tag 4
#define firebase_perf_v1_WebApplicationInfo_effective_connection_type_tag 5
#define firebase_perf_v1_GaugeMetric_session_id_tag 1
#define firebase_perf_v1_GaugeMetric_gauge_metadata_tag 3
#define firebase_perf_v1_GaugeMetric_cpu_metric_readings_tag 2
#define firebase_perf_v1_GaugeMetric_android_memory_readings_tag 4
#define firebase_perf_v1_GaugeMetric_ios_memory_readings_tag 5
#define firebase_perf_v1_IosApplicationInfo_sdk_version_tag 2
#define firebase_perf_v1_IosApplicationInfo_bundle_short_version_tag 3
#define firebase_perf_v1_IosApplicationInfo_mcc_mnc_tag 4
#define firebase_perf_v1_IosApplicationInfo_network_connection_info_tag 5
#define firebase_perf_v1_ApplicationInfo_google_app_id_tag 1
#define firebase_perf_v1_ApplicationInfo_app_instance_id_tag 2
#define firebase_perf_v1_ApplicationInfo_android_app_info_tag 3
#define firebase_perf_v1_ApplicationInfo_ios_app_info_tag 4
#define firebase_perf_v1_ApplicationInfo_web_app_info_tag 7
#define firebase_perf_v1_ApplicationInfo_application_process_state_tag 5
#define firebase_perf_v1_ApplicationInfo_custom_attributes_tag 6
#define firebase_perf_v1_PerfMetric_application_info_tag 1
#define firebase_perf_v1_PerfMetric_trace_metric_tag 2
#define firebase_perf_v1_PerfMetric_network_request_metric_tag 3
#define firebase_perf_v1_PerfMetric_gauge_metric_tag 4
#define firebase_perf_v1_PerfMetric_transport_info_tag 5
/* Struct field encoding specification for nanopb */
extern const pb_field_t firebase_perf_v1_PerfMetric_fields[6];
extern const pb_field_t firebase_perf_v1_TraceMetric_fields[9];
extern const pb_field_t firebase_perf_v1_TraceMetric_CountersEntry_fields[3];
extern const pb_field_t firebase_perf_v1_TraceMetric_CustomAttributesEntry_fields[3];
extern const pb_field_t firebase_perf_v1_NetworkRequestMetric_fields[14];
extern const pb_field_t firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_fields[3];
extern const pb_field_t firebase_perf_v1_PerfSession_fields[3];
extern const pb_field_t firebase_perf_v1_GaugeMetric_fields[6];
extern const pb_field_t firebase_perf_v1_CpuMetricReading_fields[4];
extern const pb_field_t firebase_perf_v1_IosMemoryReading_fields[4];
extern const pb_field_t firebase_perf_v1_AndroidMemoryReading_fields[3];
extern const pb_field_t firebase_perf_v1_GaugeMetadata_fields[7];
extern const pb_field_t firebase_perf_v1_ApplicationInfo_fields[8];
extern const pb_field_t firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_fields[3];
extern const pb_field_t firebase_perf_v1_WebApplicationInfo_fields[6];
extern const pb_field_t firebase_perf_v1_AndroidApplicationInfo_fields[4];
extern const pb_field_t firebase_perf_v1_NetworkConnectionInfo_fields[3];
extern const pb_field_t firebase_perf_v1_IosApplicationInfo_fields[5];
extern const pb_field_t firebase_perf_v1_TransportInfo_fields[2];
/* Maximum encoded size of messages (where known) */
/* firebase_perf_v1_PerfMetric_size depends on runtime parameters */
/* firebase_perf_v1_TraceMetric_size depends on runtime parameters */
/* firebase_perf_v1_TraceMetric_CountersEntry_size depends on runtime parameters */
/* firebase_perf_v1_TraceMetric_CustomAttributesEntry_size depends on runtime parameters */
/* firebase_perf_v1_NetworkRequestMetric_size depends on runtime parameters */
/* firebase_perf_v1_NetworkRequestMetric_CustomAttributesEntry_size depends on runtime parameters */
/* firebase_perf_v1_PerfSession_size depends on runtime parameters */
/* firebase_perf_v1_GaugeMetric_size depends on runtime parameters */
#define firebase_perf_v1_CpuMetricReading_size 33
#define firebase_perf_v1_IosMemoryReading_size 33
#define firebase_perf_v1_AndroidMemoryReading_size 22
/* firebase_perf_v1_GaugeMetadata_size depends on runtime parameters */
/* firebase_perf_v1_ApplicationInfo_size depends on runtime parameters */
/* firebase_perf_v1_ApplicationInfo_CustomAttributesEntry_size depends on runtime parameters */
/* firebase_perf_v1_WebApplicationInfo_size depends on runtime parameters */
/* firebase_perf_v1_AndroidApplicationInfo_size depends on runtime parameters */
#define firebase_perf_v1_NetworkConnectionInfo_size 13
/* firebase_perf_v1_IosApplicationInfo_size depends on runtime parameters */
#define firebase_perf_v1_TransportInfo_size 2
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define PERF_METRIC_MESSAGES \
#endif
/* @@protoc_insertion_point(eof) */
#endif
+1 -1
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
#import "FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.h"
#import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"
@@ -19,7 +19,7 @@
#import "ViewControllers/TracesViewController.h"
#import "FirebaseCore/FirebaseCore.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
@interface AppDelegate ()
@@ -20,7 +20,7 @@
#import "../Views/PerfTraceView.h"
#import "TracesViewController+Accessibility.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
/** Edge insets used by internal subviews. */
static const CGFloat kEdgeInsetsTop = 10.0f;
@@ -15,7 +15,7 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
@class PerfTraceView;
@@ -20,7 +20,7 @@
#import "FirebasePerformance/Sources/FIRPerformance_Private.h"
#import "FirebasePerformance/Sources/FPRClient+Private.h"
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Tests/Unit/Fakes/FPRFakeClient.h"
@@ -15,7 +15,7 @@
#import <XCTest/XCTest.h>
#import "FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
@@ -51,6 +51,8 @@
/** Validates if an active trace is available when the app is active. */
- (void)testActiveTrace {
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
XCTAssertNotNil([FPRAppActivityTracker sharedInstance].activeTrace);
@@ -61,6 +63,8 @@
BOOL dataCollectionEnabled = [FIRPerformance sharedInstance].dataCollectionEnabled;
[[FIRPerformance sharedInstance] setDataCollectionEnabled:NO];
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
XCTAssertNil([FPRAppActivityTracker sharedInstance].activeTrace);
@@ -74,6 +78,8 @@
FIRTrace *activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
@@ -91,6 +97,8 @@
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
FIRTrace *activeTrace = nil;
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
@@ -110,6 +118,8 @@
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
FIRTrace *activeTrace = nil;
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
@@ -140,6 +150,8 @@
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
FIRTrace *activeTrace = nil;
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
@@ -166,6 +178,8 @@
FPRAppActivityTracker *appTracker = [FPRAppActivityTracker sharedInstance];
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillResignActiveNotification
object:[UIApplication sharedApplication]];
XCTAssertEqual(appTracker.applicationState, FPRApplicationStateBackground);
@@ -55,6 +55,10 @@
XCTAssertThrows([classInstrumentor instrumentorForClassSelector:@selector(description)]);
}
#pragma mark - Unswizzle based tests
#if !SWIFT_PACKAGE
/** Tests swizzling an instance selector. */
- (void)testSwizzleInstanceSelector {
FPRClassInstrumentor *classInstrumentor =
@@ -154,4 +158,6 @@
[classInstrumentor unswizzle];
}
#endif // SWIFT_PACKAGE
@end
+13 -9
View File
@@ -27,7 +27,7 @@
#import "FirebasePerformance/Tests/Unit/Fakes/FPRFakeInstallations.h"
#import <OCMock/OCMock.h>
#import "GoogleDataTransport/GDTCORTests/Common/Fakes/GDTCORTransportFake.h"
#import "SharedTestUtilities/GDTCORTransportFake.h"
@interface FPRClientTest : FPRTestCase
@@ -68,7 +68,7 @@
/** Validates if the gdtTransport logger has received trace perfMetric. */
- (void)testLogAndProcessEventsForTrace {
// Trace type PerfMetric for event dispatch.
FPRMSGPerfMetric *perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
// Act on event logging call.
[self.client processAndLogEvent:perfMetric];
@@ -82,14 +82,16 @@
(GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
GDTCOREvent *event = fakeGdtTransport.logEvents.firstObject;
XCTAssertEqualObjects([event.dataObject transportBytes], perfMetric.data);
XCTAssertEqualObjects([event.dataObject transportBytes],
[[FPRGDTEvent gdtEventForPerfMetric:perfMetric] transportBytes]);
});
}
/** Validates if the gdtTransport logger has received network trace perfMetric. */
- (void)testLogAndProcessEventsForNetworkTrace {
// Network type PerfMetric for event dispatch.
FPRMSGPerfMetric *perfMetric = [FPRTestUtils createRandomNetworkPerfMetric:@"https://abc.xyz"];
firebase_perf_v1_PerfMetric perfMetric =
[FPRTestUtils createRandomNetworkPerfMetric:@"https://abc.xyz"];
// Act on event logging call.
[self.client processAndLogEvent:perfMetric];
@@ -103,14 +105,15 @@
(GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
GDTCOREvent *event = fakeGdtTransport.logEvents.firstObject;
XCTAssertEqualObjects([event.dataObject transportBytes], perfMetric.data);
XCTAssertEqualObjects([event.dataObject transportBytes],
[[FPRGDTEvent gdtEventForPerfMetric:perfMetric] transportBytes]);
});
}
/** Validates if the gdtTransport logger has received session gauge perfMetric. */
- (void)testLogAndProcessEventsForGauge {
// Gauge type PerfMetric for event dispatch.
FPRMSGPerfMetric *perfMetric = [FPRTestUtils createRandomGaugePerfMetric];
firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomGaugePerfMetric];
// Act on event logging call.
[self.client processAndLogEvent:perfMetric];
@@ -124,14 +127,15 @@
(GDTCORTransportFake *)self.client.gdtLogger.gdtfllTransport;
XCTAssertEqual(fakeGdtTransport.logEvents.count, 1);
GDTCOREvent *event = fakeGdtTransport.logEvents.firstObject;
XCTAssertEqualObjects([event.dataObject transportBytes], perfMetric.data);
XCTAssertEqualObjects([event.dataObject transportBytes],
[[FPRGDTEvent gdtEventForPerfMetric:perfMetric] transportBytes]);
});
}
/** Validates if the gdtTransport logger will not receive event when data collection is disabled. */
- (void)testLogAndProcessEventsNotDispatchWhenDisabled {
// Trace type PerfMetric for event dispatch.
FPRMSGPerfMetric *perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
// Act on event logging call when data collection is disabled.
self.configurations.dataCollectionEnabled = NO;
@@ -152,7 +156,7 @@
* re-enabled. */
- (void)testLogAndProcessEventsAfterReenabled {
// Trace type PerfMetric for event dispatch.
FPRMSGPerfMetric *perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
firebase_perf_v1_PerfMetric perfMetric = [FPRTestUtils createRandomPerfMetric:@"RandomTrace"];
// Act on event logging call when data collection is disabled.
self.configurations.dataCollectionEnabled = NO;
@@ -63,6 +63,10 @@
[instrument deregisterInstrumentors];
}
#pragma mark - Unswizzle based tests
#if !SWIFT_PACKAGE
- (void)testDeregisterInstrumentors {
FPRInstrument *instrument = [[FPRInstrument alloc] init];
FPRClassInstrumentor *classInstrumentor =
@@ -82,4 +86,6 @@
[classInstrumentor unswizzle];
}
#endif // SWIFT_PACKAGE
@end
@@ -35,6 +35,10 @@
XCTAssertNotNil(instrumentation);
}
#pragma mark - Unswizzle based tests
#ifndef SWIFT_PACKAGE
- (void)testRegisterInstrumentGroup {
FPRInstrumentation *instrumentation = [[FPRInstrumentation alloc] init];
NSUInteger numberOfInstrumentsInGroup =
@@ -49,4 +53,6 @@
XCTAssertTrue([instrumentation deregisterInstrumentGroup:kFPRInstrumentationGroupNetworkKey]);
}
#endif // SWIFT_PACKAGE
@end
@@ -1,4 +1,4 @@
// Copyright 2020 Google LLC
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
#import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
#import "FirebasePerformance/Sources/FPRDataUtils.h"
#import "FirebasePerformance/Sources/FPRProtoUtils.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Common/FPRConstants.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace+Private.h"
@@ -32,11 +32,11 @@
#import <OCMock/OCMock.h>
@interface FPRProtoUtilsTest : FPRTestCase
@interface FPRNanoPbUtilsTest : FPRTestCase
@end
@implementation FPRProtoUtilsTest
@implementation FPRNanoPbUtilsTest
- (void)setUp {
[super setUp];
@@ -50,42 +50,48 @@
[performance setDataCollectionEnabled:NO];
}
/** Validates that a PerfMetricMessage creation is successful. */
/** Validates that a firebase_perf_v1_PerfMetric creation is successful. */
- (void)testPerfMetricMessageCreation {
NSString *appID = @"RandomAppID";
FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(appID);
XCTAssertEqualObjects(perfMetric.applicationInfo.googleAppId, appID);
XCTAssertNotNil(perfMetric.applicationInfo);
firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(appID);
XCTAssertEqualObjects(FPRDecodeString(perfMetric.application_info.google_app_id), appID);
}
/** Tests if the application information is populated when creating a FPRMSGPerfMetric message. */
/** Tests if the application information is populated when creating a firebase_perf_v1_PerfMetric.
*/
- (void)testApplicationInfoMessage {
FPRMSGPerfMetric *event = FPRGetPerfMetricMessage(@"appid");
FPRMSGApplicationInfo *appInfo = event.applicationInfo;
XCTAssertEqual(appInfo.googleAppId, @"appid");
XCTAssertNotNil(appInfo.iosAppInfo.sdkVersion);
XCTAssertNotNil(appInfo.iosAppInfo.bundleShortVersion);
XCTAssertTrue((appInfo.iosAppInfo.mccMnc.length == 0) || (appInfo.iosAppInfo.mccMnc.length == 6));
XCTAssertTrue(appInfo.iosAppInfo.networkConnectionInfo.networkType !=
FPRMSGNetworkConnectionInfo_NetworkType_None);
if (appInfo.iosAppInfo.networkConnectionInfo.networkType ==
FPRMSGNetworkConnectionInfo_NetworkType_Mobile) {
XCTAssertTrue(appInfo.iosAppInfo.networkConnectionInfo.mobileSubtype !=
FPRMSGNetworkConnectionInfo_MobileSubtype_UnknownMobileSubtype);
firebase_perf_v1_PerfMetric event = FPRGetPerfMetricMessage(@"appid");
firebase_perf_v1_ApplicationInfo appInfo = event.application_info;
XCTAssertEqualObjects(FPRDecodeString(appInfo.google_app_id), @"appid");
XCTAssertTrue(appInfo.ios_app_info.sdk_version != NULL);
XCTAssertTrue(appInfo.has_ios_app_info);
XCTAssertTrue(appInfo.ios_app_info.bundle_short_version != NULL);
XCTAssertTrue(appInfo.ios_app_info.mcc_mnc == NULL || appInfo.ios_app_info.mcc_mnc->size == 6);
XCTAssertTrue(appInfo.ios_app_info.has_network_connection_info);
XCTAssertTrue(appInfo.ios_app_info.network_connection_info.has_network_type);
XCTAssertTrue(appInfo.ios_app_info.network_connection_info.network_type !=
firebase_perf_v1_NetworkConnectionInfo_NetworkType_NONE);
if (appInfo.ios_app_info.network_connection_info.network_type ==
firebase_perf_v1_NetworkConnectionInfo_NetworkType_MOBILE) {
XCTAssertTrue(appInfo.ios_app_info.network_connection_info.mobile_subtype !=
firebase_perf_v1_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE);
}
}
/** Validates that ApplicationInfoMessage carries global attributes. */
- (void)testApplicationInfoMessageWithAttributes {
FIRPerformance *performance = [FIRPerformance sharedInstance];
[performance setValue:@"bar" forAttribute:@"foo"];
FPRMSGPerfMetric *event = FPRGetPerfMetricMessage(@"appid");
FPRMSGApplicationInfo *appInfo = event.applicationInfo;
XCTAssertNotNil(appInfo.customAttributes);
XCTAssertEqual(appInfo.customAttributes.allKeys.count, 1);
NSDictionary *attributes = appInfo.customAttributes;
XCTAssertEqual(attributes[@"foo"], @"bar");
[performance removeAttribute:@"foo"];
[performance setValue:@"bar1" forAttribute:@"foo1"];
[performance setValue:@"bar2" forAttribute:@"foo2"];
firebase_perf_v1_PerfMetric event = FPRGetPerfMetricMessage(@"appid");
firebase_perf_v1_ApplicationInfo appInfo = event.application_info;
XCTAssertEqual(appInfo.custom_attributes_count, 2);
NSDictionary *attributes = FPRDecodeStringToStringMap(
(StringToStringMap *)appInfo.custom_attributes, appInfo.custom_attributes_count);
XCTAssertEqualObjects(attributes[@"foo1"], @"bar1");
XCTAssertEqualObjects(attributes[@"foo2"], @"bar2");
[performance removeAttribute:@"foo1"];
[performance removeAttribute:@"foo2"];
}
/** Tests if mccMnc validation is catching non numerals. */
@@ -112,7 +118,8 @@
XCTAssertNil(mccMnc);
}
/** Validates that a valid FIRTrace object to Proto conversion is successful. */
/** Validates that a valid FIRTrace object to firebase_perf_v1_TraceMetric conversion is successful.
*/
- (void)testTraceMetricMessageCreation {
FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
[trace start];
@@ -121,31 +128,34 @@
[trace incrementMetric:@"c1" byInt:2];
[trace setValue:@"bar" forAttribute:@"foo"];
[trace stop];
FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
XCTAssertNotNil(traceMetric);
XCTAssertEqualObjects(traceMetric.name, @"Random");
XCTAssertEqual(traceMetric.subtracesArray.count, 2);
XCTAssertEqual(traceMetric.counters.count, 1);
XCTAssertEqualObjects(traceMetric.subtracesArray[0].name, @"1");
XCTAssertEqualObjects(traceMetric.subtracesArray[1].name, @"2");
XCTAssertNotNil(traceMetric.customAttributes);
XCTAssertEqual(traceMetric.customAttributes.allKeys.count, 1);
NSDictionary *attributes = traceMetric.customAttributes;
XCTAssertEqual(attributes[@"foo"], @"bar");
firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
XCTAssertEqualObjects(FPRDecodeString(traceMetric.name), @"Random");
XCTAssertEqual(traceMetric.subtraces_count, 2);
XCTAssertEqual(traceMetric.counters_count, 1);
NSDictionary *counters = FPRDecodeStringToNumberMap((StringToNumberMap *)traceMetric.counters,
traceMetric.counters_count);
XCTAssertEqual([counters[@"c1"] intValue], 2);
XCTAssertEqualObjects(FPRDecodeString(traceMetric.subtraces[0].name), @"1");
XCTAssertEqualObjects(FPRDecodeString(traceMetric.subtraces[1].name), @"2");
XCTAssertTrue(traceMetric.custom_attributes != NULL);
XCTAssertEqual(traceMetric.custom_attributes_count, 1);
NSDictionary *attributes = FPRDecodeStringToStringMap(
(StringToStringMap *)traceMetric.custom_attributes, traceMetric.custom_attributes_count);
XCTAssertEqualObjects(attributes[@"foo"], @"bar");
}
/** Validates that a valid FIRTrace object to Proto conversion has required fields. */
/** Validates that a valid FIRTrace object to firebase_perf_v1_TraceMetric conversion has required
* fields. */
- (void)testTraceMetricMessageCreationHasRequiredFields {
FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
[trace start];
[trace incrementMetric:@"c1" byInt:2];
[trace stop];
FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
XCTAssertNotNil(traceMetric);
XCTAssertTrue(traceMetric.hasName);
XCTAssertTrue(traceMetric.hasClientStartTimeUs);
XCTAssertTrue(traceMetric.hasDurationUs);
XCTAssertTrue(traceMetric.hasIsAuto);
firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
XCTAssertTrue(traceMetric.name != NULL);
XCTAssertTrue(traceMetric.has_client_start_time_us);
XCTAssertTrue(traceMetric.has_duration_us);
XCTAssertTrue(traceMetric.has_is_auto);
}
/** Validates the session details inside trace metric. */
@@ -161,21 +171,13 @@
trace.activeSessions = [@[ session1, session2 ] mutableCopy];
[trace stop];
FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
XCTAssertNotNil(traceMetric);
XCTAssertNotNil(traceMetric.perfSessionsArray);
XCTAssertTrue(traceMetric.perfSessionsArray.count >= 2);
firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
XCTAssertTrue(traceMetric.perf_sessions != NULL);
XCTAssertTrue(traceMetric.perf_sessions_count >= 2);
}
/** Validates that an invalid FIRTrace object to Proto conversion is unsuccessful. */
- (void)testTraceMetricMessageCreationForInvalidTrace {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
XCTAssertNil(FPRGetTraceMetric(nil));
#pragma clang diagnostic pop
}
/** Validates that the FPRNetworkTrace object to Proto conversion is successful. */
/** Validates that the FPRNetworkTrace object to firebase_perf_v1_NetworkRequestMetric conversion is
* successful. */
- (void)testNetworkTraceMetricMessage {
NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
@@ -193,13 +195,14 @@
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:response error:error];
FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertEqualObjects(networkMetric.URL, URL.absoluteString);
XCTAssertEqual(networkMetric.HTTPMethod, FPRMSGNetworkRequestMetric_HttpMethod_Get);
XCTAssertEqual(networkMetric.networkClientErrorReason,
FPRMSGNetworkRequestMetric_NetworkClientErrorReason_GenericClientError);
XCTAssertEqual(networkMetric.HTTPResponseCode, 404);
XCTAssertEqualObjects(networkMetric.responseContentType, @"text/json");
firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertEqualObjects(FPRDecodeString(networkMetric.url), URL.absoluteString);
XCTAssertEqual(networkMetric.http_method, firebase_perf_v1_NetworkRequestMetric_HttpMethod_GET);
XCTAssertEqual(
networkMetric.network_client_error_reason,
firebase_perf_v1_NetworkRequestMetric_NetworkClientErrorReason_GENERIC_CLIENT_ERROR);
XCTAssertEqual(networkMetric.http_response_code, 404);
XCTAssertEqualObjects(FPRDecodeString(networkMetric.response_content_type), @"text/json");
}
/** Validates that the FPRNetworkTrace object to Proto conversion has required fields for a valid
@@ -221,38 +224,31 @@
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-200 userInfo:nil];
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:response error:error];
FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertTrue(networkMetric.hasURL);
XCTAssertTrue(networkMetric.hasClientStartTimeUs);
XCTAssertTrue(networkMetric.hasHTTPMethod);
XCTAssertTrue(networkMetric.hasResponsePayloadBytes);
XCTAssertTrue(networkMetric.hasNetworkClientErrorReason);
XCTAssertTrue(networkMetric.hasHTTPResponseCode);
XCTAssertTrue(networkMetric.hasResponseContentType);
XCTAssertTrue(networkMetric.hasTimeToResponseCompletedUs);
firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertTrue(networkMetric.url != NULL);
XCTAssertTrue(networkMetric.has_client_start_time_us);
XCTAssertTrue(networkMetric.has_http_method);
XCTAssertTrue(networkMetric.has_response_payload_bytes);
XCTAssertTrue(networkMetric.has_network_client_error_reason);
XCTAssertTrue(networkMetric.has_http_response_code);
XCTAssertTrue(networkMetric.response_content_type != NULL);
XCTAssertTrue(networkMetric.has_time_to_response_completed_us);
}
/** Validates that an invalid FPRNetworkTrace object to Proto conversion is unsuccessful. */
- (void)testNetworkTraceMetricMessageCreationForInvalidTrace {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"
XCTAssertNil(FPRGetNetworkRequestMetric(nil));
#pragma clang diagnostic pop
}
/** Validates that application process state conversion to proto enum type is successful. */
/** Validates that application process state conversion to firebase_perf_v1_ApplicationProcessState
* enum type is successful. */
- (void)testApplicationProcessStateConversion {
XCTAssertEqual(FPRMSGApplicationProcessState_Background,
XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_BACKGROUND,
FPRApplicationProcessState(FPRTraceStateBackgroundOnly));
XCTAssertEqual(FPRMSGApplicationProcessState_Foreground,
XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_FOREGROUND,
FPRApplicationProcessState(FPRTraceStateForegroundOnly));
XCTAssertEqual(FPRMSGApplicationProcessState_ForegroundBackground,
XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_FOREGROUND_BACKGROUND,
FPRApplicationProcessState(FPRTraceStateBackgroundAndForeground));
XCTAssertEqual(FPRMSGApplicationProcessState_ApplicationProcessStateUnknown,
XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN,
FPRApplicationProcessState(FPRTraceStateUnknown));
// Try with some random value should say the application state is unknown.
XCTAssertEqual(FPRMSGApplicationProcessState_ApplicationProcessStateUnknown,
XCTAssertEqual(firebase_perf_v1_ApplicationProcessState_APPLICATION_PROCESS_STATE_UNKNOWN,
FPRApplicationProcessState(100));
}
@@ -263,19 +259,6 @@
}
#endif
/** Validates if network events are dropped when there is not valid response code. */
- (void)testDroppingNetworkEventsWithInvalidStatusCode {
NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
[trace start];
[trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
[trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:nil error:nil];
XCTAssertNil(FPRGetNetworkRequestMetric(trace));
}
/** Validates the session details inside trace metric. */
- (void)testNetworkRequestMetricMessageHasSessionDetails {
NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
@@ -300,10 +283,9 @@
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:response error:error];
FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertNotNil(networkMetric);
XCTAssertNotNil(networkMetric.perfSessionsArray);
XCTAssertTrue(networkMetric.perfSessionsArray.count >= 2);
firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertTrue(networkMetric.perf_sessions != NULL);
XCTAssertTrue(networkMetric.perf_sessions_count >= 2);
}
/** Validates the gauge metric proto packaging works with proper conversions. */
@@ -315,13 +297,11 @@
heapAvailable:10 * 1024];
[gauges addObject:memoryData];
FPRMSGGaugeMetric *gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
XCTAssertNotNil(gaugeMetric);
XCTAssertEqual(gaugeMetric.cpuMetricReadingsArray_Count, 0);
XCTAssertEqual(gaugeMetric.iosMemoryReadingsArray_Count, 1);
FPRMSGIosMemoryReading *memoryReading = [gaugeMetric.iosMemoryReadingsArray firstObject];
XCTAssertEqual(memoryReading.usedAppHeapMemoryKb, 5);
XCTAssertEqual(memoryReading.freeAppHeapMemoryKb, 10);
firebase_perf_v1_GaugeMetric gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
XCTAssertEqual(gaugeMetric.cpu_metric_readings_count, 0);
XCTAssertEqual(gaugeMetric.ios_memory_readings_count, 1);
XCTAssertEqual(gaugeMetric.ios_memory_readings[0].used_app_heap_memory_kb, 5);
XCTAssertEqual(gaugeMetric.ios_memory_readings[0].free_app_heap_memory_kb, 10);
}
/** Validates the gauge metric proto packaging works. */
@@ -338,20 +318,9 @@
[gauges addObject:cpuData];
[gauges addObject:memoryData];
}
FPRMSGGaugeMetric *gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
XCTAssertNotNil(gaugeMetric);
XCTAssertEqual(gaugeMetric.cpuMetricReadingsArray_Count, 5);
XCTAssertEqual(gaugeMetric.iosMemoryReadingsArray_Count, 5);
}
/** Validates the gauge metric proto packaging does not create an empty package. */
- (void)testGaugeMetricProtoPackingWithEmptyData {
NSMutableArray *gauges = [[NSMutableArray alloc] init];
FPRMSGGaugeMetric *gaugeMetric1 = FPRGetGaugeMetric(gauges, @"abc");
XCTAssertNil(gaugeMetric1);
FPRMSGGaugeMetric *gaugeMetric2 = FPRGetGaugeMetric(gauges, @"");
XCTAssertNil(gaugeMetric2);
firebase_perf_v1_GaugeMetric gaugeMetric = FPRGetGaugeMetric(gauges, @"abc");
XCTAssertEqual(gaugeMetric.cpu_metric_readings_count, 5);
XCTAssertEqual(gaugeMetric.ios_memory_readings_count, 5);
}
/** Validates if the first session is a verbose session for a trace. */
@@ -366,16 +335,14 @@
trace.activeSessions = [@[ session1, session2 ] mutableCopy];
[trace stop];
FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
XCTAssertNotNil(traceMetric);
XCTAssertNotNil(traceMetric.perfSessionsArray);
XCTAssertTrue(traceMetric.perfSessionsArray.count >= 2);
firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
XCTAssertTrue(traceMetric.perf_sessions != NULL);
XCTAssertTrue(traceMetric.perf_sessions_count >= 2);
FPRMSGPerfSession *perfSession = [traceMetric.perfSessionsArray firstObject];
GPBEnumArray *firstSessionVerbosity = perfSession.sessionVerbosityArray;
XCTAssertEqual([firstSessionVerbosity valueAtIndex:0],
FPRMSGSessionVerbosity_GaugesAndSystemEvents);
XCTAssertEqualObjects(perfSession.sessionId, @"b");
firebase_perf_v1_PerfSession perfSession = traceMetric.perf_sessions[0];
XCTAssertEqual(perfSession.session_verbosity[0],
firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS);
XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"b");
}
/** Validates the verbosity ordering when no sessions are verbose. */
@@ -390,14 +357,13 @@
trace.activeSessions = [@[ session1, session2 ] mutableCopy];
[trace stop];
FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
XCTAssertNotNil(traceMetric);
XCTAssertNotNil(traceMetric.perfSessionsArray);
XCTAssertTrue(traceMetric.perfSessionsArray.count >= 2);
firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
XCTAssertTrue(traceMetric.perf_sessions != NULL);
XCTAssertTrue(traceMetric.perf_sessions_count >= 2);
FPRMSGPerfSession *perfSession = [traceMetric.perfSessionsArray firstObject];
XCTAssertEqualObjects(perfSession.sessionId, @"a");
XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
firebase_perf_v1_PerfSession perfSession = traceMetric.perf_sessions[0];
XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
XCTAssertEqual(perfSession.session_verbosity_count, 0);
}
/** Validates if a session is not verbose, do not populate the session verbosity array. */
@@ -410,14 +376,13 @@
trace.activeSessions = [@[ session1 ] mutableCopy];
[trace stop];
FPRMSGTraceMetric *traceMetric = FPRGetTraceMetric(trace);
XCTAssertNotNil(traceMetric);
XCTAssertNotNil(traceMetric.perfSessionsArray);
XCTAssertTrue(traceMetric.perfSessionsArray.count >= 1);
firebase_perf_v1_TraceMetric traceMetric = FPRGetTraceMetric(trace);
XCTAssertTrue(traceMetric.perf_sessions != NULL);
XCTAssertTrue(traceMetric.perf_sessions_count >= 1);
FPRMSGPerfSession *perfSession = [traceMetric.perfSessionsArray firstObject];
XCTAssertEqualObjects(perfSession.sessionId, @"a");
XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
firebase_perf_v1_PerfSession perfSession = traceMetric.perf_sessions[0];
XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
XCTAssertEqual(perfSession.session_verbosity_count, 0);
}
/** Validates if the first session is a verbose session for a network trace. */
@@ -446,16 +411,14 @@
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:response error:error];
FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertNotNil(networkMetric);
XCTAssertNotNil(networkMetric.perfSessionsArray);
XCTAssertTrue(networkMetric.perfSessionsArray.count >= 2);
firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertTrue(networkMetric.perf_sessions != NULL);
XCTAssertTrue(networkMetric.perf_sessions_count >= 2);
FPRMSGPerfSession *perfSession = [networkMetric.perfSessionsArray firstObject];
GPBEnumArray *firstSessionVerbosity = perfSession.sessionVerbosityArray;
XCTAssertEqual([firstSessionVerbosity valueAtIndex:0],
FPRMSGSessionVerbosity_GaugesAndSystemEvents);
XCTAssertEqualObjects(perfSession.sessionId, @"b");
firebase_perf_v1_PerfSession perfSession = networkMetric.perf_sessions[0];
XCTAssertEqual(perfSession.session_verbosity[0],
firebase_perf_v1_SessionVerbosity_GAUGES_AND_SYSTEM_EVENTS);
XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"b");
}
/** Validates the verbosity ordering when no sessions are verbose for a network trace. */
@@ -484,14 +447,13 @@
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:response error:error];
FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertNotNil(networkMetric);
XCTAssertNotNil(networkMetric.perfSessionsArray);
XCTAssertTrue(networkMetric.perfSessionsArray.count >= 2);
firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertTrue(networkMetric.perf_sessions != NULL);
XCTAssertTrue(networkMetric.perf_sessions_count >= 2);
FPRMSGPerfSession *perfSession = [networkMetric.perfSessionsArray firstObject];
XCTAssertEqualObjects(perfSession.sessionId, @"a");
XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
firebase_perf_v1_PerfSession perfSession = networkMetric.perf_sessions[0];
XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
XCTAssertEqual(perfSession.session_verbosity_count, 0);
}
/** Validates if a session is not verbose, do not populate the session verbosity array for network
@@ -520,14 +482,13 @@
[trace didReceiveData:[NSData data]];
[trace didCompleteRequestWithResponse:response error:error];
FPRMSGNetworkRequestMetric *networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertNotNil(networkMetric);
XCTAssertNotNil(networkMetric.perfSessionsArray);
XCTAssertTrue(networkMetric.perfSessionsArray.count >= 1);
firebase_perf_v1_NetworkRequestMetric networkMetric = FPRGetNetworkRequestMetric(trace);
XCTAssertTrue(networkMetric.perf_sessions != NULL);
XCTAssertTrue(networkMetric.perf_sessions_count >= 1);
FPRMSGPerfSession *perfSession = [networkMetric.perfSessionsArray firstObject];
XCTAssertEqualObjects(perfSession.sessionId, @"a");
XCTAssertEqual(perfSession.sessionVerbosityArray_Count, 0);
firebase_perf_v1_PerfSession perfSession = networkMetric.perf_sessions[0];
XCTAssertEqualObjects(FPRDecodeString(perfSession.session_id), @"a");
XCTAssertEqual(perfSession.session_verbosity_count, 0);
}
@end
@@ -21,10 +21,11 @@
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace+Private.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Tests/Unit/Configurations/FPRFakeRemoteConfig.h"
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
#import <OCMock/OCMock.h>
@@ -311,18 +312,16 @@
* Validates that the uploaded file size correctly reflect in the NetworkTrace.
*/
- (void)testDidUploadFile {
NSString *fileName = [NSString stringWithFormat:@"%@", @"unittest_tmpfile"];
NSURL *fileURL =
[NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];
NSData *data = [@"Some random text" dataUsingEncoding:NSUTF8StringEncoding];
[data writeToURL:fileURL options:NSDataWritingAtomic error:nil];
NSBundle *bundle = [FPRTestUtils getBundle];
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
FPRNetworkTrace *trace = [[FPRNetworkTrace alloc] initWithURLRequest:self.testURLRequest];
[trace start];
[trace checkpointState:FPRNetworkTraceCheckpointStateInitiated];
[trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
[trace didUploadFileWithURL:fileURL];
XCTAssertEqual(trace.requestSize, 16);
XCTAssertEqual(trace.requestSize, 26);
XCTAssertEqual(trace.responseSize, 0);
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil];
@@ -469,6 +468,10 @@
[trace checkpointState:FPRNetworkTraceCheckpointStateResponseReceived];
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
@@ -55,6 +55,10 @@
XCTAssertNotNil(instrumentor);
}
#pragma mark - Unswizzle based tests
#ifndef SWIFT_PACKAGE
- (void)testInstanceMethodSwizzle {
NSString *expectedDescription = @"Not the description you expected!";
FPRSelectorInstrumentor *instrumentor =
@@ -325,6 +329,8 @@
}
}
#endif // SWIFT_PACKAGE
/** Tests attempting to swizzle non-existent/unimplemented method (like @dynamic) returns nil. */
- (void)testNonexistentMethodReturnsNil {
FPRSelectorInstrumentor *instrumentor =
@@ -21,8 +21,6 @@
#import <GoogleDataTransport/GoogleDataTransport.h>
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
NS_ASSUME_NONNULL_BEGIN
@interface FPRTestUtils : NSObject
@@ -30,6 +28,10 @@ NS_ASSUME_NONNULL_BEGIN
/** Default initializer. */
- (instancetype)init NS_UNAVAILABLE;
/** Provide the NSBundle instance that can to be used for testing. SPM tests will have a different
* bundle when compared to the default unit test bundle. */
+ (NSBundle *)getBundle;
/** Creates a Performance Trace object. */
+ (FIRTrace *)createRandomTraceWithName:(NSString *)name;
@@ -37,22 +39,22 @@ NS_ASSUME_NONNULL_BEGIN
+ (FIRTrace *)addVerboseSessionToTrace:(FIRTrace *)trace;
/** Creates a random Performance Metric Proto object. */
+ (FPRMSGPerfMetric *)createRandomPerfMetric:(NSString *)traceName;
+ (firebase_perf_v1_PerfMetric)createRandomPerfMetric:(NSString *)traceName;
/**
* Creates a random Performance Metric Proto object, with verbose
* session ID if it is set as verbose.
*/
+ (FPRMSGPerfMetric *)createVerboseRandomPerfMetric:(NSString *)traceName;
+ (firebase_perf_v1_PerfMetric)createVerboseRandomPerfMetric:(NSString *)traceName;
/** Creates a random internal Performance Metric Proto object. */
+ (FPRMSGPerfMetric *)createRandomInternalPerfMetric:(NSString *)traceName;
+ (firebase_perf_v1_PerfMetric)createRandomInternalPerfMetric:(NSString *)traceName;
/** Creates a random network request Performance Metric Proto object. */
+ (FPRMSGPerfMetric *)createRandomNetworkPerfMetric:(NSString *)url;
+ (firebase_perf_v1_PerfMetric)createRandomNetworkPerfMetric:(NSString *)url;
/** Creates a random gauge Performance Metric Proto object. */
+ (FPRMSGPerfMetric *)createRandomGaugePerfMetric;
+ (firebase_perf_v1_PerfMetric)createRandomGaugePerfMetric;
/** Creates a random GDTCOREvent object. */
+ (GDTCOREvent *)createRandomTraceGDTEvent:(NSString *)traceName;
+29 -21
View File
@@ -14,14 +14,14 @@
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
#import "FirebasePerformance/Sources/FPRProtoUtils.h"
#import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
#import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeData.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace+Private.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
#import "FirebasePerformance/Sources/Protogen/nanopb/perf_metric.nanopb.h"
static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
@@ -29,6 +29,14 @@ static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
#pragma mark - Test utility methods
+ (NSBundle *)getBundle {
#if SWIFT_PACKAGE
return Firebase_PerformanceUnit_SWIFTPM_MODULE_BUNDLE();
#else
return [NSBundle bundleForClass:[FPRTestUtils class]];
#endif
}
+ (FIRTrace *)createRandomTraceWithName:(NSString *)traceName {
FIRTrace *trace = [[FIRTrace alloc] initWithName:traceName];
[trace start];
@@ -47,40 +55,40 @@ static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
return trace;
}
+ (FPRMSGPerfMetric *)createRandomPerfMetric:(NSString *)traceName {
FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
+ (firebase_perf_v1_PerfMetric)createRandomPerfMetric:(NSString *)traceName {
firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
FIRTrace *trace = [FPRTestUtils createRandomTraceWithName:traceName];
// Make sure there are no sessions.
trace.activeSessions = [NSMutableArray array];
perfMetric.traceMetric = FPRGetTraceMetric(trace);
FPRSetTraceMetric(&perfMetric, FPRGetTraceMetric(trace));
return perfMetric;
}
+ (FPRMSGPerfMetric *)createVerboseRandomPerfMetric:(NSString *)traceName {
FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
+ (firebase_perf_v1_PerfMetric)createVerboseRandomPerfMetric:(NSString *)traceName {
firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
FIRTrace *trace = [FPRTestUtils createRandomTraceWithName:traceName];
trace = [FPRTestUtils addVerboseSessionToTrace:trace];
perfMetric.traceMetric = FPRGetTraceMetric(trace);
FPRSetTraceMetric(&perfMetric, FPRGetTraceMetric(trace));
return perfMetric;
}
+ (FPRMSGPerfMetric *)createRandomInternalPerfMetric:(NSString *)traceName {
FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
+ (firebase_perf_v1_PerfMetric)createRandomInternalPerfMetric:(NSString *)traceName {
firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
FIRTrace *trace = [[FIRTrace alloc] initInternalTraceWithName:traceName];
[trace start];
[trace stop];
// Make sure there are no sessions.
trace.activeSessions = [NSMutableArray array];
perfMetric.traceMetric = FPRGetTraceMetric(trace);
FPRSetTraceMetric(&perfMetric, FPRGetTraceMetric(trace));
return perfMetric;
}
+ (FPRMSGPerfMetric *)createRandomNetworkPerfMetric:(NSString *)url {
FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
+ (firebase_perf_v1_PerfMetric)createRandomNetworkPerfMetric:(NSString *)url {
firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
NSURL *URL = [NSURL URLWithString:url];
NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
@@ -97,13 +105,13 @@ static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
[networkTrace didReceiveData:[NSData data]];
[networkTrace didCompleteRequestWithResponse:response error:nil];
networkTrace.activeSessions = [NSMutableArray array];
perfMetric.networkRequestMetric = FPRGetNetworkRequestMetric(networkTrace);
FPRSetNetworkRequestMetric(&perfMetric, FPRGetNetworkRequestMetric(networkTrace));
return perfMetric;
}
+ (FPRMSGPerfMetric *)createRandomGaugePerfMetric {
FPRMSGPerfMetric *perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
+ (firebase_perf_v1_PerfMetric)createRandomGaugePerfMetric {
firebase_perf_v1_PerfMetric perfMetric = FPRGetPerfMetricMessage(@"RandomAppID");
NSMutableArray<NSObject *> *gauges = [[NSMutableArray alloc] init];
NSDate *date = [NSDate date];
@@ -112,14 +120,14 @@ static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
heapAvailable:10 * 1024];
[gauges addObject:memoryData];
FPRMSGGaugeMetric *gaugeMetric = FPRGetGaugeMetric(gauges, @"123");
perfMetric.gaugeMetric = gaugeMetric;
firebase_perf_v1_GaugeMetric gaugeMetric = FPRGetGaugeMetric(gauges, @"123");
FPRSetGaugeMetric(&perfMetric, gaugeMetric);
return perfMetric;
}
+ (GDTCOREvent *)createRandomTraceGDTEvent:(NSString *)traceName {
FPRMSGPerfMetric *perfMetric = [self createRandomPerfMetric:traceName];
firebase_perf_v1_PerfMetric perfMetric = [self createRandomPerfMetric:traceName];
NSString *mappingID = [NSString stringWithFormat:@"%ld", (long)kLogSource];
GDTCOREvent *gdtEvent = [[GDTCOREvent alloc] initWithMappingID:mappingID target:kGDTCORTargetFLL];
@@ -128,7 +136,7 @@ static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
}
+ (GDTCOREvent *)createRandomInternalTraceGDTEvent:(NSString *)traceName {
FPRMSGPerfMetric *perfMetric = [self createRandomInternalPerfMetric:traceName];
firebase_perf_v1_PerfMetric perfMetric = [self createRandomInternalPerfMetric:traceName];
NSString *mappingID = [NSString stringWithFormat:@"%ld", (long)kLogSource];
GDTCOREvent *gdtEvent = [[GDTCOREvent alloc] initWithMappingID:mappingID target:kGDTCORTargetFLL];
@@ -137,7 +145,7 @@ static NSInteger const kLogSource = 462; // LogRequest_LogSource_Fireperf
}
+ (GDTCOREvent *)createRandomNetworkGDTEvent:(NSString *)url {
FPRMSGPerfMetric *perfMetric = [self createRandomNetworkPerfMetric:url];
firebase_perf_v1_PerfMetric perfMetric = [self createRandomNetworkPerfMetric:url];
NSString *mappingID = [NSString stringWithFormat:@"%ld", (long)kLogSource];
GDTCOREvent *gdtEvent = [[GDTCOREvent alloc] initWithMappingID:mappingID target:kGDTCORTargetFLL];
@@ -17,6 +17,7 @@
#import "FirebasePerformance/Sources/FPRURLFilter.h"
#import "FirebasePerformance/Sources/FPRURLFilter_Private.h"
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
#import "FirebasePerformance/Tests/Unit/Fakes/NSBundleFake.h"
#import <GoogleDataTransport/GoogleDataTransport.h>
@@ -63,9 +64,9 @@
/** Tests shouldInstrument when the plist file is being used. */
- (void)testShouldInstrumentUsingPlist {
NSString *plistPath =
[[NSBundle bundleForClass:self.class] pathForResource:@"FPRURLFilterTests-Info"
ofType:@"plist"];
NSBundle *bundle = [FPRTestUtils getBundle];
NSString *plistPath = [bundle pathForResource:@"FPRURLFilterTests-Info" ofType:@"plist"];
NSDictionary *plistContent = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSBundleFake *mainBundle = [[NSBundleFake alloc] init];
@@ -38,7 +38,7 @@
self.logGaugeMetricCalledTimes++;
}
- (void)processAndLogEvent:(FPRMSGPerfMetric *)event {
- (void)processAndLogEvent:(firebase_perf_v1_PerfMetric)event {
self.processAndLogEventCalledTimes++;
}
@@ -20,7 +20,7 @@
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags.h"
#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager+Private.h"
#import "FirebasePerformance/Sources/Gauges/FPRGaugeManager.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Gauges/CPU/FPRCPUGaugeCollector+Private.h"
@@ -20,10 +20,9 @@
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags+Private.h"
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags.h"
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Public/FIRHTTPMetric.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRHTTPMetric.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/FPRProtoUtils.h"
#import "FirebasePerformance/Sources/Instrumentation/FIRHTTPMetric+Private.h"
#import "FirebasePerformance/Tests/Unit/Configurations/FPRFakeRemoteConfig.h"
@@ -166,7 +165,6 @@
[metric markResponseStart];
[metric stop];
FPRNetworkTrace *networkTrace = metric.networkTrace;
XCTAssertNotNil(FPRGetNetworkRequestMetric(networkTrace));
XCTAssertEqualObjects(networkTrace.URLRequest.URL, self.sampleURL);
XCTAssertEqual(networkTrace.requestSize, 100);
XCTAssertEqual(networkTrace.responseSize, 300);
@@ -174,7 +172,7 @@
XCTAssertEqualObjects(networkTrace.responseContentType, @"text/json");
}
/** Validate if the metric creation fails if the response code is not set. */
/** Validate if the network trace is invalid if the response code is not set. */
- (void)testMetricCreationFailsWhenResponseCodeNotSet {
id mock = [OCMockObject partialMockForObject:[FPRClient sharedInstance]];
OCMStub([mock logNetworkTrace:[OCMArg any]]).andDo(nil);
@@ -187,7 +185,7 @@
[metric markResponseStart];
[metric stop];
FPRNetworkTrace *networkTrace = metric.networkTrace;
XCTAssertNil(FPRGetNetworkRequestMetric(networkTrace));
XCTAssertFalse([networkTrace isValid]);
}
/** Validates that starting and stopping logs an event. */
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma mark - Unswizzle based tests
#if !SWIFT_PACKAGE
#import "FirebasePerformance/Tests/Unit/Instruments/FPRNSURLConnectionInstrumentTestDelegates.h"
#import <XCTest/XCTest.h>
@@ -20,9 +24,10 @@
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNSURLConnectionInstrument.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
#import "FirebasePerformance/Tests/Unit/Server/FPRHermeticTestServer.h"
@interface FPRNSURLConnectionInstrumentTest : FPRTestCase
@@ -137,7 +142,7 @@
XCTAssertNotNil(connection);
[connection start];
// Only let it check for a connection for a half second.
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
XCTAssertTrue(delegate.connectionDidFailWithErrorCalled);
[self.testServer start];
[instrument deregisterInstrumentors];
@@ -157,7 +162,7 @@
XCTAssertNotNil(connection);
[connection start];
// Only let it check for a connection for a half second.
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
XCTAssertTrue(delegate.connectionDidFailWithErrorCalled);
[self.testServer start];
[instrument deregisterInstrumentors];
@@ -196,7 +201,7 @@
XCTAssertNotNil(connection);
[connection start];
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:connection]);
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
XCTAssertTrue(delegate.connectionDidFailWithErrorCalled);
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:connection]);
[self.testServer start];
@@ -356,8 +361,9 @@
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = @"POST";
NSURL *fileURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"smallDownloadFile"
withExtension:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
request.HTTPBody = [NSData dataWithContentsOfURL:fileURL];
FPRNSURLConnectionCompleteTestDelegate *delegate =
[[FPRNSURLConnectionCompleteTestDelegate alloc] init];
@@ -513,3 +519,5 @@
}
@end
#endif // SWIFT_PACKAGE
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma mark - Unswizzle based tests
#ifndef SWIFT_PACKAGE
#import "FirebasePerformance/Tests/Unit/Instruments/FPRNSURLSessionInstrumentTestDelegates.h"
#import <XCTest/XCTest.h>
@@ -22,9 +26,10 @@
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNSURLSessionInstrument.h"
#import "FirebasePerformance/Sources/Instrumentation/Network/FPRNSURLSessionInstrument_Private.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
#import "FirebasePerformance/Tests/Unit/Server/FPRHermeticTestServer.h"
/** This class is used to wrap an NSURLSession object during testing. */
@@ -381,8 +386,9 @@
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = @"POST";
NSURL *fileURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"smallDownloadFile"
withExtension:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileURL];
[uploadTask resume];
@@ -490,7 +496,7 @@
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testBigDownload"];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:URL];
[downloadTask resume];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:downloadTask]);
XCTAssertTrue(delegate.URLSessionDownloadTaskDidResumeAtOffsetExpectedTotalBytesCalled);
[instrument deregisterInstrumentors];
@@ -607,8 +613,9 @@
NSURLSession *session = [NSURLSession sharedSession];
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *fileURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"smallDownloadFile"
withExtension:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileURL];
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
XCTAssertNotNil(uploadTask);
@@ -623,8 +630,9 @@
NSURLSession *session = [NSURLSession sharedSession];
NSURL *URL = [self.testServer.serverURL URLByAppendingPathComponent:@"testUpload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *fileURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"smallDownloadFile"
withExtension:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
XCTestExpectation *expectation = [self expectationWithDescription:@"completionHandler called"];
void (^completionHandler)(NSData *_Nullable, NSURLResponse *_Nullable, NSError *_Nullable) =
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
@@ -788,8 +796,8 @@
XCTAssertNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
}];
NSURL *fileURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"smallDownloadFile"
withExtension:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSURL *fileURL = [bundle URLForResource:@"smallDownloadFile" withExtension:@""];
uploadTask = [session uploadTaskWithRequest:URLRequest fromFile:fileURL];
[uploadTask resume];
XCTAssertNotNil([FPRNetworkTrace networkTraceFromObject:uploadTask]);
@@ -802,3 +810,5 @@
}
@end
#endif // SWIFT_PACKAGE
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma mark - Unswizzle based tests
#if !SWIFT_PACKAGE
#import "FirebasePerformance/Sources/Instrumentation/UIKit/FPRUIViewControllerInstrument.h"
#import <XCTest/XCTest.h>
@@ -19,7 +23,7 @@
#import <OCMock/OCMock.h>
#import "FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker+Private.h"
#import "FirebasePerformance/Sources/AppActivity/FPRScreenTraceTracker.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import <GoogleUtilities/GULSwizzler.h>
@@ -168,3 +172,5 @@ static BOOL originalViewDidDisappearInvoked = NO;
}
@end
#endif // SWIFT_PACKAGE
@@ -18,8 +18,6 @@
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
@interface FPRGDTEventTest : XCTestCase
@end
@@ -28,7 +26,7 @@
/** Tests the designated initializer. */
- (void)testInstanceCreation {
FPRMSGPerfMetric *metric = [FPRMSGPerfMetric message];
firebase_perf_v1_PerfMetric metric = firebase_perf_v1_PerfMetric_init_default;
FPRGDTEvent *event = [FPRGDTEvent gdtEventForPerfMetric:metric];
XCTAssertNotNil(event);
@@ -36,7 +34,7 @@
/** Validate that the instance has transportBytes for default Perf Metric. */
- (void)testInstanceHasTransportBytesForDefaultPerfMetric {
FPRMSGPerfMetric *metric = [FPRMSGPerfMetric message];
firebase_perf_v1_PerfMetric metric = firebase_perf_v1_PerfMetric_init_default;
FPRGDTEvent *event = [FPRGDTEvent gdtEventForPerfMetric:metric];
XCTAssertTrue([event transportBytes] > 0);
@@ -44,7 +42,7 @@
/** Validate that the instance has transportBytes for valid Perf Metric. */
- (void)testInstanceHasTransportBytesForValidPerfMetric {
FPRMSGPerfMetric *metric = [FPRTestUtils createRandomPerfMetric:@"t1"];
firebase_perf_v1_PerfMetric metric = [FPRTestUtils createRandomPerfMetric:@"t1"];
FPRGDTEvent *event = [FPRGDTEvent gdtEventForPerfMetric:metric];
XCTAssertTrue([event transportBytes] > 0);
@@ -18,11 +18,11 @@
#import "FirebasePerformance/Sources/Loggers/FPRGDTLogSampler.h"
#import "FirebasePerformance/Sources/Configurations/FPRConfigurations+Private.h"
#import "FirebasePerformance/Sources/FPRProtoUtils.h"
#import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace+Private.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTEvent.h"
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
@@ -73,7 +73,7 @@
target:kGDTCORTargetFLL];
// Generates sample trace metric.
FPRMSGPerfMetric *tracePerfMetric = [FPRTestUtils createRandomPerfMetric:@"Random"];
firebase_perf_v1_PerfMetric tracePerfMetric = [FPRTestUtils createRandomPerfMetric:@"Random"];
self.transportTraceEvent = [self.gdtfllTransport eventForTransport];
self.transportTraceEvent.qosTier = GDTCOREventQosDefault;
@@ -81,7 +81,7 @@
// Generates sample network trace metric.
NSString *randomAppID = @"RandomID";
FPRMSGPerfMetric *networkTraceMetric = FPRGetPerfMetricMessage(randomAppID);
firebase_perf_v1_PerfMetric networkTraceMetric = FPRGetPerfMetricMessage(randomAppID);
NSURL *URL = [NSURL URLWithString:@"https://abc.xyz"];
NSURLRequest *URLRequest = [NSURLRequest requestWithURL:URL];
FPRNetworkTrace *networkTrace = [[FPRNetworkTrace alloc] initWithURLRequest:URLRequest];
@@ -98,7 +98,7 @@
[networkTrace didCompleteRequestWithResponse:response error:nil];
// Make sure there are no sessions as they will not be sampled.
networkTrace.activeSessions = [NSMutableArray array];
networkTraceMetric.networkRequestMetric = FPRGetNetworkRequestMetric(networkTrace);
FPRSetNetworkRequestMetric(&networkTraceMetric, FPRGetNetworkRequestMetric(networkTrace));
self.transportNetworkEvent = [self.gdtfllTransport eventForTransport];
self.transportNetworkEvent.qosTier = GDTCOREventQosDefault;
@@ -190,7 +190,7 @@
[self.fakeConfigs setTraceSamplingRate:0.0];
// Trace is verbose.
FPRMSGPerfMetric *traceMetric = [FPRTestUtils createVerboseRandomPerfMetric:@"Random"];
firebase_perf_v1_PerfMetric traceMetric = [FPRTestUtils createVerboseRandomPerfMetric:@"Random"];
GDTCOREvent *traceEvent = [self.gdtfllTransport eventForTransport];
traceEvent.qosTier = GDTCOREventQosDefault;
@@ -205,7 +205,7 @@
[self.fakeConfigs setTraceSamplingRate:0.0];
// Trace is non-verbose.
FPRMSGPerfMetric *tracePerfMetric = [FPRTestUtils createRandomPerfMetric:@"random"];
firebase_perf_v1_PerfMetric tracePerfMetric = [FPRTestUtils createRandomPerfMetric:@"random"];
GDTCOREvent *traceEvent = [self.gdtfllTransport eventForTransport];
traceEvent.qosTier = GDTCOREventQosDefault;
@@ -221,7 +221,7 @@
[self.fakeConfigs setNetworkSamplingRate:0.0];
// Network request is verbose.
FPRMSGPerfMetric *networkMetric = FPRGetPerfMetricMessage(@"RandomID");
firebase_perf_v1_PerfMetric networkMetric = FPRGetPerfMetricMessage(@"RandomID");
NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
NSURLRequest *testURLRequest = [NSURLRequest requestWithURL:URL];
FPRNetworkTrace *networkTrace = [[FPRNetworkTrace alloc] initWithURLRequest:testURLRequest];
@@ -234,7 +234,7 @@
FPRSessionDetails *details =
[[FPRSessionDetails alloc] initWithSessionId:@"random" options:FPRSessionOptionsGauges];
networkTrace.activeSessions = [[NSMutableArray alloc] initWithObjects:details, nil];
networkMetric.networkRequestMetric = FPRGetNetworkRequestMetric(networkTrace);
FPRSetNetworkRequestMetric(&networkMetric, FPRGetNetworkRequestMetric(networkTrace));
GDTCOREvent *networkEvent = [self.gdtfllTransport eventForTransport];
networkEvent.qosTier = GDTCOREventQosDefault;
@@ -249,7 +249,7 @@
[self.fakeConfigs setNetworkSamplingRate:0.0];
// Network request is not verbose.
FPRMSGPerfMetric *networkMetric = FPRGetPerfMetricMessage(@"RandomID");
firebase_perf_v1_PerfMetric networkMetric = FPRGetPerfMetricMessage(@"RandomID");
NSURL *URL = [NSURL URLWithString:@"https://abc.com"];
NSURLRequest *testURLRequest = [NSURLRequest requestWithURL:URL];
FPRNetworkTrace *networkTrace = [[FPRNetworkTrace alloc] initWithURLRequest:testURLRequest];
@@ -261,7 +261,7 @@
[networkTrace didCompleteRequestWithResponse:response error:nil];
// Make sure the session information is empty.
networkTrace.activeSessions = [NSMutableArray array];
networkMetric.networkRequestMetric = FPRGetNetworkRequestMetric(networkTrace);
FPRSetNetworkRequestMetric(&networkMetric, FPRGetNetworkRequestMetric(networkTrace));
GDTCOREvent *networkEvent = [self.gdtfllTransport eventForTransport];
networkEvent.qosTier = GDTCOREventQosDefault;
@@ -14,6 +14,7 @@
#import <XCTest/XCTest.h>
#import "FirebasePerformance/Sources/FPRNanoPbUtils.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTLogSampler.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTLogger.h"
#import "FirebasePerformance/Sources/Loggers/FPRGDTLogger_Private.h"
@@ -23,9 +24,7 @@
#import <GoogleDataTransport/GoogleDataTransport.h>
#import "GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransport_Private.h"
#import "GoogleDataTransport/GDTCORTests/Common/Fakes/GDTCORTransportFake.h"
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
#import "SharedTestUtilities/GDTCORTransportFake.h"
@interface FPRGDTLoggerTest : XCTestCase
@@ -97,8 +96,8 @@
/** Validate all the required fields are set when logging an Event. */
- (void)testValidateEventFieldsToBeLogged {
// Log the event.
FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:@"t1"];
event.applicationInfo.appInstanceId = @"abc";
firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:@"t1"];
event.application_info.app_instance_id = FPREncodeString(@"abc");
[self.logger logEvent:event];
// Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
@@ -126,8 +125,8 @@
int logCount = 3;
for (int i = 1; i <= logCount; i++) {
NSString *traceName = [NSString stringWithFormat:@"t%d", i];
FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:traceName];
event.applicationInfo.appInstanceId = @"abc";
firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:traceName];
event.application_info.app_instance_id = FPREncodeString(@"abc");
[self.logger logEvent:event];
}
@@ -155,8 +154,8 @@
self.logger.isSimulator = YES;
// Log the event.
FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:@"t1"];
event.applicationInfo.appInstanceId = @"abc";
firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:@"t1"];
event.application_info.app_instance_id = FPREncodeString(@"abc");
[self.logger logEvent:event];
// Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
@@ -175,8 +174,8 @@
self.logger.isSimulator = NO;
// Log the event.
FPRMSGPerfMetric *event = [FPRTestUtils createRandomPerfMetric:@"t1"];
event.applicationInfo.appInstanceId = @"abc";
firebase_perf_v1_PerfMetric event = [FPRTestUtils createRandomPerfMetric:@"t1"];
event.application_info.app_instance_id = FPREncodeString(@"abc");
[self.logger logEvent:event];
// Note: Refer "dispatch_async issue" in "testLogMultipleEvents".
@@ -19,10 +19,9 @@
#import "FirebasePerformance/Sources/Loggers/FPRGDTRateLimiter.h"
#import "FirebasePerformance/Sources/AppActivity/FPRAppActivityTracker.h"
#import "FirebasePerformance/Sources/FPRProtoUtils.h"
#import "FirebasePerformance/Sources/Instrumentation/FPRNetworkTrace.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Tests/Unit/Common/FPRFakeDate.h"
#import "FirebasePerformance/Tests/Unit/FPRTestCase.h"
@@ -30,8 +29,6 @@
#import <GoogleDataTransport/GoogleDataTransport.h>
#import "FirebasePerformance/ProtoSupport/PerfMetric.pbobjc.h"
@interface FPRGDTRateLimiterTest : FPRTestCase
@end
@@ -1,11 +0,0 @@
objc_library(
name = "testserver",
srcs = glob(["**/*.m"]),
hdrs = glob(["**/*.h"]),
data = [
"bigDownloadFile",
"smallDownloadFile",
],
visibility = ["//visibility:public"],
deps = ["//third_party/objective_c/GCDWebServer"],
)
@@ -14,9 +14,15 @@
#import <Foundation/Foundation.h>
#if SWIFT_PACKAGE
#import "GCDWebServer.h"
#import "GCDWebServerDataResponse.h"
#import "GCDWebServerFileResponse.h"
#else
#import <GCDWebServer/GCDWebServer.h>
#import <GCDWebServer/GCDWebServerDataResponse.h>
#import <GCDWebServer/GCDWebServerFileResponse.h>
#endif
NS_ASSUME_NONNULL_BEGIN
@@ -13,6 +13,7 @@
// limitations under the License.
#import "FirebasePerformance/Tests/Unit/Server/FPRHermeticTestServer.h"
#import "FirebasePerformance/Tests/Unit/FPRTestUtils.h"
@interface FPRHermeticTestServer ()
@@ -131,8 +132,8 @@
/** Registers the "/testDownload" path, which responds with a small amount of data. */
- (void)registerPathTestDownload {
NSString *filePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"smallDownloadFile"
ofType:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSString *filePath = [bundle pathForResource:@"smallDownloadFile" ofType:@""];
id processBlock = ^GCDWebServerResponse *(__kindof GCDWebServerRequest *request) {
GCDWebServerFileResponse *response = [[GCDWebServerFileResponse alloc] initWithFile:filePath];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC),
@@ -151,8 +152,8 @@
/** Registers the "/testBigDownload" path, which responds with a larger amount of data. */
- (void)registerPathTestBigDownload {
NSString *filePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"bigDownloadFile"
ofType:@""];
NSBundle *bundle = [FPRTestUtils getBundle];
NSString *filePath = [bundle pathForResource:@"bigDownloadFile" ofType:@""];
id processBlock = ^GCDWebServerResponse *(__kindof GCDWebServerRequest *request) {
GCDWebServerFileResponse *response = [[GCDWebServerFileResponse alloc] initWithFile:filePath];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC),
@@ -21,8 +21,8 @@
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags+Private.h"
#import "FirebasePerformance/Sources/Configurations/FPRRemoteConfigFlags.h"
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FIRTrace.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRTrace.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
#import "FirebasePerformance/Sources/Timer/FIRTrace+Private.h"
@@ -494,6 +494,8 @@
/** Validates if the metric is incremented if a trace is started but not stopped. */
- (void)testTraceStartedNotStoppedIncrementsAMetric {
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
object:[UIApplication sharedApplication]];
FIRTrace *activeTrace = [FPRAppActivityTracker sharedInstance].activeTrace;
@@ -735,6 +737,10 @@
FIRTrace *trace = [[FIRTrace alloc] initWithName:@"Random"];
[trace start];
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter postNotificationName:UIWindowDidBecomeVisibleNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification
object:[UIApplication sharedApplication]];
[defaultCenter postNotificationName:UIApplicationWillEnterForegroundNotification
object:[UIApplication sharedApplication]];
@@ -16,7 +16,7 @@
#import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
#import "FirebasePerformance/Sources/FPRClient.h"
#import "FirebasePerformance/Sources/Public/FIRPerformance.h"
#import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
#import "FirebasePerformance/Sources/Timer/FPRCounterList.h"
@interface FPRCounterListTest : XCTestCase
+66
View File
@@ -116,6 +116,10 @@ let package = Package(
name: "FirebaseMLModelDownloader",
targets: ["FirebaseMLModelDownloader"]
),
.library(
name: "FirebasePerformance",
targets: ["FirebasePerformanceTarget"]
),
.library(
name: "FirebaseRemoteConfig",
targets: ["FirebaseRemoteConfig"]
@@ -187,6 +191,11 @@ let package = Package(
url: "https://github.com/firebase/leveldb.git",
"1.22.2" ..< "1.23.0"
),
.package(
name: "GCDWebServer",
url: "https://github.com/SlaunchaMan/GCDWebServer.git",
.revision("935e2736044e71e5341663c3cc9a335ba6867a2b")
),
// Branches need a force update with a run with the revision set like below.
// .package(url: "https://github.com/paulb777/nanopb.git", .revision("564392bd87bd093c308a3aaed3997466efb95f74"))
],
@@ -820,6 +829,59 @@ let package = Package(
]
),
.target(
name: "FirebasePerformanceTarget",
dependencies: [.target(name: "FirebasePerformance",
condition: .when(platforms: [.iOS, .tvOS]))],
path: "SwiftPM-PlatformExclude/FirebasePerformanceWrap"
),
.target(
name: "FirebasePerformance",
dependencies: [
"FirebaseCore",
"FirebaseInstallations",
"FirebaseRemoteConfig",
.product(name: "GoogleDataTransport", package: "GoogleDataTransport"),
.product(name: "GULEnvironment", package: "GoogleUtilities"),
.product(name: "GULISASwizzler", package: "GoogleUtilities"),
.product(name: "GULMethodSwizzler", package: "GoogleUtilities"),
.product(name: "GULUserDefaults", package: "GoogleUtilities"),
.product(name: "nanopb", package: "nanopb"),
],
path: "FirebasePerformance/Sources",
publicHeadersPath: "Public",
cSettings: [
.headerSearchPath("../../"),
.define("PB_FIELD_32BIT", to: "1"),
.define("PB_NO_PACKED_STRUCTS", to: "1"),
.define("PB_ENABLE_MALLOC", to: "1"),
.define("FIRPerformance_LIB_VERSION", to: firebaseVersion),
],
linkerSettings: [
.linkedFramework("SystemConfiguration", .when(platforms: [.iOS, .tvOS])),
.linkedFramework("MobileCoreServices", .when(platforms: [.iOS, .tvOS])),
.linkedFramework("QuartzCore", .when(platforms: [.iOS, .tvOS])),
]
),
.testTarget(
name: "PerformanceUnit",
dependencies: [
"FirebasePerformanceTarget",
"OCMock",
"SharedTestUtilities",
"GCDWebServer",
],
path: "FirebasePerformance/Tests/Unit",
resources: [
.process("FPRURLFilterTests-Info.plist"),
.process("Server/smallDownloadFile"),
.process("Server/bigDownloadFile"),
],
cSettings: [
.headerSearchPath("../../.."),
]
),
.target(
name: "SharedTestUtilities",
dependencies: ["FirebaseCore", "OCMock"],
@@ -916,6 +978,8 @@ let package = Package(
condition: .when(platforms: [.iOS, .tvOS])),
"FirebaseInstallations",
"FirebaseMessaging",
.target(name: "FirebasePerformance",
condition: .when(platforms: [.iOS, .tvOS])),
"FirebaseRemoteConfig",
"FirebaseStorage",
"FirebaseStorageSwift",
@@ -950,6 +1014,8 @@ let package = Package(
"FirebaseInAppMessaging",
"FirebaseInstallations",
"FirebaseMessaging",
.target(name: "FirebasePerformance",
condition: .when(platforms: [.iOS, .tvOS])),
"FirebaseRemoteConfig",
"FirebaseStorage",
],
@@ -14,7 +14,7 @@
* limitations under the License.
*/
#import "GoogleDataTransport/GDTCORTests/Common/Fakes/GDTCORTransportFake.h"
#import "SharedTestUtilities/GDTCORTransportFake.h"
@interface GDTCORTransportFake ()
@@ -0,0 +1,21 @@
// Copyright 2021 Google LLC
//
// 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 <TargetConditionals.h>
#if TARGET_OS_WATCH
#warning "Firebase Performance does not support watchOS"
#endif
#if TARGET_OS_OSX
#warning "Firebase Performance does not support macOS"
#endif
@@ -0,0 +1,21 @@
// Copyright 2021 Google LLC
//
// 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 <TargetConditionals.h>
#if TARGET_OS_WATCH
#warning "Firebase Performance does not support watchOS"
#endif
#if TARGET_OS_OSX
#warning "Firebase Performance does not support macOS"
#endif
@@ -30,6 +30,9 @@
#endif
#import "FirebaseInstallations/FirebaseInstallations.h"
#import "FirebaseMessaging/FirebaseMessaging.h"
#if (TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || TARGET_OS_TVOS
#import "FirebasePerformance/FirebasePerformance.h"
#endif
#import "FirebaseRemoteConfig/FirebaseRemoteConfig.h"
#import "FirebaseStorage/FirebaseStorage.h"
@@ -51,5 +54,8 @@
#endif
#import <FirebaseInstallations/FirebaseInstallations.h>
#import <FirebaseMessaging/FirebaseMessaging.h>
#if (TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || TARGET_OS_TVOS
#import <FirebasePerformance/FirebasePerformance.h>
#endif
#import <FirebaseRemoteConfig/FirebaseRemoteConfig.h>
#import <FirebaseStorage/FirebaseStorage.h>
@@ -30,5 +30,8 @@
#endif
@import FirebaseInstallations;
@import FirebaseMessaging;
#if (TARGET_OS_IOS && !TARGET_OS_MACCATALYST) || TARGET_OS_TVOS
@import FirebasePerformance;
#endif
@import FirebaseRemoteConfig;
@import FirebaseStorage;
+3
View File
@@ -34,6 +34,9 @@ import FirebaseFunctions
#endif
import FirebaseInstallations
import FirebaseMessaging
#if (os(iOS) && !targetEnvironment(macCatalyst)) || os(tvOS)
import FirebasePerformance
#endif
import FirebaseRemoteConfig
import FirebaseStorage
import FirebaseStorageSwift
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "PerformanceUnit"
BuildableName = "PerformanceUnit"
BlueprintName = "PerformanceUnit"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "PerformanceUnit"
BuildableName = "PerformanceUnit"
BlueprintName = "PerformanceUnit"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>