Class CallId

java.lang.Object
com.codename1.call.CallId

public final class CallId extends Object

Canonical form of the identifier that names one call everywhere: in this API, in CallKit, in Telecom, and in the VoIP push payload a server sends.

It is an RFC 4122 identifier written as 36 characters, uppercase, with hyphens -- 6B29FC40-CA47-1067-B31D-00DD010662DA. The case is fixed rather than ignored because the identifier is compared as a string on every hop, including by a server that did not come from this API, and "compare case-insensitively everywhere" is a rule that only has to be forgotten once.

Who allocates one
  • For a call this app places or learns about over its own connection, this app allocates with random().
  • For a call that arrives as a VoIP push, the sending server allocates and the identifier travels in the payload, because on iOS the call must be reported to the system before any of this app's code runs. See VoipPush.

Either way the same identifier must be used by both ends for the whole life of the call, or the two sides will disagree about which call an action refers to.

This class is not instantiated; it holds the format and the generator.

  • Method Summary

    Modifier and Type
    Method
    Description
    static String
    format(byte[] bytes)
    Renders 16 bytes as a canonical identifier.
    static boolean
    Whether id is a canonical identifier: 36 characters, hyphens in the four expected places, hex everywhere else.
    static String
    Upper-cases a well-formed identifier, or returns null if it is not well-formed.
    static String
    A fresh random (version 4) identifier in canonical form.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • random

      public static String random()

      A fresh random (version 4) identifier in canonical form.

      From SecureRandom, deliberately, and NOT from java.util.Random. The device runtime's Random is this(System.currentTimeMillis()) over a 48-bit LCG -- see vm/JavaAPI/src/java/util/Random.java -- so two processes that reach this class in the same millisecond produce the same sequence of identifiers, and it is the SEED that collides rather than the 122 random bits, which is a far smaller space than the format suggests. A call id is not decoration: it is the key CallKit and Telecom hold the session under and the token the app's server routes signalling by, so two calls sharing one aliases them -- CallKit answers a duplicate report with CallUUIDAlreadyExists, and a server hands the wrong session an answer or an end.

      Every port that supports calling implements secureRandomBytes, so this does not narrow which PLATFORMS the API works on -- but it does require the runtime to be up, because the bytes come through the implementation. That is true wherever application code runs and is NOT true in a platform service the OS starts on its own: Android's CN1ConnectionService can be created by Telecom in a process with no Display, and it mints its own id there rather than calling this. A port adding a similar entry point has to do the same.

      Returns:
      36 uppercase characters with hyphens
    • format

      public static String format(byte[] bytes)
      Renders 16 bytes as a canonical identifier.
      Parameters:
      bytes - exactly 16 bytes
      Returns:
      the canonical form
      Throws:
      IllegalArgumentException - if bytes is not 16 long
    • isValid

      public static boolean isValid(String id)
      Whether id is a canonical identifier: 36 characters, hyphens in the four expected places, hex everywhere else. Case is not checked here -- use normalize(String) to both check and fix the case.
      Parameters:
      id - the candidate, may be null
      Returns:
      true if the shape is right
    • normalize

      public static String normalize(String id)

      Upper-cases a well-formed identifier, or returns null if it is not well-formed.

      Ports call this on the way in, so a lowercase identifier from a server payload is accepted and stored canonically rather than becoming a call nothing can later find. A null return is the signal to answer CallError.INVALID_ID; this never throws, because the value routinely comes from off the device.

      Parameters:
      id - the candidate, may be null
      Returns:
      the canonical form, or null if id is not an identifier