Forráskód Böngészése

Add support for CCT EventCode field (#5767)

* Add support for eventCode property to GDTCCTEvent

* Add support for eventCode property to GDTCCTEvent

* Add support for eventCode property to GDTCCTEvent

* Format Code

* resolve the first round of comments

* address last round of comments

* Make GDTCOREvent+GDTCCTSupport a public category so EventCode can be set by developers

Co-authored-by: Juan Jose Lopez Jaimez <jjlopezjaimez@google.com>
Juan José López Jaimez 5 éve
szülő
commit
3127b8cce1

+ 1 - 0
GoogleDataTransportCCTSupport.podspec

@@ -30,6 +30,7 @@ Support library to provide event prioritization and uploading for the GoogleData
 
   s.source_files = 'GoogleDataTransportCCTSupport/GDTCCTLibrary/**/*'
   s.private_header_files = 'GoogleDataTransportCCTSupport/GDTCCTLibrary/Private/*.h'
+  s.public_header_files = 'GoogleDataTransportCCTSupport/GDTCCTLibrary/Public/*.h'
   s.ios.frameworks = 'SystemConfiguration', 'CoreTelephony'
   s.osx.frameworks = 'SystemConfiguration', 'CoreTelephony'
   s.tvos.frameworks = 'SystemConfiguration'

+ 6 - 1
GoogleDataTransportCCTSupport/GDTCCTLibrary/GDTCCTNanopbHelpers.m

@@ -31,7 +31,7 @@
 #import <nanopb/pb_decode.h>
 #import <nanopb/pb_encode.h>
 
-#import "GDTCCTLibrary/Private/GDTCOREvent+NetworkConnectionInfo.h"
+#import "GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h"
 
 #pragma mark - General purpose encoders
 
@@ -145,6 +145,11 @@ gdt_cct_LogEvent GDTCCTConstructLogEvent(GDTCOREvent *event) {
                                    length:networkConnectionInfoData.length];
       logEvent.has_network_connection_info = 1;
     }
+    NSNumber *eventCode = event.eventCode;
+    if (eventCode != nil) {
+      logEvent.has_event_code = 1;
+      logEvent.event_code = [eventCode intValue];
+    }
   }
   NSError *error;
   NSData *extensionBytes;

+ 1 - 1
GoogleDataTransportCCTSupport/GDTCCTLibrary/GDTCCTPrioritizer.m

@@ -23,7 +23,7 @@
 #import <GoogleDataTransport/GDTCORTargets.h>
 
 #import "GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h"
-#import "GDTCCTLibrary/Private/GDTCOREvent+NetworkConnectionInfo.h"
+#import "GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h"
 
 const static int64_t kMillisPerDay = 8.64e+7;
 

+ 236 - 0
GoogleDataTransportCCTSupport/GDTCCTLibrary/GDTCOREvent+GDTCCTSupport.m

