From 057def534c2a18e2e1b70e1e5e04ce09e9ac3b79 Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Thu, 5 May 2016 17:17:07 -0700 Subject: [PATCH] Add support for Telecom analytics extensions Add classes for call events and a field for them in ParcelableCallAnalytics. Add classes for timing information on user-visible operations. Add the TelecomAnalytics class as the top-level object for analytics. Add log session timing information to the TelecomAnalytics class, independent of individual calls. Bug: 28623064 Change-Id: Ifee5fdf6b6b341869ff0ff26c4388d357e3d9922 --- api/system-current.txt | 108 ++++++++++- .../telecom/ParcelableCallAnalytics.java | 182 +++++++++++++++++- ...llAnalytics.aidl => TelecomAnalytics.aidl} | 2 +- .../android/telecom/TelecomAnalytics.java | 148 ++++++++++++++ .../java/android/telecom/TelecomManager.java | 4 +- telecomm/java/android/telecom/TimedEvent.java | 51 +++++ .../internal/telecom/ITelecomService.aidl | 4 +- 7 files changed, 491 insertions(+), 8 deletions(-) rename telecomm/java/android/telecom/{ParcelableCallAnalytics.aidl => TelecomAnalytics.aidl} (94%) create mode 100644 telecomm/java/android/telecom/TelecomAnalytics.java create mode 100644 telecomm/java/android/telecom/TimedEvent.java diff --git a/api/system-current.txt b/api/system-current.txt index 213ae53546243..24fd7288ee7fa 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -39332,14 +39332,16 @@ package android.telecom { } public class ParcelableCallAnalytics implements android.os.Parcelable { - ctor public ParcelableCallAnalytics(long, long, int, boolean, boolean, int, int, boolean, java.lang.String, boolean); + ctor public ParcelableCallAnalytics(long, long, int, boolean, boolean, int, int, boolean, java.lang.String, boolean, java.util.List, java.util.List); ctor public ParcelableCallAnalytics(android.os.Parcel); + method public java.util.List analyticsEvents(); method public int describeContents(); method public long getCallDurationMillis(); method public int getCallTechnologies(); method public int getCallTerminationCode(); method public int getCallType(); method public java.lang.String getConnectionService(); + method public java.util.List getEventTimings(); method public long getStartTimeMillis(); method public boolean isAdditionalCall(); method public boolean isCreatedFromExistingConnection(); @@ -39360,6 +39362,73 @@ package android.telecom { field public static final int THIRD_PARTY_PHONE = 16; // 0x10 } + public static final class ParcelableCallAnalytics.AnalyticsEvent implements android.os.Parcelable { + ctor public ParcelableCallAnalytics.AnalyticsEvent(int, long); + method public int describeContents(); + method public int getEventName(); + method public long getTimeSinceLastEvent(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int AUDIO_ROUTE_BT = 204; // 0xcc + field public static final int AUDIO_ROUTE_EARPIECE = 205; // 0xcd + field public static final int AUDIO_ROUTE_HEADSET = 206; // 0xce + field public static final int AUDIO_ROUTE_SPEAKER = 207; // 0xcf + field public static final int BIND_CS = 5; // 0x5 + field public static final int BLOCK_CHECK_FINISHED = 105; // 0x69 + field public static final int BLOCK_CHECK_INITIATED = 104; // 0x68 + field public static final int CONFERENCE_WITH = 300; // 0x12c + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int CS_BOUND = 6; // 0x6 + field public static final int DIRECT_TO_VM_FINISHED = 103; // 0x67 + field public static final int DIRECT_TO_VM_INITIATED = 102; // 0x66 + field public static final int FILTERING_COMPLETED = 107; // 0x6b + field public static final int FILTERING_INITIATED = 106; // 0x6a + field public static final int FILTERING_TIMED_OUT = 108; // 0x6c + field public static final int MUTE = 202; // 0xca + field public static final int REMOTELY_HELD = 402; // 0x192 + field public static final int REMOTELY_UNHELD = 403; // 0x193 + field public static final int REQUEST_ACCEPT = 7; // 0x7 + field public static final int REQUEST_HOLD = 400; // 0x190 + field public static final int REQUEST_PULL = 500; // 0x1f4 + field public static final int REQUEST_REJECT = 8; // 0x8 + field public static final int REQUEST_UNHOLD = 401; // 0x191 + field public static final int SCREENING_COMPLETED = 101; // 0x65 + field public static final int SCREENING_SENT = 100; // 0x64 + field public static final int SET_ACTIVE = 1; // 0x1 + field public static final int SET_DIALING = 4; // 0x4 + field public static final int SET_DISCONNECTED = 2; // 0x2 + field public static final int SET_HOLD = 404; // 0x194 + field public static final int SET_PARENT = 302; // 0x12e + field public static final int SET_SELECT_PHONE_ACCOUNT = 0; // 0x0 + field public static final int SILENCE = 201; // 0xc9 + field public static final int SKIP_RINGING = 200; // 0xc8 + field public static final int SPLIT_CONFERENCE = 301; // 0x12d + field public static final int START_CONNECTION = 3; // 0x3 + field public static final int SWAP = 405; // 0x195 + field public static final int UNMUTE = 203; // 0xcb + } + + public static final class ParcelableCallAnalytics.EventTiming implements android.os.Parcelable { + ctor public ParcelableCallAnalytics.EventTiming(int, long); + method public int describeContents(); + method public int getName(); + method public long getTime(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int ACCEPT_TIMING = 0; // 0x0 + field public static final int BIND_CS_TIMING = 6; // 0x6 + field public static final int BLOCK_CHECK_FINISHED_TIMING = 9; // 0x9 + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int DIRECT_TO_VM_FINISHED_TIMING = 8; // 0x8 + field public static final int DISCONNECT_TIMING = 2; // 0x2 + field public static final int FILTERING_COMPLETED_TIMING = 10; // 0xa + field public static final int FILTERING_TIMED_OUT_TIMING = 11; // 0xb + field public static final int HOLD_TIMING = 3; // 0x3 + field public static final int INVALID = 999999; // 0xf423f + field public static final int OUTGOING_TIME_TO_DIALING_TIMING = 5; // 0x5 + field public static final int REJECT_TIMING = 1; // 0x1 + field public static final int SCREENING_COMPLETED_TIMING = 7; // 0x7 + field public static final int UNHOLD_TIMING = 4; // 0x4 + } + public final deprecated class Phone { method public final void addListener(android.telecom.Phone.Listener); method public final boolean canAddCall(); @@ -39576,6 +39645,41 @@ package android.telecom { field public static final android.os.Parcelable.Creator CREATOR; } + public final class TelecomAnalytics implements android.os.Parcelable { + ctor public TelecomAnalytics(java.util.List, java.util.List); + method public int describeContents(); + method public java.util.List getCallAnalytics(); + method public java.util.List getSessionTimings(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + } + + public static final class TelecomAnalytics.SessionTiming implements android.os.Parcelable { + ctor public TelecomAnalytics.SessionTiming(int, long); + method public int describeContents(); + method public java.lang.Integer getKey(); + method public long getTime(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int CSW_ADD_CONFERENCE_CALL = 108; // 0x6c + field public static final int CSW_HANDLE_CREATE_CONNECTION_COMPLETE = 100; // 0x64 + field public static final int CSW_REMOVE_CALL = 106; // 0x6a + field public static final int CSW_SET_ACTIVE = 101; // 0x65 + field public static final int CSW_SET_DIALING = 103; // 0x67 + field public static final int CSW_SET_DISCONNECTED = 104; // 0x68 + field public static final int CSW_SET_IS_CONFERENCED = 107; // 0x6b + field public static final int CSW_SET_ON_HOLD = 105; // 0x69 + field public static final int CSW_SET_RINGING = 102; // 0x66 + field public static final int ICA_ANSWER_CALL = 1; // 0x1 + field public static final int ICA_CONFERENCE = 8; // 0x8 + field public static final int ICA_DISCONNECT_CALL = 3; // 0x3 + field public static final int ICA_HOLD_CALL = 4; // 0x4 + field public static final int ICA_MUTE = 6; // 0x6 + field public static final int ICA_REJECT_CALL = 2; // 0x2 + field public static final int ICA_SET_AUDIO_ROUTE = 7; // 0x7 + field public static final int ICA_UNHOLD_CALL = 5; // 0x5 + } + public class TelecomManager { method public void acceptRingingCall(); method public void acceptRingingCall(int); @@ -39585,7 +39689,7 @@ package android.telecom { method public deprecated void clearAccounts(); method public void clearPhoneAccounts(); method public android.content.Intent createManageBlockedNumbersIntent(); - method public java.util.List dumpAnalytics(); + method public android.telecom.TelecomAnalytics dumpAnalytics(); method public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean); method public boolean endCall(); method public android.net.Uri getAdnUriForPhoneAccount(android.telecom.PhoneAccountHandle); diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java index e7c9672605323..0ee9babe66591 100644 --- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java +++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java @@ -20,11 +20,168 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.util.ArrayList; +import java.util.List; + /** * @hide */ @SystemApi public class ParcelableCallAnalytics implements Parcelable { + public static final class AnalyticsEvent implements Parcelable { + public static final int SET_SELECT_PHONE_ACCOUNT = 0; + public static final int SET_ACTIVE = 1; + public static final int SET_DISCONNECTED = 2; + public static final int START_CONNECTION = 3; + public static final int SET_DIALING = 4; + public static final int BIND_CS = 5; + public static final int CS_BOUND = 6; + public static final int REQUEST_ACCEPT = 7; + public static final int REQUEST_REJECT = 8; + + public static final int SCREENING_SENT = 100; + public static final int SCREENING_COMPLETED = 101; + public static final int DIRECT_TO_VM_INITIATED = 102; + public static final int DIRECT_TO_VM_FINISHED = 103; + public static final int BLOCK_CHECK_INITIATED = 104; + public static final int BLOCK_CHECK_FINISHED = 105; + public static final int FILTERING_INITIATED = 106; + public static final int FILTERING_COMPLETED = 107; + public static final int FILTERING_TIMED_OUT = 108; + + public static final int SKIP_RINGING = 200; + public static final int SILENCE = 201; + public static final int MUTE = 202; + public static final int UNMUTE = 203; + public static final int AUDIO_ROUTE_BT = 204; + public static final int AUDIO_ROUTE_EARPIECE = 205; + public static final int AUDIO_ROUTE_HEADSET = 206; + public static final int AUDIO_ROUTE_SPEAKER = 207; + + public static final int CONFERENCE_WITH = 300; + public static final int SPLIT_CONFERENCE = 301; + public static final int SET_PARENT = 302; + + public static final int REQUEST_HOLD = 400; + public static final int REQUEST_UNHOLD = 401; + public static final int REMOTELY_HELD = 402; + public static final int REMOTELY_UNHELD = 403; + public static final int SET_HOLD = 404; + public static final int SWAP = 405; + + public static final int REQUEST_PULL = 500; + + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator () { + + @Override + public AnalyticsEvent createFromParcel(Parcel in) { + return new AnalyticsEvent(in); + } + + @Override + public AnalyticsEvent[] newArray(int size) { + return new AnalyticsEvent[size]; + } + }; + + private int mEventName; + private long mTimeSinceLastEvent; + + public AnalyticsEvent(int eventName, long timestamp) { + mEventName = eventName; + mTimeSinceLastEvent = timestamp; + } + + AnalyticsEvent(Parcel in) { + mEventName = in.readInt(); + mTimeSinceLastEvent = in.readLong(); + } + + public int getEventName() { + return mEventName; + } + + public long getTimeSinceLastEvent() { + return mTimeSinceLastEvent; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mEventName); + out.writeLong(mTimeSinceLastEvent); + } + } + + public static final class EventTiming implements Parcelable { + public static final int ACCEPT_TIMING = 0; + public static final int REJECT_TIMING = 1; + public static final int DISCONNECT_TIMING = 2; + public static final int HOLD_TIMING = 3; + public static final int UNHOLD_TIMING = 4; + public static final int OUTGOING_TIME_TO_DIALING_TIMING = 5; + public static final int BIND_CS_TIMING = 6; + public static final int SCREENING_COMPLETED_TIMING = 7; + public static final int DIRECT_TO_VM_FINISHED_TIMING = 8; + public static final int BLOCK_CHECK_FINISHED_TIMING = 9; + public static final int FILTERING_COMPLETED_TIMING = 10; + public static final int FILTERING_TIMED_OUT_TIMING = 11; + + public static final int INVALID = 999999; + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator () { + + @Override + public EventTiming createFromParcel(Parcel in) { + return new EventTiming(in); + } + + @Override + public EventTiming[] newArray(int size) { + return new EventTiming[size]; + } + }; + + private int mName; + private long mTime; + + public EventTiming(int name, long time) { + this.mName = name; + this.mTime = time; + } + + private EventTiming(Parcel in) { + mName = in.readInt(); + mTime = in.readLong(); + } + + public int getName() { + return mName; + } + + public long getTime() { + return mTime; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mName); + out.writeLong(mTime); + } + } + public static final int CALLTYPE_UNKNOWN = 0; public static final int CALLTYPE_INCOMING = 1; public static final int CALLTYPE_OUTGOING = 2; @@ -87,10 +244,17 @@ public class ParcelableCallAnalytics implements Parcelable { // Whether the call object was created from an existing connection. private final boolean isCreatedFromExistingConnection; + // A list of events that are associated with this call + private final List analyticsEvents; + + // A map from event-pair names to their durations. + private final List eventTimings; + public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType, boolean isAdditionalCall, boolean isInterrupted, int callTechnologies, int callTerminationCode, boolean isEmergencyCall, String connectionService, - boolean isCreatedFromExistingConnection) { + boolean isCreatedFromExistingConnection, List analyticsEvents, + List eventTimings) { this.startTimeMillis = startTimeMillis; this.callDurationMillis = callDurationMillis; this.callType = callType; @@ -101,6 +265,8 @@ public class ParcelableCallAnalytics implements Parcelable { this.isEmergencyCall = isEmergencyCall; this.connectionService = connectionService; this.isCreatedFromExistingConnection = isCreatedFromExistingConnection; + this.analyticsEvents = analyticsEvents; + this.eventTimings = eventTimings; } public ParcelableCallAnalytics(Parcel in) { @@ -114,6 +280,10 @@ public class ParcelableCallAnalytics implements Parcelable { isEmergencyCall = readByteAsBoolean(in); connectionService = in.readString(); isCreatedFromExistingConnection = readByteAsBoolean(in); + analyticsEvents = new ArrayList<>(); + in.readTypedList(analyticsEvents, AnalyticsEvent.CREATOR); + eventTimings = new ArrayList<>(); + in.readTypedList(eventTimings, EventTiming.CREATOR); } public void writeToParcel(Parcel out, int flags) { @@ -127,6 +297,8 @@ public class ParcelableCallAnalytics implements Parcelable { writeBooleanAsByte(out, isEmergencyCall); out.writeString(connectionService); writeBooleanAsByte(out, isCreatedFromExistingConnection); + out.writeTypedList(analyticsEvents); + out.writeTypedList(eventTimings); } public long getStartTimeMillis() { @@ -169,6 +341,14 @@ public class ParcelableCallAnalytics implements Parcelable { return isCreatedFromExistingConnection; } + public List analyticsEvents() { + return analyticsEvents; + } + + public List getEventTimings() { + return eventTimings; + } + @Override public int describeContents() { return 0; diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl b/telecomm/java/android/telecom/TelecomAnalytics.aidl similarity index 94% rename from telecomm/java/android/telecom/ParcelableCallAnalytics.aidl rename to telecomm/java/android/telecom/TelecomAnalytics.aidl index b7e78d1959fc4..08ad0a2cad1af 100644 --- a/telecomm/java/android/telecom/ParcelableCallAnalytics.aidl +++ b/telecomm/java/android/telecom/TelecomAnalytics.aidl @@ -19,4 +19,4 @@ package android.telecom; /** * {@hide} */ -parcelable ParcelableCallAnalytics; +parcelable TelecomAnalytics; diff --git a/telecomm/java/android/telecom/TelecomAnalytics.java b/telecomm/java/android/telecom/TelecomAnalytics.java new file mode 100644 index 0000000000000..6e0d02c1a941c --- /dev/null +++ b/telecomm/java/android/telecom/TelecomAnalytics.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 + */ + +package android.telecom; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @hide + */ +@SystemApi +public final class TelecomAnalytics implements Parcelable { + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator () { + + @Override + public TelecomAnalytics createFromParcel(Parcel in) { + return new TelecomAnalytics(in); + } + + @Override + public TelecomAnalytics[] newArray(int size) { + return new TelecomAnalytics[size]; + } + }; + + public static final class SessionTiming extends TimedEvent implements Parcelable { + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator () { + + @Override + public SessionTiming createFromParcel(Parcel in) { + return new SessionTiming(in); + } + + @Override + public SessionTiming[] newArray(int size) { + return new SessionTiming[size]; + } + }; + + public static final int ICA_ANSWER_CALL = 1; + public static final int ICA_REJECT_CALL = 2; + public static final int ICA_DISCONNECT_CALL = 3; + public static final int ICA_HOLD_CALL = 4; + public static final int ICA_UNHOLD_CALL = 5; + public static final int ICA_MUTE = 6; + public static final int ICA_SET_AUDIO_ROUTE = 7; + public static final int ICA_CONFERENCE = 8; + + public static final int CSW_HANDLE_CREATE_CONNECTION_COMPLETE = 100; + public static final int CSW_SET_ACTIVE = 101; + public static final int CSW_SET_RINGING = 102; + public static final int CSW_SET_DIALING = 103; + public static final int CSW_SET_DISCONNECTED = 104; + public static final int CSW_SET_ON_HOLD = 105; + public static final int CSW_REMOVE_CALL = 106; + public static final int CSW_SET_IS_CONFERENCED = 107; + public static final int CSW_ADD_CONFERENCE_CALL = 108; + + private int mId; + private long mTime; + + public SessionTiming(int id, long time) { + this.mId = id; + this.mTime = time; + } + + private SessionTiming(Parcel in) { + mId = in.readInt(); + mTime = in.readLong(); + } + + @Override + public Integer getKey() { + return mId; + } + + @Override + public long getTime() { + return mTime; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mId); + out.writeLong(mTime); + } + } + + private List mSessionTimings; + private List mCallAnalytics; + + public TelecomAnalytics(List sessionTimings, + List callAnalytics) { + this.mSessionTimings = sessionTimings; + this.mCallAnalytics = callAnalytics; + } + + private TelecomAnalytics(Parcel in) { + mSessionTimings = new ArrayList<>(); + in.readTypedList(mSessionTimings, SessionTiming.CREATOR); + mCallAnalytics = new ArrayList<>(); + in.readTypedList(mCallAnalytics, ParcelableCallAnalytics.CREATOR); + } + + public List getSessionTimings() { + return mSessionTimings; + } + + public List getCallAnalytics() { + return mCallAnalytics; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeTypedList(mSessionTimings); + out.writeTypedList(mCallAnalytics); + } +} diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index ff5daaf08230a..f12886afa6e5a 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1443,9 +1443,9 @@ public class TelecomManager { */ @SystemApi @RequiresPermission(Manifest.permission.DUMP) - public List dumpAnalytics() { + public TelecomAnalytics dumpAnalytics() { ITelecomService service = getTelecomService(); - List result = null; + TelecomAnalytics result = null; if (service != null) { try { result = service.dumpCallAnalytics(); diff --git a/telecomm/java/android/telecom/TimedEvent.java b/telecomm/java/android/telecom/TimedEvent.java new file mode 100644 index 0000000000000..e484e791f5efa --- /dev/null +++ b/telecomm/java/android/telecom/TimedEvent.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * 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 + */ + +package android.telecom; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * @hide + */ +public abstract class TimedEvent { + public abstract long getTime(); + public abstract T getKey(); + + public static Map averageTimings(Collection> events) { + HashMap counts = new HashMap<>(); + HashMap result = new HashMap<>(); + + for (TimedEvent entry : events) { + if (counts.containsKey(entry.getKey())) { + counts.put(entry.getKey(), counts.get(entry.getKey()) + 1); + result.put(entry.getKey(), result.get(entry.getKey()) + entry.getTime()); + } else { + counts.put(entry.getKey(), 1); + result.put(entry.getKey(), (double) entry.getTime()); + } + } + + for (Map.Entry entry : result.entrySet()) { + result.put(entry.getKey(), entry.getValue() / counts.get(entry.getKey())); + } + + return result; + } +} + diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 871565de33c99..5c412e7afb0ef 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -18,7 +18,7 @@ package com.android.internal.telecom; import android.content.ComponentName; import android.content.Intent; -import android.telecom.ParcelableCallAnalytics; +import android.telecom.TelecomAnalytics; import android.telecom.PhoneAccountHandle; import android.net.Uri; import android.os.Bundle; @@ -148,7 +148,7 @@ interface ITelecomService { /** * @see TelecomServiceImpl#dumpCallAnalytics */ - List dumpCallAnalytics(); + TelecomAnalytics dumpCallAnalytics(); // // Internal system apis relating to call management.