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.SmsSession; 22 23 import java.util.ArrayDeque; 24 import java.util.Deque; 25 import java.util.concurrent.atomic.AtomicInteger; 26 27 /** The ongoing SMS session */ 28 public 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 # */ increaseExpectedResponse()55 public void increaseExpectedResponse() { 56 mNumExpectedResponses.incrementAndGet(); 57 } 58 59 /** Decrease the expected response # */ decreaseExpectedResponse()60 public void decreaseExpectedResponse() { 61 mNumExpectedResponses.decrementAndGet(); 62 } 63 64 /** Get the expected response # */ getNumExpectedResponses()65 public int getNumExpectedResponses() { 66 return mNumExpectedResponses.get(); 67 } 68 69 /** Check if events dropped */ isEventsDropped()70 public boolean isEventsDropped() { return mEventsDropped; } 71 72 /** 73 * Constructor 74 * 75 * @param phoneId Phone id 76 */ InProgressSmsSession(int phoneId)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 */ addEvent(SmsSessionEventBuilder builder)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 */ addEvent(long timestamp, SmsSessionEventBuilder builder)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