@Override
  public void track(TrackPayload track) {
    Properties properties = track.properties();
    String event = track.event();
    String category = properties.category();

    sendProductEvent(event, category, properties);

    if (COMPLETED_ORDER_PATTERN.matcher(event).matches()) {
      List<Product> products = properties.products();
      if (!isNullOrEmpty(products)) {
        for (int i = 0; i < products.size(); i++) {
          Product product = products.get(i);
          ItemHitBuilder hitBuilder = new ItemHitBuilder();
          hitBuilder
              .setTransactionId(properties.orderId())
              .setName(product.name())
              .setSku(product.sku())
              .setPrice(product.price())
              .setQuantity(product.getLong(QUANTITY_KEY, 0))
              .build();
          attachCustomDimensionsAndMetrics(hitBuilder, properties);
          Map<String, String> hit = hitBuilder.build();
          tracker.send(hit);
          logger.verbose("tracker.send(%s);", hit);
        }
      }
      TransactionBuilder transactionBuilder = new TransactionBuilder();
      transactionBuilder
          .setTransactionId(properties.orderId())
          .setCurrencyCode(properties.currency())
          .setRevenue(properties.total())
          .setTax(properties.tax())
          .setShipping(properties.shipping());
      Map<String, String> transaction = transactionBuilder.build();
      tracker.send(transaction);
      logger.verbose("tracker.send(%s);", transaction);
    }

    String label = properties.getString(LABEL_KEY);
    EventHitBuilder eventHitBuilder = new EventHitBuilder();
    eventHitBuilder
        .setAction(event)
        .setCategory(isNullOrEmpty(category) ? DEFAULT_CATEGORY : category)
        .setLabel(label)
        .setValue((int) properties.value());
    attachCustomDimensionsAndMetrics(eventHitBuilder, properties);
    Map<String, String> eventHit = eventHitBuilder.build();
    tracker.send(eventHit);
    logger.verbose("tracker.send(%s);", eventHit);
  }
  @Override
  public void screen(ScreenPayload screen) {
    Properties properties = screen.properties();
    String screenName = screen.event();

    sendProductEvent(screenName, screen.category(), properties);

    tracker.setScreenName(screenName);
    logger.verbose("tracker.setScreenName(%s);", screenName);

    ScreenViewHitBuilder hitBuilder = new ScreenViewHitBuilder();
    attachCustomDimensionsAndMetrics(hitBuilder, properties);
    Map<String, String> hit = hitBuilder.build();
    tracker.send(hit);
    logger.verbose("tracker.send(%s);", hit);
  }
 public void uncaughtException(Thread thread, Throwable throwable) {
   String s = "UncaughtException";
   if (xZ != null) {
     if (thread != null) {
       s = thread.getName();
     } else {
       s = null;
     }
     s = xZ.getDescription(s, throwable);
   }
   z.V((new StringBuilder()).append("Tracking Exception: ").append(s).toString());
   xY.send((new HitBuilders.ExceptionBuilder()).setDescription(s).setFatal(true).build());
   GoogleAnalytics.getInstance(mContext).dispatchLocalHits();
   if (xX != null) {
     z.V("Passing exception to original handler.");
     xX.uncaughtException(thread, throwable);
   }
 }
  /** Send a product event. */
  void sendProductEvent(String event, String category, Properties properties) {
    if (!PRODUCT_EVENT_NAME_PATTERN.matcher(event).matches()) {
      return;
    }

    ItemHitBuilder itemHitBuilder = new ItemHitBuilder();
    itemHitBuilder
        .setTransactionId(properties.orderId())
        .setCurrencyCode(properties.currency())
        .setName(properties.name())
        .setSku(properties.sku())
        .setCategory(isNullOrEmpty(category) ? DEFAULT_CATEGORY : category)
        .setPrice(properties.price())
        .setQuantity(properties.getLong(QUANTITY_KEY, 0))
        .build();
    attachCustomDimensionsAndMetrics(itemHitBuilder, properties);
    Map<String, String> itemHit = itemHitBuilder.build();
    tracker.send(itemHit);
    logger.verbose("tracker.send(%s);", itemHit);
  }