@@ -0,0 +1,236 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#import "GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h"
+
+#import <GoogleDataTransport/GDTCORConsoleLogger.h>
+
+NSString *const GDTCCTNeedsNetworkConnectionInfo = @"needs_network_connection_info";
+
+NSString *const GDTCCTNetworkConnectionInfo = @"network_connection_info";
+
+NSString *const GDTCCTEventCodeInfo = @"event_code_info";
+
+@implementation GDTCOREvent (GDTCCTSupport)
+
+- (void)setNeedsNetworkConnectionInfoPopulated:(BOOL)needsNetworkConnectionInfoPopulated {
+  if (!needsNetworkConnectionInfoPopulated) {
+    if (!self.customBytes) {
+      return;
+    }
+
+    // Make sure we don't destroy the eventCode data, if any is present.
+    @try {
+      NSError *error;
+      NSMutableDictionary *bytesDict =
+          [[NSJSONSerialization JSONObjectWithData:self.customBytes options:0
+                                             error:&error] mutableCopy];
+      if (error) {
+        GDTCORLogDebug(@"Error when setting an event's event_code: %@", error);
+        return;
+      }
+      NSNumber *eventCode = bytesDict[GDTCCTEventCodeInfo];
+      if (eventCode != nil) {
+        self.customBytes =
+            [NSJSONSerialization dataWithJSONObject:@{GDTCCTEventCodeInfo : eventCode}
+                                            options:0
+                                              error:&error];
+      }
+    } @catch (NSException *exception) {
+      GDTCORLogDebug(@"Error when setting the event for needs_network_connection_info: %@",
+                     exception);
+    }
+  } else {
+    @try {
+      NSError *error;
+      NSMutableDictionary *bytesDict;
+      if (self.customBytes) {
+        bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes
+                                                     options:0
+                                                       error:&error] mutableCopy];
+        if (error) {
+          GDTCORLogDebug(@"Error when setting an even'ts event_code: %@", error);
+          return;
+        }
+      } else {
+        bytesDict = [[NSMutableDictionary alloc] init];
+      }
+      [bytesDict setObject:@YES forKey:GDTCCTNeedsNetworkConnectionInfo];
+      self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];
+    } @catch (NSException *exception) {
+      GDTCORLogDebug(@"Error when setting the event for needs_network_connection_info: %@",
+                     exception);
+    }
+  }
+}
+
+- (BOOL)needsNetworkConnectionInfoPopulated {
+  if (self.customBytes) {
+    @try {
+      NSError *error;
+      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes
+                                                                options:0
+                                                                  error:&error];
+      return bytesDict && !error && [bytesDict[GDTCCTNeedsNetworkConnectionInfo] boolValue];
+    } @catch (NSException *exception) {
+      GDTCORLogDebug(@"Error when checking the event for needs_network_connection_info: %@",
+                     exception);
+    }
+  }
+  return NO;
+}
+
+- (void)setNetworkConnectionInfoData:(NSData *)networkConnectionInfoData {
+  @try {
+    NSError *error;
+    NSString *dataString = [networkConnectionInfoData base64EncodedStringWithOptions:0];
+    if (dataString != nil) {
+      NSMutableDictionary *bytesDict;
+      if (self.customBytes) {
+        bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes
+                                                     options:0
+                                                       error:&error] mutableCopy];
+        if (error) {
+          GDTCORLogDebug(@"Error when setting an even'ts event_code: %@", error);
+          return;
+        }
+      } else {
+        bytesDict = [[NSMutableDictionary alloc] init];
+      }
+      [bytesDict setObject:dataString forKey:GDTCCTNetworkConnectionInfo];
+      self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];
+      if (error) {
+        self.customBytes = nil;
+        GDTCORLogDebug(@"Error when setting an event's network_connection_info: %@", error);
+      }
+    }
+  } @catch (NSException *exception) {
+    GDTCORLogDebug(@"Error when setting an event's network_connection_info: %@", exception);
+  }
+}
+
+- (nullable NSData *)networkConnectionInfoData {
+  if (self.customBytes) {
+    @try {
+      NSError *error;
+      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes
+                                                                options:0
+                                                                  error:&error];
+      NSString *base64Data = bytesDict[GDTCCTNetworkConnectionInfo];
+      NSData *networkConnectionInfoData = [[NSData alloc] initWithBase64EncodedString:base64Data
+                                                                              options:0];
+      if (error) {
+        GDTCORLogDebug(@"Error when getting an event's network_connection_info: %@", error);
+        return nil;
+      } else {
+        return networkConnectionInfoData;
+      }
+    } @catch (NSException *exception) {
+      GDTCORLogDebug(@"Error when getting an event's network_connection_info: %@", exception);
+    }
+  }
+  return nil;
+}
+
+- (NSNumber *)eventCode {
+  if (self.customBytes) {
+    @try {
+      NSError *error;
+      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes
+                                                                options:0
+                                                                  error:&error];
+      NSString *eventCodeString = bytesDict[GDTCCTEventCodeInfo];
+
+      if (!eventCodeString) {
+        return nil;
+      }
+
+      NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
+      formatter.numberStyle = NSNumberFormatterDecimalStyle;
+      NSNumber *eventCode = [formatter numberFromString:eventCodeString];
+
+      if (error) {
+        GDTCORLogDebug(@"Error when getting an event's network_connection_info: %@", error);
+        return nil;
+      } else {
+        return eventCode;
+      }
+    } @catch (NSException *exception) {
+      GDTCORLogDebug(@"Error when getting an event's event_code: %@", exception);
+    }
+  }
+  return nil;
+}
+
+- (void)setEventCode:(NSNumber *)eventCode {
+  if (eventCode == nil) {
+    if (!self.customBytes) {
+      return;
+    }
+
+    NSError *error;
+    NSMutableDictionary *bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes
+                                                                      options:0
+                                                                        error:&error] mutableCopy];
+    if (error) {
+      GDTCORLogDebug(@"Error when setting an event's event_code: %@", error);
+      return;
+    }
+
+    [bytesDict removeObjectForKey:GDTCCTEventCodeInfo];
+    self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];
+    if (error) {
+      self.customBytes = nil;
+      GDTCORLogDebug(@"Error when setting an event's event_code: %@", error);
+      return;
+    }
+    return;
+  }
+
+  @try {
+    NSMutableDictionary *bytesDict;
+    NSError *error;
+    if (self.customBytes) {
+      bytesDict = [[NSJSONSerialization JSONObjectWithData:self.customBytes options:0
+                                                     error:&error] mutableCopy];
+      if (error) {
+        GDTCORLogDebug(@"Error when setting an event's event_code: %@", error);
+        return;
+      }
+    } else {
+      bytesDict = [[NSMutableDictionary alloc] init];
+    }
+
+    NSString *eventCodeString = [eventCode stringValue];
+    if (eventCodeString == nil) {
+      return;
+    }
+
+    [bytesDict setObject:eventCodeString forKey:GDTCCTEventCodeInfo];
+
+    self.customBytes = [NSJSONSerialization dataWithJSONObject:bytesDict options:0 error:&error];
+    if (error) {
+      self.customBytes = nil;
+      GDTCORLogDebug(@"Error when setting an event's network_connection_info: %@", error);
+      return;
+    }
+
+  } @catch (NSException *exception) {
+    GDTCORLogDebug(@"Error when getting an event's network_connection_info: %@", exception);
+  }
+}
+
+@end

