/** * The call state is a combination of the plain state and a call ID. * <p> * The call state is global, there should not be multiple instances of this. * <p> * This is a pure data holder, no validation is being done. * <p> * This class is thread safe.
*/
@AnyThread publicclass CallState { privatestaticfinal Logger logger = getThreemaLogger("CallState");
/** * No call is currently active.
*/ staticfinalint IDLE = 0;
/** * This state only happens on the callee side, * before the call was accepted.
*/ staticfinalint RINGING = 1;
/** * A call was accepted and is being setup.
*/ staticfinalint INITIALIZING = 2;
/** * A call is currently ongoing.
*/ staticfinalint CALLING = 3;
/** * A call is being disconnected.
*/ staticfinalint DISCONNECTING = 4;
@Retention(RetentionPolicy.SOURCE)
@IntDef({IDLE, RINGING, INITIALIZING, CALLING, DISCONNECTING})
@interface State {
}
privatefinal AtomicInteger state = new AtomicInteger(IDLE); privatefinal AtomicLong callId = new AtomicLong(0);
/** * Whether or not an answer for this call ID has been received yet. * <p> * This flag is reset when the state transitions to DISCONNECTING or IDLE.
*/ privatevolatileboolean answerReceived = false;
/** * The incoming call counter is a transitional variable that is used as long as the call ID has * not yet been fully rolled out. It is being used to avoid problems if two calls are using the * default call ID "0". The counter is only incremented for incoming calls (in setStateRinging).
*/
@Deprecated privatefinal AtomicLong incomingCallCounter = new AtomicLong(0);
/** * Return the current Call ID. * <p> * Note: Depending on the use case you might want to use {@link #getStateSnapshot()} instead.
*/ publiclong getCallId() { returnthis.callId.get();
}
/** * Return whether an answer was already received for this call.
*/ publicsynchronizedboolean answerReceived() { returnthis.answerReceived;
}
/** * Return an immutable snapshot of the current state. * This allows reading the state and the Call ID independently without locking.
*/ publicsynchronized @NonNull CallStateSnapshot getStateSnapshot() { returnnew CallStateSnapshot( this.state.get(), this.callId.get(), this.incomingCallCounter.get()
);
}
/** * Return the state name for the specified state.
*/ static @NonNull String getStateName(@State int state) { switch (state) { case CallState.IDLE: return"IDLE"; case CallState.RINGING: return"RINGING"; case CallState.INITIALIZING: return"INITIALIZING"; case CallState.CALLING: return"CALLING"; case CallState.DISCONNECTING: return"DISCONNECTING"; default: return"UNKNOWN";
}
}
publicsynchronizedvoid setRinging(long callId) { final @State int state = this.state.get(); if (this.state.get() != IDLE) {
logger.warn("Call state change from {} to RINGING", getStateName(state));
} this.state.set(RINGING);
if (this.callId.get() != 0) {
logger.warn("Call ID changed from {} to {}", this.callId, callId);
} this.callId.set(callId);
this.incomingCallCounter.incrementAndGet();
}
publicsynchronizedvoid setInitializing(long callId) { final @State int state = this.state.get(); if (state != RINGING && state != IDLE) {
logger.warn("Call state change from {} to INITIALIZING", getStateName(state));
} this.state.set(INITIALIZING);
finallong oldCallId = this.callId.get(); if (oldCallId != 0 && oldCallId != callId) {
logger.warn("Call ID changed from {} to {}", oldCallId, callId);
} this.callId.set(callId);
}
publicsynchronizedvoid setCalling(long callId) { final @State int state = this.state.get(); if (state != INITIALIZING) {
logger.warn("Call state change from {} to CALLING", getStateName(state));
} this.state.set(CALLING);
finallong oldCallId = this.callId.get(); if (oldCallId != callId) {
logger.warn("Call ID changed from {} to {}", oldCallId, callId);
} this.callId.set(callId);
}
publicsynchronizedvoid setDisconnecting(long callId) { final @State int state = this.state.get(); if (state != INITIALIZING && state != CALLING) {
logger.warn("Call state change from {} to DISCONNECTING", getStateName(state));
} this.state.set(DISCONNECTING);
finallong oldCallId = this.callId.get(); if (oldCallId != callId) {
logger.warn("Call ID changed from {} to {}", oldCallId, callId);
} this.callId.set(callId); this.answerReceived = false;
}
//endregion
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-04-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.