1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony.metrics;
18 
19 import android.os.SystemClock;
20 
21 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession;
22 
23 import java.util.ArrayDeque;
24 import java.util.Deque;
25 
26 /** The ongoing Call session */
27 public class InProgressCallSession {
28 
29     /** Maximum events stored in the session */
30     private static final int MAX_EVENTS = 300;
31 
32     /** Phone id */
33     public final int phoneId;
34 
35     /** Call session events */
36     public final Deque<TelephonyCallSession.Event> events;
37 
38     /** Call session starting system time in minute */
39     public final int startSystemTimeMin;
40 
41     /** Call session starting elapsed time in milliseconds */
42     public final long startElapsedTimeMs;
43 
44     /** The last event's time */
45     private long mLastElapsedTimeMs;
46 
47     /** Indicating events dropped */
48     private boolean mEventsDropped = false;
49 
50     /** Last known phone state */
51     private int mLastKnownPhoneState;
52 
53     /** Check if events dropped */
isEventsDropped()54     public boolean isEventsDropped() { return mEventsDropped; }
55 
56     /**
57      * Constructor
58      *
59      * @param phoneId Phone id
60      */
InProgressCallSession(int phoneId)61     public InProgressCallSession(int phoneId) {
62         this.phoneId = phoneId;
63         events = new ArrayDeque<>();
64         // Save session start with lowered precision due to the privacy requirements
65         startSystemTimeMin = TelephonyMetrics.roundSessionStart(System.currentTimeMillis());
66         startElapsedTimeMs = SystemClock.elapsedRealtime();
67         mLastElapsedTimeMs = startElapsedTimeMs;
68     }
69 
70     /**
71      * Add event
72      *
73      * @param builder Event builder
74      */
addEvent(CallSessionEventBuilder builder)75     public void addEvent(CallSessionEventBuilder builder) {
76         addEvent(SystemClock.elapsedRealtime(), builder);
77     }
78 
79     /**
80      * Add event
81      *
82      * @param timestamp Timestamp to be recoded with the event
83      * @param builder Event builder
84      */
addEvent(long timestamp, CallSessionEventBuilder builder)85     synchronized public void addEvent(long timestamp, CallSessionEventBuilder builder) {
86         if (events.size() >= MAX_EVENTS) {
87             events.removeFirst();
88             mEventsDropped = true;
89         }
90 
91         builder.setDelay(TelephonyMetrics.toPrivacyFuzzedTimeInterval(
92                 mLastElapsedTimeMs, timestamp));
93 
94         events.add(builder.build());
95         mLastElapsedTimeMs = timestamp;
96     }
97 
98     /**
99      * Check if the Call Session contains CS calls
100      * @return true if there are CS calls in the call list
101      */
containsCsCalls()102     public boolean containsCsCalls() {
103         for (TelephonyCallSession.Event event : events) {
104             if (event.type == TelephonyCallSession.Event.Type.RIL_CALL_LIST_CHANGED) {
105                 return true;
106             }
107         }
108         return false;
109     }
110 
111     /**
112      * Set Phone State
113      * @param state
114      */
setLastKnownPhoneState(int state)115     public void setLastKnownPhoneState(int state) {
116         mLastKnownPhoneState = state;
117     }
118 
119     /**
120      * Checks if Phone is in Idle state
121      * @return true if device is in Phone is idle state.
122      *
123      */
isPhoneIdle()124     public boolean isPhoneIdle() {
125         return (mLastKnownPhoneState == TelephonyCallSession.Event.PhoneState.STATE_IDLE);
126     }
127 }
128