Analytics.java revision a3eccfee788c3ac3c831a443b085b141b39bb63d
13258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu/* 23258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * Copyright (C) 2015 The Android Open Source Project 33258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * 43258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * Licensed under the Apache License, Version 2.0 (the "License"); 53258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * you may not use this file except in compliance with the License. 63258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * You may obtain a copy of the License at 73258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * 83258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * http://www.apache.org/licenses/LICENSE-2.0 93258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * 103258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * Unless required by applicable law or agreed to in writing, software 113258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * distributed under the License is distributed on an "AS IS" BASIS, 123258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * See the License for the specific language governing permissions and 143258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * limitations under the License 153258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu */ 163258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 173258720f5526f766aa26c19cf01b32ac20d19d1dHall Liupackage com.android.server.telecom; 183258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 19d7fe686253f2135a948cafc776aa25db645ec27eHall Liuimport android.telecom.Connection; 203258720f5526f766aa26c19cf01b32ac20d19d1dHall Liuimport android.telecom.DisconnectCause; 21a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebingerimport android.telecom.Logging.EventManager; 22874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport android.telecom.ParcelableCallAnalytics; 23874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport android.telecom.TelecomAnalytics; 242f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liuimport android.util.Base64; 25a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebingerimport android.telecom.Log; 263258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 273258720f5526f766aa26c19cf01b32ac20d19d1dHall Liuimport com.android.internal.annotations.VisibleForTesting; 283258720f5526f766aa26c19cf01b32ac20d19d1dHall Liuimport com.android.internal.util.IndentingPrintWriter; 293258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 302f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liuimport java.io.PrintWriter; 31874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport java.util.ArrayList; 322f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liuimport java.util.Arrays; 33874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport java.util.Collections; 343258720f5526f766aa26c19cf01b32ac20d19d1dHall Liuimport java.util.HashMap; 35874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport java.util.LinkedList; 36874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport java.util.List; 373258720f5526f766aa26c19cf01b32ac20d19d1dHall Liuimport java.util.Map; 38874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport java.util.stream.Collectors; 39874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 40874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport static android.telecom.ParcelableCallAnalytics.AnalyticsEvent; 41874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liuimport static android.telecom.TelecomAnalytics.SessionTiming; 423258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 433258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu/** 443258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * A class that collects and stores data on how calls are being made, in order to 453258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * aggregate these into useful statistics. 463258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu */ 473258720f5526f766aa26c19cf01b32ac20d19d1dHall Liupublic class Analytics { 482f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu public static final String ANALYTICS_DUMPSYS_ARG = "analytics"; 492f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu private static final String CLEAR_ANALYTICS_ARG = "clear"; 502f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 51874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static final Map<String, Integer> sLogEventToAnalyticsEvent = 52874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu new HashMap<String, Integer>() {{ 53a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SET_SELECT_PHONE_ACCOUNT, 54a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger AnalyticsEvent.SET_SELECT_PHONE_ACCOUNT); 55a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REQUEST_HOLD, AnalyticsEvent.REQUEST_HOLD); 56a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REQUEST_UNHOLD, AnalyticsEvent.REQUEST_UNHOLD); 57a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SWAP, AnalyticsEvent.SWAP); 58a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SKIP_RINGING, AnalyticsEvent.SKIP_RINGING); 59a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.CONFERENCE_WITH, AnalyticsEvent.CONFERENCE_WITH); 60a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SPLIT_FROM_CONFERENCE, AnalyticsEvent.SPLIT_CONFERENCE); 61a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SET_PARENT, AnalyticsEvent.SET_PARENT); 62a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.MUTE, AnalyticsEvent.MUTE); 63a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.UNMUTE, AnalyticsEvent.UNMUTE); 64a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.AUDIO_ROUTE_BT, AnalyticsEvent.AUDIO_ROUTE_BT); 65a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.AUDIO_ROUTE_EARPIECE, AnalyticsEvent.AUDIO_ROUTE_EARPIECE); 66a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.AUDIO_ROUTE_HEADSET, AnalyticsEvent.AUDIO_ROUTE_HEADSET); 67a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.AUDIO_ROUTE_SPEAKER, AnalyticsEvent.AUDIO_ROUTE_SPEAKER); 68a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SILENCE, AnalyticsEvent.SILENCE); 69a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SCREENING_COMPLETED, AnalyticsEvent.SCREENING_COMPLETED); 70a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.BLOCK_CHECK_FINISHED, AnalyticsEvent.BLOCK_CHECK_FINISHED); 71a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.DIRECT_TO_VM_FINISHED, AnalyticsEvent.DIRECT_TO_VM_FINISHED); 72a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REMOTELY_HELD, AnalyticsEvent.REMOTELY_HELD); 73a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REMOTELY_UNHELD, AnalyticsEvent.REMOTELY_UNHELD); 74a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REQUEST_PULL, AnalyticsEvent.REQUEST_PULL); 75a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REQUEST_ACCEPT, AnalyticsEvent.REQUEST_ACCEPT); 76a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.REQUEST_REJECT, AnalyticsEvent.REQUEST_REJECT); 77a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SET_ACTIVE, AnalyticsEvent.SET_ACTIVE); 78a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SET_DISCONNECTED, AnalyticsEvent.SET_DISCONNECTED); 79a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SET_HOLD, AnalyticsEvent.SET_HOLD); 80a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SET_DIALING, AnalyticsEvent.SET_DIALING); 81a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.START_CONNECTION, AnalyticsEvent.START_CONNECTION); 82a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.BIND_CS, AnalyticsEvent.BIND_CS); 83a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.CS_BOUND, AnalyticsEvent.CS_BOUND); 84a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.SCREENING_SENT, AnalyticsEvent.SCREENING_SENT); 85a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.DIRECT_TO_VM_INITIATED, AnalyticsEvent.DIRECT_TO_VM_INITIATED); 86a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.BLOCK_CHECK_INITIATED, AnalyticsEvent.BLOCK_CHECK_INITIATED); 87a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.FILTERING_INITIATED, AnalyticsEvent.FILTERING_INITIATED); 88a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.FILTERING_COMPLETED, AnalyticsEvent.FILTERING_COMPLETED); 89a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.FILTERING_TIMED_OUT, AnalyticsEvent.FILTERING_TIMED_OUT); 90874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu }}; 91874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 92874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static final Map<String, Integer> sLogSessionToSessionId = 93874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu new HashMap<String, Integer> () {{ 94a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_ANSWER_CALL, SessionTiming.ICA_ANSWER_CALL); 95a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_REJECT_CALL, SessionTiming.ICA_REJECT_CALL); 96a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_DISCONNECT_CALL, SessionTiming.ICA_DISCONNECT_CALL); 97a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_HOLD_CALL, SessionTiming.ICA_HOLD_CALL); 98a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_UNHOLD_CALL, SessionTiming.ICA_UNHOLD_CALL); 99a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_MUTE, SessionTiming.ICA_MUTE); 100a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_SET_AUDIO_ROUTE, SessionTiming.ICA_SET_AUDIO_ROUTE); 101a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.ICA_CONFERENCE, SessionTiming.ICA_CONFERENCE); 102a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_HANDLE_CREATE_CONNECTION_COMPLETE, 103874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu SessionTiming.CSW_HANDLE_CREATE_CONNECTION_COMPLETE); 104a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_SET_ACTIVE, SessionTiming.CSW_SET_ACTIVE); 105a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_SET_RINGING, SessionTiming.CSW_SET_RINGING); 106a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_SET_DIALING, SessionTiming.CSW_SET_DIALING); 107a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_SET_DISCONNECTED, SessionTiming.CSW_SET_DISCONNECTED); 108a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_SET_ON_HOLD, SessionTiming.CSW_SET_ON_HOLD); 109a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_REMOVE_CALL, SessionTiming.CSW_REMOVE_CALL); 110a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_SET_IS_CONFERENCED, SessionTiming.CSW_SET_IS_CONFERENCED); 111a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL, 112a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger SessionTiming.CSW_ADD_CONFERENCE_CALL); 113874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 114874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu }}; 115874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 116874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static final Map<String, Integer> sLogEventTimingToAnalyticsEventTiming = 117874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu new HashMap<String, Integer>() {{ 118a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.ACCEPT_TIMING, 119874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.ACCEPT_TIMING); 120a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.REJECT_TIMING, 121874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.REJECT_TIMING); 122a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.DISCONNECT_TIMING, 123874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.DISCONNECT_TIMING); 124a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.HOLD_TIMING, 125874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.HOLD_TIMING); 126a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.UNHOLD_TIMING, 127874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.UNHOLD_TIMING); 128a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.OUTGOING_TIME_TO_DIALING_TIMING, 129874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.OUTGOING_TIME_TO_DIALING_TIMING); 130a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.BIND_CS_TIMING, 131874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.BIND_CS_TIMING); 132a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.SCREENING_COMPLETED_TIMING, 133874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.SCREENING_COMPLETED_TIMING); 134a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.DIRECT_TO_VM_FINISHED_TIMING, 135874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.DIRECT_TO_VM_FINISHED_TIMING); 136a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.BLOCK_CHECK_FINISHED_TIMING, 137874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.BLOCK_CHECK_FINISHED_TIMING); 138a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.FILTERING_COMPLETED_TIMING, 139874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.FILTERING_COMPLETED_TIMING); 140a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger put(LogUtils.Events.Timings.FILTERING_TIMED_OUT_TIMING, 141874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.FILTERING_TIMED_OUT_TIMING); 142874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu }}; 143874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 144874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static final Map<Integer, String> sSessionIdToLogSession = new HashMap<>(); 145874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu static { 146874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu for (Map.Entry<String, Integer> e : sLogSessionToSessionId.entrySet()) { 147874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sSessionIdToLogSession.put(e.getValue(), e.getKey()); 1483258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 149874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 1503258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 151874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static class CallInfo { 152874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCallStartTime(long startTime) { 1533258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1543258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 155874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCallEndTime(long endTime) { 1563258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1573258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 158874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCallIsAdditional(boolean isAdditional) { 1593258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1603258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 161874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCallIsInterrupted(boolean isInterrupted) { 1623258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1633258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 164874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCallDisconnectCause(DisconnectCause disconnectCause) { 1653258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1663258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 167874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void addCallTechnology(int callTechnology) { 1683258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1693258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 170874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCreatedFromExistingConnection(boolean createdFromExistingConnection) { 171874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 172874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 173874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public void setCallConnectionService(String connectionServiceName) { 174874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 175874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 176a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger public void setCallEvents(EventManager.EventRecord records) { 1773258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1784640c4fc55ca4118351330d68684ca9989661ccdHall Liu 1794640c4fc55ca4118351330d68684ca9989661ccdHall Liu public void setCallIsVideo(boolean isVideo) { 1804640c4fc55ca4118351330d68684ca9989661ccdHall Liu } 1814640c4fc55ca4118351330d68684ca9989661ccdHall Liu 1824640c4fc55ca4118351330d68684ca9989661ccdHall Liu public void addVideoEvent(int eventId, int videoState) { 1834640c4fc55ca4118351330d68684ca9989661ccdHall Liu } 1849d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu 1859d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu public void addInCallService(String serviceName, int type) { 1869d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu } 187d7fe686253f2135a948cafc776aa25db645ec27eHall Liu 188d7fe686253f2135a948cafc776aa25db645ec27eHall Liu public void addCallProperties(int properties) { 189d7fe686253f2135a948cafc776aa25db645ec27eHall Liu } 1903258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 1913258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 1923258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu /** 1933258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu * A class that holds data associated with a call. 1943258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu */ 1953258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @VisibleForTesting 1963258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public static class CallInfoImpl extends CallInfo { 1973258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public String callId; 1983258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public long startTime; // start time in milliseconds since the epoch. 0 if not yet set. 1993258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public long endTime; // end time in milliseconds since the epoch. 0 if not yet set. 2003258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public int callDirection; // one of UNKNOWN_DIRECTION, INCOMING_DIRECTION, 2013258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // or OUTGOING_DIRECTION. 2023258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public boolean isAdditionalCall = false; // true if the call came in while another call was 2033258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // in progress or if the user dialed this call 2043258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // while in the middle of another call. 2053258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public boolean isInterrupted = false; // true if the call was interrupted by an incoming 2063258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // or outgoing call. 2073258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public int callTechnologies; // bitmask denoting which technologies a call used. 2083258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2093258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // true if the Telecom Call object was created from an existing connection via 2103258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // CallsManager#createCallForExistingConnection, for example, by ImsConference. 2113258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public boolean createdFromExistingConnection = false; 2123258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2133258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public DisconnectCause callTerminationReason; 2143258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public String connectionService; 2153258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public boolean isEmergency = false; 2163258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 217a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger public EventManager.EventRecord callEvents; 218874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 2194640c4fc55ca4118351330d68684ca9989661ccdHall Liu public boolean isVideo = false; 2202f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu public List<TelecomLogClass.VideoEvent> videoEvents; 2219d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu public List<TelecomLogClass.InCallServiceInfo> inCallServiceInfos; 222d7fe686253f2135a948cafc776aa25db645ec27eHall Liu public int callProperties = 0; 223d7fe686253f2135a948cafc776aa25db645ec27eHall Liu 2244640c4fc55ca4118351330d68684ca9989661ccdHall Liu private long mTimeOfLastVideoEvent = -1; 2254640c4fc55ca4118351330d68684ca9989661ccdHall Liu 2263258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu CallInfoImpl(String callId, int callDirection) { 2273258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callId = callId; 2283258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu startTime = 0; 2293258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu endTime = 0; 2303258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callDirection = callDirection; 2313258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu callTechnologies = 0; 2323258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu connectionService = ""; 2334640c4fc55ca4118351330d68684ca9989661ccdHall Liu videoEvents = new LinkedList<>(); 2349d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu inCallServiceInfos = new LinkedList<>(); 2353258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2363258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2373258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu CallInfoImpl(CallInfoImpl other) { 2383258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callId = other.callId; 2393258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.startTime = other.startTime; 2403258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.endTime = other.endTime; 2413258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callDirection = other.callDirection; 2423258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.isAdditionalCall = other.isAdditionalCall; 2433258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.isInterrupted = other.isInterrupted; 2443258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callTechnologies = other.callTechnologies; 2453258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.createdFromExistingConnection = other.createdFromExistingConnection; 2463258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.connectionService = other.connectionService; 2473258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.isEmergency = other.isEmergency; 248874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu this.callEvents = other.callEvents; 2494640c4fc55ca4118351330d68684ca9989661ccdHall Liu this.isVideo = other.isVideo; 2504640c4fc55ca4118351330d68684ca9989661ccdHall Liu this.videoEvents = other.videoEvents; 251d7fe686253f2135a948cafc776aa25db645ec27eHall Liu this.callProperties = other.callProperties; 2523258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2533258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if (other.callTerminationReason != null) { 2543258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callTerminationReason = new DisconnectCause( 2553258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu other.callTerminationReason.getCode(), 2563258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu other.callTerminationReason.getLabel(), 2573258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu other.callTerminationReason.getDescription(), 2583258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu other.callTerminationReason.getReason(), 2593258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu other.callTerminationReason.getTone()); 2603258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } else { 2613258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callTerminationReason = null; 2623258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2633258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2643258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2653258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 2663258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCallStartTime(long startTime) { 2673258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting startTime for call " + callId + " to " + startTime); 2683258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.startTime = startTime; 2693258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2703258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2713258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 2723258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCallEndTime(long endTime) { 2733258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting endTime for call " + callId + " to " + endTime); 2743258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.endTime = endTime; 2753258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2763258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2773258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 2783258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCallIsAdditional(boolean isAdditional) { 2793258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting isAdditional for call " + callId + " to " + isAdditional); 2803258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.isAdditionalCall = isAdditional; 2813258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2823258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2833258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 2843258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCallIsInterrupted(boolean isInterrupted) { 2853258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting isInterrupted for call " + callId + " to " + isInterrupted); 2863258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.isInterrupted = isInterrupted; 2873258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2883258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2893258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 2903258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void addCallTechnology(int callTechnology) { 2913258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "adding callTechnology for call " + callId + ": " + callTechnology); 2923258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callTechnologies |= callTechnology; 2933258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 2943258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 2953258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 2963258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCallDisconnectCause(DisconnectCause disconnectCause) { 2973258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting disconnectCause for call " + callId + " to " + disconnectCause); 2983258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.callTerminationReason = disconnectCause; 2993258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 3003258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 3013258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 3023258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCreatedFromExistingConnection(boolean createdFromExistingConnection) { 3033258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting createdFromExistingConnection for call " + callId + " to " 3043258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + createdFromExistingConnection); 3053258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.createdFromExistingConnection = createdFromExistingConnection; 3063258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 3073258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 3083258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 3093258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public void setCallConnectionService(String connectionServiceName) { 3103258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "setting connection service for call " + callId + ": " 3113258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + connectionServiceName); 3123258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu this.connectionService = connectionServiceName; 3133258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 3143258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 3153258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu @Override 316a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger public void setCallEvents(EventManager.EventRecord records) { 317874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu this.callEvents = records; 318874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 319874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 320874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu @Override 3214640c4fc55ca4118351330d68684ca9989661ccdHall Liu public void setCallIsVideo(boolean isVideo) { 3224640c4fc55ca4118351330d68684ca9989661ccdHall Liu this.isVideo = isVideo; 3234640c4fc55ca4118351330d68684ca9989661ccdHall Liu } 3244640c4fc55ca4118351330d68684ca9989661ccdHall Liu 3254640c4fc55ca4118351330d68684ca9989661ccdHall Liu @Override 3264640c4fc55ca4118351330d68684ca9989661ccdHall Liu public void addVideoEvent(int eventId, int videoState) { 3274640c4fc55ca4118351330d68684ca9989661ccdHall Liu long timeSinceLastEvent; 3284640c4fc55ca4118351330d68684ca9989661ccdHall Liu long currentTime = System.currentTimeMillis(); 3294640c4fc55ca4118351330d68684ca9989661ccdHall Liu if (mTimeOfLastVideoEvent < 0) { 3304640c4fc55ca4118351330d68684ca9989661ccdHall Liu timeSinceLastEvent = -1; 3314640c4fc55ca4118351330d68684ca9989661ccdHall Liu } else { 3324640c4fc55ca4118351330d68684ca9989661ccdHall Liu timeSinceLastEvent = roundToOneSigFig(currentTime - mTimeOfLastVideoEvent); 3334640c4fc55ca4118351330d68684ca9989661ccdHall Liu } 3344640c4fc55ca4118351330d68684ca9989661ccdHall Liu mTimeOfLastVideoEvent = currentTime; 3354640c4fc55ca4118351330d68684ca9989661ccdHall Liu 3362f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu videoEvents.add(new TelecomLogClass.VideoEvent() 3372f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setEventName(eventId) 3382f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setTimeSinceLastEventMillis(timeSinceLastEvent) 3392f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setVideoState(videoState)); 3404640c4fc55ca4118351330d68684ca9989661ccdHall Liu } 3414640c4fc55ca4118351330d68684ca9989661ccdHall Liu 3424640c4fc55ca4118351330d68684ca9989661ccdHall Liu @Override 3439d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu public void addInCallService(String serviceName, int type) { 3449d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu inCallServiceInfos.add(new TelecomLogClass.InCallServiceInfo() 3459d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu .setInCallServiceName(serviceName) 3469d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu .setInCallServiceType(type)); 3479d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu } 3489d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu 3499d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu @Override 350d7fe686253f2135a948cafc776aa25db645ec27eHall Liu public void addCallProperties(int properties) { 351d7fe686253f2135a948cafc776aa25db645ec27eHall Liu this.callProperties |= properties; 352d7fe686253f2135a948cafc776aa25db645ec27eHall Liu } 353d7fe686253f2135a948cafc776aa25db645ec27eHall Liu 354d7fe686253f2135a948cafc776aa25db645ec27eHall Liu @Override 3553258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public String toString() { 3563258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return "{\n" 3573258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " startTime: " + startTime + '\n' 3583258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " endTime: " + endTime + '\n' 3593258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " direction: " + getCallDirectionString() + '\n' 3603258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " isAdditionalCall: " + isAdditionalCall + '\n' 3613258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " isInterrupted: " + isInterrupted + '\n' 3623258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " callTechnologies: " + getCallTechnologiesAsString() + '\n' 3633258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + " callTerminationReason: " + getCallDisconnectReasonString() + '\n' 364ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu + " connectionService: " + connectionService + '\n' 3654640c4fc55ca4118351330d68684ca9989661ccdHall Liu + " isVideoCall: " + isVideo + '\n' 3669d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu + " inCallServices: " + getInCallServicesString() + '\n' 367d7fe686253f2135a948cafc776aa25db645ec27eHall Liu + " callProperties: " + Connection.propertiesToStringShort(callProperties) 368d7fe686253f2135a948cafc776aa25db645ec27eHall Liu + '\n' 3693258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu + "}\n"; 3703258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 3713258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 372ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public ParcelableCallAnalytics toParcelableAnalytics() { 3732f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu TelecomLogClass.CallLog analyticsProto = toProto(); 3742f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu List<ParcelableCallAnalytics.AnalyticsEvent> events = 3752f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu Arrays.stream(analyticsProto.callEvents) 3762f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .map(callEventProto -> new ParcelableCallAnalytics.AnalyticsEvent( 3772f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu callEventProto.getEventName(), 3782f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu callEventProto.getTimeSinceLastEventMillis()) 3792f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu ).collect(Collectors.toList()); 3802f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 3812f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu List<ParcelableCallAnalytics.EventTiming> timings = 3822f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu Arrays.stream(analyticsProto.callTimings) 3832f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .map(callTimingProto -> new ParcelableCallAnalytics.EventTiming( 3842f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu callTimingProto.getTimingName(), 3852f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu callTimingProto.getTimeMillis()) 3862f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu ).collect(Collectors.toList()); 3872f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 3882f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu ParcelableCallAnalytics result = new ParcelableCallAnalytics( 3892f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu // rounds down to nearest 5 minute mark 3902f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getStartTime5Min(), 3912f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getCallDurationMillis(), 3922f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getType(), 3932f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getIsAdditionalCall(), 3942f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getIsInterrupted(), 3952f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getCallTechnologies(), 3962f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getCallTerminationCode(), 3972f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getIsEmergencyCall(), 3982f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.connectionService[0], 3992f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu analyticsProto.getIsCreatedFromExistingConnection(), 4002f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu events, 4012f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu timings); 4022f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 4032f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.setIsVideoCall(analyticsProto.getIsVideoCall()); 4042f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.setVideoEvents(Arrays.stream(analyticsProto.videoEvents) 4052f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .map(videoEventProto -> new ParcelableCallAnalytics.VideoEvent( 4062f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu videoEventProto.getEventName(), 4072f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu videoEventProto.getTimeSinceLastEventMillis(), 4082f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu videoEventProto.getVideoState()) 4092f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu ).collect(Collectors.toList())); 4102f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 4112f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu return result; 4122f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu } 4132f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 4142f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu public TelecomLogClass.CallLog toProto() { 4152f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu TelecomLogClass.CallLog result = new TelecomLogClass.CallLog(); 4162f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.setStartTime5Min( 4172f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu startTime - startTime % ParcelableCallAnalytics.MILLIS_IN_5_MINUTES); 4182f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 419ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu // Rounds up to the nearest second. 4200bd869ca557dc11950be3e967e7bcc3abf0ca729Hall Liu long callDuration = (endTime == 0 || startTime == 0) ? 0 : endTime - startTime; 421ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu callDuration += (callDuration % MILLIS_IN_1_SECOND == 0) ? 422ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu 0 : (MILLIS_IN_1_SECOND - callDuration % MILLIS_IN_1_SECOND); 4232f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.setCallDurationMillis(callDuration); 4242f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 4252f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.setType(callDirection) 4262f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setIsAdditionalCall(isAdditionalCall) 4272f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setIsInterrupted(isInterrupted) 4282f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setCallTechnologies(callTechnologies) 4292f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setCallTerminationCode( 4302f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu callTerminationReason == null ? 4312f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu ParcelableCallAnalytics.STILL_CONNECTED : 4322f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu callTerminationReason.getCode()) 4332f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setIsEmergencyCall(isEmergency) 4342f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setIsCreatedFromExistingConnection(createdFromExistingConnection) 4352f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setIsEmergencyCall(isEmergency) 436d7fe686253f2135a948cafc776aa25db645ec27eHall Liu .setIsVideoCall(isVideo) 437d7fe686253f2135a948cafc776aa25db645ec27eHall Liu .setConnectionProperties(callProperties); 4382f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 4392f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.connectionService = new String[] {connectionService}; 440874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu if (callEvents != null) { 4412f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.callEvents = convertLogEventsToProtoEvents(callEvents.getEvents()); 4422f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.callTimings = callEvents.extractEventTimings().stream() 4432f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .map(Analytics::logEventTimingToProtoEventTiming) 4442f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .toArray(TelecomLogClass.EventTimingEntry[]::new); 445874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 4462f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.videoEvents = 4472f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu videoEvents.toArray(new TelecomLogClass.VideoEvent[videoEvents.size()]); 4489d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu result.inCallServices = inCallServiceInfos.toArray( 4499d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu new TelecomLogClass.InCallServiceInfo[inCallServiceInfos.size()]); 4509d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu 4514640c4fc55ca4118351330d68684ca9989661ccdHall Liu return result; 452ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu } 453ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu 4543258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu private String getCallDirectionString() { 4553258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu switch (callDirection) { 4563258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu case UNKNOWN_DIRECTION: 4573258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return "UNKNOWN"; 4583258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu case INCOMING_DIRECTION: 4593258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return "INCOMING"; 4603258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu case OUTGOING_DIRECTION: 4613258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return "OUTGOING"; 4623258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu default: 4633258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return "UNKNOWN"; 4643258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 4653258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 4663258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 4673258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu private String getCallTechnologiesAsString() { 4683258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu StringBuilder s = new StringBuilder(); 4693258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu s.append('['); 4703258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if ((callTechnologies & CDMA_PHONE) != 0) s.append("CDMA "); 4713258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if ((callTechnologies & GSM_PHONE) != 0) s.append("GSM "); 4723258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if ((callTechnologies & SIP_PHONE) != 0) s.append("SIP "); 4733258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if ((callTechnologies & IMS_PHONE) != 0) s.append("IMS "); 4743258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if ((callTechnologies & THIRD_PARTY_PHONE) != 0) s.append("THIRD_PARTY "); 4753258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu s.append(']'); 4763258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return s.toString(); 4773258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 4783258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 4793258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu private String getCallDisconnectReasonString() { 4803258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu if (callTerminationReason != null) { 4813258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return callTerminationReason.toString(); 4823258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } else { 4833258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return "NOT SET"; 4843258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 4853258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 4869d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu 4879d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu private String getInCallServicesString() { 4889d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu StringBuilder s = new StringBuilder(); 4899d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append("[\n"); 4909d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu for (TelecomLogClass.InCallServiceInfo service : inCallServiceInfos) { 4919d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append(" "); 4929d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append("name: "); 4939d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append(service.getInCallServiceName()); 4949d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append(" type: "); 4959d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append(service.getInCallServiceType()); 4969d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append("\n"); 4979d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu } 4989d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu s.append("]"); 4999d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu return s.toString(); 5009d15ca4316bb3a89bba11b62d2e17e2fb80fdc74Hall Liu } 5013258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 5023258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public static final String TAG = "TelecomAnalytics"; 5033258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 5043258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // Constants for call direction 505ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int UNKNOWN_DIRECTION = ParcelableCallAnalytics.CALLTYPE_UNKNOWN; 506ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int INCOMING_DIRECTION = ParcelableCallAnalytics.CALLTYPE_INCOMING; 507ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int OUTGOING_DIRECTION = ParcelableCallAnalytics.CALLTYPE_OUTGOING; 5083258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 5093258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu // Constants for call technology 510ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int CDMA_PHONE = ParcelableCallAnalytics.CDMA_PHONE; 511ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int GSM_PHONE = ParcelableCallAnalytics.GSM_PHONE; 512ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int IMS_PHONE = ParcelableCallAnalytics.IMS_PHONE; 513ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int SIP_PHONE = ParcelableCallAnalytics.SIP_PHONE; 514ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final int THIRD_PARTY_PHONE = ParcelableCallAnalytics.THIRD_PARTY_PHONE; 515ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu 5164640c4fc55ca4118351330d68684ca9989661ccdHall Liu // Constants for video events 5174640c4fc55ca4118351330d68684ca9989661ccdHall Liu public static final int SEND_LOCAL_SESSION_MODIFY_REQUEST = 5184640c4fc55ca4118351330d68684ca9989661ccdHall Liu ParcelableCallAnalytics.VideoEvent.SEND_LOCAL_SESSION_MODIFY_REQUEST; 5194640c4fc55ca4118351330d68684ca9989661ccdHall Liu public static final int SEND_LOCAL_SESSION_MODIFY_RESPONSE = 5204640c4fc55ca4118351330d68684ca9989661ccdHall Liu ParcelableCallAnalytics.VideoEvent.SEND_LOCAL_SESSION_MODIFY_RESPONSE; 5214640c4fc55ca4118351330d68684ca9989661ccdHall Liu public static final int RECEIVE_REMOTE_SESSION_MODIFY_REQUEST = 5224640c4fc55ca4118351330d68684ca9989661ccdHall Liu ParcelableCallAnalytics.VideoEvent.RECEIVE_REMOTE_SESSION_MODIFY_REQUEST; 5234640c4fc55ca4118351330d68684ca9989661ccdHall Liu public static final int RECEIVE_REMOTE_SESSION_MODIFY_RESPONSE = 5244640c4fc55ca4118351330d68684ca9989661ccdHall Liu ParcelableCallAnalytics.VideoEvent.RECEIVE_REMOTE_SESSION_MODIFY_RESPONSE; 5254640c4fc55ca4118351330d68684ca9989661ccdHall Liu 526ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu public static final long MILLIS_IN_1_SECOND = ParcelableCallAnalytics.MILLIS_IN_1_SECOND; 5273258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 5283258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu private static final Object sLock = new Object(); // Coarse lock for all of analytics 5293258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu private static final Map<String, CallInfoImpl> sCallIdToInfo = new HashMap<>(); 530874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu private static final List<SessionTiming> sSessionTimings = new LinkedList<>(); 531874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 532874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static void addSessionTiming(String sessionName, long time) { 533874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu if (sLogSessionToSessionId.containsKey(sessionName)) { 534874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu synchronized (sLock) { 535874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sSessionTimings.add(new SessionTiming(sLogSessionToSessionId.get(sessionName), 536874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu time)); 537874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 538874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 539874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 5403258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 5413258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public static CallInfo initiateCallAnalytics(String callId, int direction) { 5423258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Log.d(TAG, "Starting analytics for call " + callId); 5433258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu CallInfoImpl callInfo = new CallInfoImpl(callId, direction); 5443258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu synchronized (sLock) { 5453258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu sCallIdToInfo.put(callId, callInfo); 5463258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 5473258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return callInfo; 5483258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 5493258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 550874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static TelecomAnalytics dumpToParcelableAnalytics() { 551874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu List<ParcelableCallAnalytics> calls = new LinkedList<>(); 552874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu List<SessionTiming> sessionTimings = new LinkedList<>(); 553ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu synchronized (sLock) { 554874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu calls.addAll(sCallIdToInfo.values().stream() 555874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu .map(CallInfoImpl::toParcelableAnalytics) 556874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu .collect(Collectors.toList())); 557874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sessionTimings.addAll(sSessionTimings); 558ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu sCallIdToInfo.clear(); 559874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sSessionTimings.clear(); 560ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu } 561874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu return new TelecomAnalytics(sessionTimings, calls); 562ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu } 563ecd74a56dbce2d15ff46ad3e64a16dfe8b6c734fHall Liu 5642f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu public static void dumpToEncodedProto(PrintWriter pw, String[] args) { 5652f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu TelecomLogClass.TelecomLog result = new TelecomLogClass.TelecomLog(); 5662f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 5672f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu synchronized (sLock) { 5682f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.callLogs = sCallIdToInfo.values().stream() 5692f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .map(CallInfoImpl::toProto) 5702f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .toArray(TelecomLogClass.CallLog[]::new); 5712f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu result.sessionTimings = sSessionTimings.stream() 5722f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .map(timing -> new TelecomLogClass.LogSessionTiming() 5732f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setSessionEntryPoint(timing.getKey()) 5742f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setTimeMillis(timing.getTime())) 5752f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .toArray(TelecomLogClass.LogSessionTiming[]::new); 5762f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu if (args.length > 1 && CLEAR_ANALYTICS_ARG.equals(args[1])) { 5772f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu sCallIdToInfo.clear(); 5782f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu sSessionTimings.clear(); 5792f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu } 5802f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu } 5812f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu String encodedProto = Base64.encodeToString( 5822f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu TelecomLogClass.TelecomLog.toByteArray(result), Base64.DEFAULT); 5832f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu pw.write(encodedProto); 5842f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu } 5852f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu 5863258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public static void dump(IndentingPrintWriter writer) { 5873258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu synchronized (sLock) { 588874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu int prefixLength = CallsManager.TELECOM_CALL_ID_PREFIX.length(); 589874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu List<String> callIds = new ArrayList<>(sCallIdToInfo.keySet()); 590874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu // Sort the analytics in increasing order of call IDs 591d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu try { 592d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu Collections.sort(callIds, (id1, id2) -> { 593d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu int i1, i2; 594d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu try { 595d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu i1 = Integer.valueOf(id1.substring(prefixLength)); 596d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu } catch (NumberFormatException e) { 597d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu i1 = Integer.MAX_VALUE; 598d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu } 599d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu 600d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu try { 601d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu i2 = Integer.valueOf(id2.substring(prefixLength)); 602d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu } catch (NumberFormatException e) { 603d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu i2 = Integer.MAX_VALUE; 604d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu } 605d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu return i1 - i2; 606d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu }); 607d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu } catch (IllegalArgumentException e) { 608d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu // do nothing, leave the list in a partially sorted state. 609d7e370d9a0b5fa4b99e8a832ba0b690f0f8fb4beHall Liu } 610874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 611874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu for (String callId : callIds) { 612874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu writer.printf("Call %s: ", callId); 613874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu writer.println(sCallIdToInfo.get(callId).toString()); 6143258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 615874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 616874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu Map<Integer, Double> averageTimings = SessionTiming.averageTimings(sSessionTimings); 617874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu averageTimings.entrySet().stream() 618874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu .filter(e -> sSessionIdToLogSession.containsKey(e.getKey())) 619874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu .forEach(e -> writer.printf("%s: %.2f\n", 620874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sSessionIdToLogSession.get(e.getKey()), e.getValue())); 6213258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 6223258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 6233258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 6243258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public static void reset() { 6253258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu synchronized (sLock) { 6263258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu sCallIdToInfo.clear(); 6273258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 6283258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 6293258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu 6303258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu /** 631874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu * Returns a copy of callIdToInfo. Use only for testing. 6323258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu */ 633874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu @VisibleForTesting 6343258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu public static Map<String, CallInfoImpl> cloneData() { 6353258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu synchronized (sLock) { 6363258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu Map<String, CallInfoImpl> result = new HashMap<>(sCallIdToInfo.size()); 6373258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu for (Map.Entry<String, CallInfoImpl> entry : sCallIdToInfo.entrySet()) { 6383258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu result.put(entry.getKey(), new CallInfoImpl(entry.getValue())); 6393258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 6403258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu return result; 6413258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 6423258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu } 643874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 6442f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu private static TelecomLogClass.Event[] convertLogEventsToProtoEvents( 645a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger List<EventManager.Event> logEvents) { 646874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu long timeOfLastEvent = -1; 6472f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu ArrayList<TelecomLogClass.Event> events = new ArrayList<>(logEvents.size()); 648a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger for (EventManager.Event logEvent : logEvents) { 649874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu if (sLogEventToAnalyticsEvent.containsKey(logEvent.eventId)) { 6502f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu TelecomLogClass.Event event = new TelecomLogClass.Event(); 6512f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu event.setEventName(sLogEventToAnalyticsEvent.get(logEvent.eventId)); 6522f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu event.setTimeSinceLastEventMillis(roundToOneSigFig( 6532f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu timeOfLastEvent < 0 ? -1 : logEvent.time - timeOfLastEvent)); 6542f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu events.add(event); 655874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu timeOfLastEvent = logEvent.time; 656874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 657874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 6582f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu return events.toArray(new TelecomLogClass.Event[events.size()]); 659874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 660874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 6612f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu private static TelecomLogClass.EventTimingEntry logEventTimingToProtoEventTiming( 662a3eccfee788c3ac3c831a443b085b141b39bb63dBrad Ebinger EventManager.EventRecord.EventTiming logEventTiming) { 663874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu int analyticsEventTimingName = 664874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sLogEventTimingToAnalyticsEventTiming.containsKey(logEventTiming.name) ? 665874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu sLogEventTimingToAnalyticsEventTiming.get(logEventTiming.name) : 666874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu ParcelableCallAnalytics.EventTiming.INVALID; 6672f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu return new TelecomLogClass.EventTimingEntry() 6682f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setTimingName(analyticsEventTimingName) 6692f4f0a038dbf9f6372ac8c9b1535f8cc8d0f8256Hall Liu .setTimeMillis(logEventTiming.time); 670874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 671874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu 672874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu @VisibleForTesting 673874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu public static long roundToOneSigFig(long val) { 674874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu if (val == 0) { 675874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu return val; 676874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 677874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu int logVal = (int) Math.floor(Math.log10(val < 0 ? -val : val)); 678874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu double s = Math.pow(10, logVal); 679874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu double dec = val / s; 680874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu return (long) (Math.round(dec) * s); 681874c0f8fa95a5da5a82e67c1fe39697883d753ebHall Liu } 6823258720f5526f766aa26c19cf01b32ac20d19d1dHall Liu} 683