+ 0 - 102
GoogleDataTransportCCTSupport/GDTCCTLibrary/GDTCOREvent+NetworkConnectionInfo.m

@@ -1,102 +0,0 @@
-/*
- * Copyright 2020 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.
- */
-
-#import "GDTCCTLibrary/Private/GDTCOREvent+NetworkConnectionInfo.h"
-
-#import <GoogleDataTransport/GDTCORConsoleLogger.h>
-
-NSString *const GDTCCTNeedsNetworkConnectionInfo = @"needs_network_connection_info";
-
-NSString *const GDTCCTNetworkConnectionInfo = @"network_connection_info";
-
-@implementation GDTCOREvent (CCTNetworkConnectionInfo)
-
-- (void)setNeedsNetworkConnectionInfoPopulated:(BOOL)needsNetworkConnectionInfoPopulated {
-  if (!needsNetworkConnectionInfoPopulated) {
-    self.customBytes = nil;
-  } else {
-    @try {
-      NSError *error;
-      self.customBytes =
-          [NSJSONSerialization dataWithJSONObject:@{GDTCCTNeedsNetworkConnectionInfo : @YES}
-                                          options:0
-                                            error:&error];
-    } @catch (NSException *exception) {
-      GDTCORLogDebug(@"Error when setting the event for needs_network_connection_info: %@",
-                     exception);
-    }
-  }
-}
-
-- (BOOL)needsNetworkConnectionInfoPopulated {
-  if (self.customBytes) {
-    @try {
-      NSError *error;
-      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes
-                                                                options:0
-                                                                  error:&error];
-      return bytesDict && !error && [bytesDict[GDTCCTNeedsNetworkConnectionInfo] boolValue];
-    } @catch (NSException *exception) {
-      GDTCORLogDebug(@"Error when checking the event for needs_network_connection_info: %@",
-                     exception);
-    }
-  }
-  return NO;
-}
-
-- (void)setNetworkConnectionInfoData:(NSData *)networkConnectionInfoData {
-  @try {
-    NSError *error;
-    NSString *dataString = [networkConnectionInfoData base64EncodedStringWithOptions:0];
-    if (dataString) {
-      self.customBytes =
-          [NSJSONSerialization dataWithJSONObject:@{GDTCCTNetworkConnectionInfo : dataString}
-                                          options:0
-                                            error:&error];
-      if (error) {
-        self.customBytes = nil;
-        GDTCORLogDebug(@"Error when setting an event's network_connection_info: %@", error);
-      }
-    }
-  } @catch (NSException *exception) {
-    GDTCORLogDebug(@"Error when setting an event's network_connection_info: %@", exception);
-  }
-}
-
-- (nullable NSData *)networkConnectionInfoData {
-  if (self.customBytes) {
-    @try {
-      NSError *error;
-      NSDictionary *bytesDict = [NSJSONSerialization JSONObjectWithData:self.customBytes
-                                                                options:0
-                                                                  error:&error];
-      NSString *base64Data = bytesDict[GDTCCTNetworkConnectionInfo];
-      NSData *networkConnectionInfoData = [[NSData alloc] initWithBase64EncodedString:base64Data
-                                                                              options:0];
-      if (error) {
-        GDTCORLogDebug(@"Error when getting an event's network_connection_info: %@", error);
-        return nil;
-      } else {
-        return networkConnectionInfoData;
-      }
-    } @catch (NSException *exception) {
-      GDTCORLogDebug(@"Error when getting an event's network_connection_info: %@", exception);
-    }
-  }
-  return nil;
-}
-
-@end

