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
17package com.android.internal.telephony.metrics;
18
19import android.os.SystemClock;
20
21import com.android.internal.telephony.TelephonyProto.SmsSession;
22
23import java.util.ArrayDeque;
24import java.util.Deque;
25import java.util.concurrent.atomic.AtomicInteger;
26
27/** The ongoing SMS session */
28public class InProgressSmsSession {
29
30    /** Maximum events stored in the session */
31    private static final int MAX_EVENTS = 20;
32
33    /** Phone id */
34    public final int phoneId;
35
36    /** SMS session events */
37    public final Deque<SmsSession.Event> events;
38
39    /** Sms session starting system time in minute */
40    public final int startSystemTimeMin;
41
42    /** Sms session starting elapsed time in milliseconds */
43    public final long startElapsedTimeMs;
44
45    /** The last event's time */
46    private long mLastElapsedTimeMs;
47
48    /** Indicating events dropped */
49    private boolean mEventsDropped = false;
50
51    /** The expected SMS response #. One session could contain multiple SMS requests/responses. */
52    private AtomicInteger mNumExpectedResponses = new AtomicInteger(0);
53
54    /** Increase the expected response # */
55    public void increaseExpectedResponse() {
56        mNumExpectedResponses.incrementAndGet();
57    }
58
59    /** Decrease the expected response # */
60    public void decreaseExpectedResponse() {
61        mNumExpectedResponses.decrementAndGet();
62    }
63
64    /** Get the expected response # */
65    public int getNumExpectedResponses() {
66        return mNumExpectedResponses.get();
67    }
68
69    /** Check if events dropped */
70    public boolean isEventsDropped() { return mEventsDropped; }
71
72    /**
73     * Constructor
74     *
75     * @param phoneId Phone id
76     */
77    public InProgressSmsSession(int phoneId) {
78        this.phoneId = phoneId;
79        events = new ArrayDeque<>();
80        // Save session start with lowered precision due to the privacy requirements
81        startSystemTimeMin = TelephonyMetrics.roundSessionStart(System.currentTimeMillis());
82        startElapsedTimeMs = SystemClock.elapsedRealtime();
83        mLastElapsedTimeMs = startElapsedTimeMs;
84    }
85
86    /**
87     * Add event
88     *
89     * @param builder Event builder
90     */
91    public void addEvent(SmsSessionEventBuilder builder) {
92        addEvent(SystemClock.elapsedRealtime(), builder);
93    }
94
95    /**
96     * Add event
97     *
98     * @param timestamp Timestamp to be recoded with the event
99     * @param builder Event builder
100     */
101    public synchronized void addEvent(long timestamp, SmsSessionEventBuilder builder) {
102        if (events.size() >= MAX_EVENTS) {
103            events.removeFirst();
104            mEventsDropped = true;
105        }
106
107        builder.setDelay(TelephonyMetrics.toPrivacyFuzzedTimeInterval(
108                mLastElapsedTimeMs, timestamp));
109
110        events.add(builder.build());
111        mLastElapsedTimeMs = timestamp;
112    }
113}
114