FPRDiagnostics.m 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import "FirebasePerformance/Sources/Common/FPRDiagnostics.h"
  15. #import "FirebasePerformance/Sources/Common/FPRDiagnostics_Private.h"
  16. #import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
  17. void __FPRAssert(id object, BOOL condition, const char *func) {
  18. static BOOL diagnosticsEnabled = NO;
  19. static dispatch_once_t onceToken;
  20. NSDictionary<NSString *, NSString *> *environment = [NSProcessInfo processInfo].environment;
  21. // Enable diagnostics when in test environment
  22. if (environment[@"XCTestConfigurationFilePath"] != nil) {
  23. diagnosticsEnabled = [FPRDiagnostics isEnabled];
  24. } else {
  25. dispatch_once(&onceToken, ^{
  26. diagnosticsEnabled = [FPRDiagnostics isEnabled];
  27. });
  28. }
  29. if (__builtin_expect(!condition && diagnosticsEnabled, NO)) {
  30. FPRLogError(kFPRDiagnosticFailure, @"Failure in %s, information follows:", func);
  31. FPRLogNotice(kFPRDiagnosticLog, @"Stack for failure in %s:\n%@", func,
  32. [NSThread callStackSymbols]);
  33. if ([[object class] respondsToSelector:@selector(emitDiagnostics)]) {
  34. [[object class] performSelector:@selector(emitDiagnostics) withObject:nil];
  35. }
  36. if ([object respondsToSelector:@selector(emitDiagnostics)]) {
  37. [object performSelector:@selector(emitDiagnostics) withObject:nil];
  38. }
  39. FPRLogNotice(kFPRDiagnosticLog, @"End of diagnostics for %s failure.", func);
  40. }
  41. }
  42. @implementation FPRDiagnostics
  43. static FPRConfigurations *_configuration;
  44. + (void)initialize {
  45. _configuration = [FPRConfigurations sharedInstance];
  46. }
  47. + (FPRConfigurations *)configuration {
  48. return _configuration;
  49. }
  50. + (void)setConfiguration:(FPRConfigurations *)config {
  51. _configuration = config;
  52. }
  53. + (BOOL)isEnabled {
  54. // Check a soft-linked FIRCore class to see if this is running in the app store.
  55. Class FIRAppEnvironmentUtil = NSClassFromString(@"FIRAppEnvironmentUtil");
  56. SEL isFromAppStore = NSSelectorFromString(@"isFromAppStore");
  57. #pragma clang diagnostic push
  58. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  59. if (FIRAppEnvironmentUtil && [FIRAppEnvironmentUtil respondsToSelector:isFromAppStore] &&
  60. [FIRAppEnvironmentUtil performSelector:isFromAppStore]) {
  61. return NO;
  62. }
  63. #pragma clang diagnostic pop
  64. BOOL enabled = [FPRDiagnostics.configuration diagnosticsEnabled];
  65. if (enabled) {
  66. static dispatch_once_t onceToken;
  67. dispatch_once(&onceToken, ^{
  68. FPRLogNotice(kFPRDiagnosticInfo, @"Firebase Performance Diagnostics have been enabled!");
  69. });
  70. }
  71. return enabled;
  72. }
  73. @end