+ 5 - 1
GoogleDataTransportCCTSupport/GDTCCTLibrary/Private/GDTCOREvent+NetworkConnectionInfo.h → GoogleDataTransportCCTSupport/GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h

@@ -30,7 +30,7 @@ FOUNDATION_EXPORT NSString *const GDTCCTNetworkConnectionInfo;
 
 /** A category that uses the customBytes property of a GDTCOREvent to store network connection info.
  */
-@interface GDTCOREvent (CCTNetworkConnectionInfo)
+@interface GDTCOREvent (GDTCCTSupport)
 
 /** If YES, needs the network connection info field set during prioritization.
  * @note Uses the GDTCOREvent customBytes property.
@@ -42,6 +42,10 @@ FOUNDATION_EXPORT NSString *const GDTCCTNetworkConnectionInfo;
  */
 @property(nullable, nonatomic) NSData *networkConnectionInfoData;
 
+/** Code that identifies the event to be sent to the CCT backend.
+ */
+@property(nullable, nonatomic) NSNumber *eventCode;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 31 - 1
GoogleDataTransportCCTSupport/GDTCCTTests/Unit/GDTCCTPrioritizerTest.m

@@ -20,7 +20,7 @@
 
 #import "GDTCCTLibrary/Private/GDTCCTNanopbHelpers.h"
 #import "GDTCCTLibrary/Private/GDTCCTPrioritizer.h"
-#import "GDTCCTLibrary/Private/GDTCOREvent+NetworkConnectionInfo.h"
+#import "GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h"
 
 @interface GDTCCTPrioritizerTest : XCTestCase
 
@@ -168,14 +168,44 @@
   GDTCCTPrioritizer *prioritizer = [[GDTCCTPrioritizer alloc] init];
   GDTCOREvent *event = [_CCTGenerator generateEvent:GDTCOREventQosDefault];
   event.needsNetworkConnectionInfoPopulated = YES;
+  event.eventCode = @(1405);
   [prioritizer prioritizeEvent:event];
   NSData *networkConnectionInfoData = event.networkConnectionInfoData;
   XCTAssertNotNil(networkConnectionInfoData);
+  XCTAssertNotNil(event.eventCode);
+  XCTAssertEqualObjects(event.eventCode, @(1405));
   gdt_cct_NetworkConnectionInfo info;
   [networkConnectionInfoData getBytes:&info length:networkConnectionInfoData.length];
   XCTAssertNotEqual(info.network_type, gdt_cct_NetworkConnectionInfo_NetworkType_NONE);
 }
 
+/** Tests getting and setting the eventCode. */
+- (void)testEventCode {
+  NSNumber *const testCode = @(1405);
+  GDTCOREvent *event = [_CCTGenerator generateEvent:GDTCOREventQosDefault];
+  event.eventCode = testCode;
+  XCTAssertEqualObjects(event.eventCode, testCode);
+
+  event.needsNetworkConnectionInfoPopulated = NO;
+  XCTAssertEqualObjects(event.eventCode, testCode);
+
+  event.needsNetworkConnectionInfoPopulated = YES;
+  XCTAssertEqualObjects(event.eventCode, testCode);
+
+  NSData *testData = [@"test" dataUsingEncoding:kCFStringEncodingUTF8];
+  event.networkConnectionInfoData = testData;
+  XCTAssertEqualObjects(event.eventCode, testCode);
+
+  event.networkConnectionInfoData = nil;
+  XCTAssertEqualObjects(event.eventCode, testCode);
+
+  event.eventCode = nil;
+  event.networkConnectionInfoData = testData;
+  XCTAssertEqualObjects(event.eventCode, nil);
+  XCTAssertNotNil(event.networkConnectionInfoData);
+  XCTAssertEqualObjects(event.networkConnectionInfoData, testData);
+}
+
 /** Tests encoding and decoding a clock using a keyed archiver. */
 - (void)testEncodingAndDecoding {
   GDTCCTPrioritizer *prioritizer = [GDTCCTPrioritizer sharedInstance];

+ 4 - 0
GoogleDataTransportCCTSupport/GDTCCTTests/Unit/Helpers/GDTCCTEventGenerator.m

@@ -21,6 +21,8 @@
 #import <GoogleDataTransport/GDTCORPlatform.h>
 #import <GoogleDataTransport/GDTCORTargets.h>
 
+#import "GDTCCTLibrary/Public/GDTCOREvent+GDTCCTSupport.h"
+
 @interface GDTCCTEventGeneratorDataObject : NSObject <GDTCOREventDataObject>
 
 @property(nullable, nonatomic) NSURL *dataFile;
@@ -78,6 +80,7 @@
   GDTCCTEventGeneratorDataObject *dataObject = [[GDTCCTEventGeneratorDataObject alloc] init];
   dataObject.dataFile = testDataFile;
   event.dataObject = dataObject;
+  event.eventCode = @(1405);
   NSString *eventPath = [NSString stringWithFormat:@"test-event-%lf", CFAbsoluteTimeGetCurrent()];
   NSError *error;
   [self writeEvent:event toGDTPath:eventPath error:&error];
@@ -93,6 +96,7 @@
   GDTCCTEventGeneratorDataObject *dataObject = [[GDTCCTEventGeneratorDataObject alloc] init];
   dataObject.dataFile = fileURL;
   event.dataObject = dataObject;
+  event.eventCode = @(1405);
   NSError *error;
   [self writeEvent:event
          toGDTPath:[NSString stringWithFormat:@"test-event-%lf", CFAbsoluteTimeGetCurrent()]