Home | History | Annotate | Download | only in telecom
      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 android.telecom;
     18 
     19 import android.annotation.SystemApi;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 
     23 import java.util.ArrayList;
     24 import java.util.LinkedList;
     25 import java.util.List;
     26 
     27 /**
     28  * @hide
     29  */
     30 @SystemApi
     31 public class ParcelableCallAnalytics implements Parcelable {
     32     /** {@hide} */
     33     public static final class VideoEvent implements Parcelable {
     34         public static final int SEND_LOCAL_SESSION_MODIFY_REQUEST = 0;
     35         public static final int SEND_LOCAL_SESSION_MODIFY_RESPONSE = 1;
     36         public static final int RECEIVE_REMOTE_SESSION_MODIFY_REQUEST = 2;
     37         public static final int RECEIVE_REMOTE_SESSION_MODIFY_RESPONSE = 3;
     38 
     39         public static final @android.annotation.NonNull Parcelable.Creator<VideoEvent> CREATOR =
     40                 new Parcelable.Creator<VideoEvent> () {
     41 
     42                     @Override
     43                     public VideoEvent createFromParcel(Parcel in) {
     44                         return new VideoEvent(in);
     45                     }
     46 
     47                     @Override
     48                     public VideoEvent[] newArray(int size) {
     49                         return new VideoEvent[size];
     50                     }
     51                 };
     52 
     53         private int mEventName;
     54         private long mTimeSinceLastEvent;
     55         private int mVideoState;
     56 
     57         public VideoEvent(int eventName, long timeSinceLastEvent, int videoState) {
     58             mEventName = eventName;
     59             mTimeSinceLastEvent = timeSinceLastEvent;
     60             mVideoState = videoState;
     61         }
     62 
     63         VideoEvent(Parcel in) {
     64             mEventName = in.readInt();
     65             mTimeSinceLastEvent = in.readLong();
     66             mVideoState = in.readInt();
     67         }
     68 
     69         public int getEventName() {
     70             return mEventName;
     71         }
     72 
     73         public long getTimeSinceLastEvent() {
     74             return mTimeSinceLastEvent;
     75         }
     76 
     77         public int getVideoState() {
     78             return mVideoState;
     79         }
     80 
     81         @Override
     82         public int describeContents() {
     83             return 0;
     84         }
     85 
     86         @Override
     87         public void writeToParcel(Parcel out, int flags) {
     88             out.writeInt(mEventName);
     89             out.writeLong(mTimeSinceLastEvent);
     90             out.writeInt(mVideoState);
     91         }
     92     }
     93 
     94     public static final class AnalyticsEvent implements Parcelable {
     95         public static final int SET_SELECT_PHONE_ACCOUNT = 0;
     96         public static final int SET_ACTIVE = 1;
     97         public static final int SET_DISCONNECTED = 2;
     98         public static final int START_CONNECTION = 3;
     99         public static final int SET_DIALING = 4;
    100         public static final int BIND_CS = 5;
    101         public static final int CS_BOUND = 6;
    102         public static final int REQUEST_ACCEPT = 7;
    103         public static final int REQUEST_REJECT = 8;
    104 
    105         public static final int SCREENING_SENT = 100;
    106         public static final int SCREENING_COMPLETED = 101;
    107         public static final int DIRECT_TO_VM_INITIATED = 102;
    108         public static final int DIRECT_TO_VM_FINISHED = 103;
    109         public static final int BLOCK_CHECK_INITIATED = 104;
    110         public static final int BLOCK_CHECK_FINISHED = 105;
    111         public static final int FILTERING_INITIATED = 106;
    112         public static final int FILTERING_COMPLETED = 107;
    113         public static final int FILTERING_TIMED_OUT = 108;
    114 
    115         public static final int SKIP_RINGING = 200;
    116         public static final int SILENCE = 201;
    117         public static final int MUTE = 202;
    118         public static final int UNMUTE = 203;
    119         public static final int AUDIO_ROUTE_BT = 204;
    120         public static final int AUDIO_ROUTE_EARPIECE = 205;
    121         public static final int AUDIO_ROUTE_HEADSET = 206;
    122         public static final int AUDIO_ROUTE_SPEAKER = 207;
    123 
    124         public static final int CONFERENCE_WITH = 300;
    125         public static final int SPLIT_CONFERENCE = 301;
    126         public static final int SET_PARENT = 302;
    127 
    128         public static final int REQUEST_HOLD = 400;
    129         public static final int REQUEST_UNHOLD = 401;
    130         public static final int REMOTELY_HELD = 402;
    131         public static final int REMOTELY_UNHELD = 403;
    132         public static final int SET_HOLD = 404;
    133         public static final int SWAP = 405;
    134 
    135         public static final int REQUEST_PULL = 500;
    136 
    137 
    138         public static final @android.annotation.NonNull Parcelable.Creator<AnalyticsEvent> CREATOR =
    139                 new Parcelable.Creator<AnalyticsEvent> () {
    140 
    141                     @Override
    142                     public AnalyticsEvent createFromParcel(Parcel in) {
    143                         return new AnalyticsEvent(in);
    144                     }
    145 
    146                     @Override
    147                     public AnalyticsEvent[] newArray(int size) {
    148                         return new AnalyticsEvent[size];
    149                     }
    150                 };
    151 
    152         private int mEventName;
    153         private long mTimeSinceLastEvent;
    154 
    155         public AnalyticsEvent(int eventName, long timestamp) {
    156             mEventName = eventName;
    157             mTimeSinceLastEvent = timestamp;
    158         }
    159 
    160         AnalyticsEvent(Parcel in) {
    161             mEventName = in.readInt();
    162             mTimeSinceLastEvent = in.readLong();
    163         }
    164 
    165         public int getEventName() {
    166             return mEventName;
    167         }
    168 
    169         public long getTimeSinceLastEvent() {
    170             return mTimeSinceLastEvent;
    171         }
    172 
    173         @Override
    174         public int describeContents() {
    175             return 0;
    176         }
    177 
    178         @Override
    179         public void writeToParcel(Parcel out, int flags) {
    180             out.writeInt(mEventName);
    181             out.writeLong(mTimeSinceLastEvent);
    182         }
    183     }
    184 
    185     public static final class EventTiming implements Parcelable {
    186         public static final int ACCEPT_TIMING = 0;
    187         public static final int REJECT_TIMING = 1;
    188         public static final int DISCONNECT_TIMING = 2;
    189         public static final int HOLD_TIMING = 3;
    190         public static final int UNHOLD_TIMING = 4;
    191         public static final int OUTGOING_TIME_TO_DIALING_TIMING = 5;
    192         public static final int BIND_CS_TIMING = 6;
    193         public static final int SCREENING_COMPLETED_TIMING = 7;
    194         public static final int DIRECT_TO_VM_FINISHED_TIMING = 8;
    195         public static final int BLOCK_CHECK_FINISHED_TIMING = 9;
    196         public static final int FILTERING_COMPLETED_TIMING = 10;
    197         public static final int FILTERING_TIMED_OUT_TIMING = 11;
    198         /** {@hide} */
    199         public static final int START_CONNECTION_TO_REQUEST_DISCONNECT_TIMING = 12;
    200 
    201         public static final int INVALID = 999999;
    202 
    203         public static final @android.annotation.NonNull Parcelable.Creator<EventTiming> CREATOR =
    204                 new Parcelable.Creator<EventTiming> () {
    205 
    206                     @Override
    207                     public EventTiming createFromParcel(Parcel in) {
    208                         return new EventTiming(in);
    209                     }
    210 
    211                     @Override
    212                     public EventTiming[] newArray(int size) {
    213                         return new EventTiming[size];
    214                     }
    215                 };
    216 
    217         private int mName;
    218         private long mTime;
    219 
    220         public EventTiming(int name, long time) {
    221             this.mName = name;
    222             this.mTime = time;
    223         }
    224 
    225         private EventTiming(Parcel in) {
    226             mName = in.readInt();
    227             mTime = in.readLong();
    228         }
    229 
    230         public int getName() {
    231             return mName;
    232         }
    233 
    234         public long getTime() {
    235             return mTime;
    236         }
    237 
    238         @Override
    239         public int describeContents() {
    240             return 0;
    241         }
    242 
    243         @Override
    244         public void writeToParcel(Parcel out, int flags) {
    245             out.writeInt(mName);
    246             out.writeLong(mTime);
    247         }
    248     }
    249 
    250     public static final int CALLTYPE_UNKNOWN = 0;
    251     public static final int CALLTYPE_INCOMING = 1;
    252     public static final int CALLTYPE_OUTGOING = 2;
    253 
    254     // Constants for call technology
    255     public static final int CDMA_PHONE = 0x1;
    256     public static final int GSM_PHONE = 0x2;
    257     public static final int IMS_PHONE = 0x4;
    258     public static final int SIP_PHONE = 0x8;
    259     public static final int THIRD_PARTY_PHONE = 0x10;
    260 
    261     /**
    262      * Indicating the call source is not specified.
    263      *
    264      * @hide
    265      */
    266     public static final int CALL_SOURCE_UNSPECIFIED = 0;
    267 
    268     /**
    269      * Indicating the call is initiated via emergency dialer's dialpad.
    270      *
    271      * @hide
    272      */
    273     public static final int CALL_SOURCE_EMERGENCY_DIALPAD = 1;
    274 
    275     /**
    276      * Indicating the call is initiated via emergency dialer's shortcut button.
    277      *
    278      * @hide
    279      */
    280     public static final int CALL_SOURCE_EMERGENCY_SHORTCUT = 2;
    281 
    282     public static final long MILLIS_IN_5_MINUTES = 1000 * 60 * 5;
    283     public static final long MILLIS_IN_1_SECOND = 1000;
    284 
    285     public static final int STILL_CONNECTED = -1;
    286 
    287     public static final @android.annotation.NonNull Parcelable.Creator<ParcelableCallAnalytics> CREATOR =
    288             new Parcelable.Creator<ParcelableCallAnalytics> () {
    289 
    290                 @Override
    291                 public ParcelableCallAnalytics createFromParcel(Parcel in) {
    292                     return new ParcelableCallAnalytics(in);
    293                 }
    294 
    295                 @Override
    296                 public ParcelableCallAnalytics[] newArray(int size) {
    297                     return new ParcelableCallAnalytics[size];
    298                 }
    299             };
    300 
    301     // The start time of the call in milliseconds since Jan. 1, 1970, rounded to the nearest
    302     // 5 minute increment.
    303     private final long startTimeMillis;
    304 
    305     // The duration of the call, in milliseconds.
    306     private final long callDurationMillis;
    307 
    308     // ONE OF calltype_unknown, calltype_incoming, or calltype_outgoing
    309     private final int callType;
    310 
    311     // true if the call came in while another call was in progress or if the user dialed this call
    312     // while in the middle of another call.
    313     private final boolean isAdditionalCall;
    314 
    315     // true if the call was interrupted by an incoming or outgoing call.
    316     private final boolean isInterrupted;
    317 
    318     // bitmask denoting which technologies a call used.
    319     private final int callTechnologies;
    320 
    321     // Any of the DisconnectCause codes, or STILL_CONNECTED.
    322     private final int callTerminationCode;
    323 
    324     // Whether the call is an emergency call
    325     private final boolean isEmergencyCall;
    326 
    327     // The package name of the connection service that this call used.
    328     private final String connectionService;
    329 
    330     // Whether the call object was created from an existing connection.
    331     private final boolean isCreatedFromExistingConnection;
    332 
    333     // A list of events that are associated with this call
    334     private final List<AnalyticsEvent> analyticsEvents;
    335 
    336     // A map from event-pair names to their durations.
    337     private final List<EventTiming> eventTimings;
    338 
    339     // Whether the call has ever been a video call.
    340     private boolean isVideoCall = false;
    341 
    342     // A list of video events that have occurred.
    343     private List<VideoEvent> videoEvents;
    344 
    345     // The source where user initiated this call. ONE OF the CALL_SOURCE_* constants.
    346     private int callSource = CALL_SOURCE_UNSPECIFIED;
    347 
    348     public ParcelableCallAnalytics(long startTimeMillis, long callDurationMillis, int callType,
    349             boolean isAdditionalCall, boolean isInterrupted, int callTechnologies,
    350             int callTerminationCode, boolean isEmergencyCall, String connectionService,
    351             boolean isCreatedFromExistingConnection, List<AnalyticsEvent> analyticsEvents,
    352             List<EventTiming> eventTimings) {
    353         this.startTimeMillis = startTimeMillis;
    354         this.callDurationMillis = callDurationMillis;
    355         this.callType = callType;
    356         this.isAdditionalCall = isAdditionalCall;
    357         this.isInterrupted = isInterrupted;
    358         this.callTechnologies = callTechnologies;
    359         this.callTerminationCode = callTerminationCode;
    360         this.isEmergencyCall = isEmergencyCall;
    361         this.connectionService = connectionService;
    362         this.isCreatedFromExistingConnection = isCreatedFromExistingConnection;
    363         this.analyticsEvents = analyticsEvents;
    364         this.eventTimings = eventTimings;
    365     }
    366 
    367     public ParcelableCallAnalytics(Parcel in) {
    368         startTimeMillis = in.readLong();
    369         callDurationMillis = in.readLong();
    370         callType = in.readInt();
    371         isAdditionalCall = readByteAsBoolean(in);
    372         isInterrupted = readByteAsBoolean(in);
    373         callTechnologies = in.readInt();
    374         callTerminationCode = in.readInt();
    375         isEmergencyCall = readByteAsBoolean(in);
    376         connectionService = in.readString();
    377         isCreatedFromExistingConnection = readByteAsBoolean(in);
    378         analyticsEvents = new ArrayList<>();
    379         in.readTypedList(analyticsEvents, AnalyticsEvent.CREATOR);
    380         eventTimings = new ArrayList<>();
    381         in.readTypedList(eventTimings, EventTiming.CREATOR);
    382         isVideoCall = readByteAsBoolean(in);
    383         videoEvents = new LinkedList<>();
    384         in.readTypedList(videoEvents, VideoEvent.CREATOR);
    385         callSource = in.readInt();
    386     }
    387 
    388     public void writeToParcel(Parcel out, int flags) {
    389         out.writeLong(startTimeMillis);
    390         out.writeLong(callDurationMillis);
    391         out.writeInt(callType);
    392         writeBooleanAsByte(out, isAdditionalCall);
    393         writeBooleanAsByte(out, isInterrupted);
    394         out.writeInt(callTechnologies);
    395         out.writeInt(callTerminationCode);
    396         writeBooleanAsByte(out, isEmergencyCall);
    397         out.writeString(connectionService);
    398         writeBooleanAsByte(out, isCreatedFromExistingConnection);
    399         out.writeTypedList(analyticsEvents);
    400         out.writeTypedList(eventTimings);
    401         writeBooleanAsByte(out, isVideoCall);
    402         out.writeTypedList(videoEvents);
    403         out.writeInt(callSource);
    404     }
    405 
    406     /** {@hide} */
    407     public void setIsVideoCall(boolean isVideoCall) {
    408         this.isVideoCall = isVideoCall;
    409     }
    410 
    411     /** {@hide} */
    412     public void setVideoEvents(List<VideoEvent> videoEvents) {
    413         this.videoEvents = videoEvents;
    414     }
    415 
    416     /** {@hide} */
    417     public void setCallSource(int callSource) {
    418         this.callSource = callSource;
    419     }
    420 
    421     public long getStartTimeMillis() {
    422         return startTimeMillis;
    423     }
    424 
    425     public long getCallDurationMillis() {
    426         return callDurationMillis;
    427     }
    428 
    429     public int getCallType() {
    430         return callType;
    431     }
    432 
    433     public boolean isAdditionalCall() {
    434         return isAdditionalCall;
    435     }
    436 
    437     public boolean isInterrupted() {
    438         return isInterrupted;
    439     }
    440 
    441     public int getCallTechnologies() {
    442         return callTechnologies;
    443     }
    444 
    445     public int getCallTerminationCode() {
    446         return callTerminationCode;
    447     }
    448 
    449     public boolean isEmergencyCall() {
    450         return isEmergencyCall;
    451     }
    452 
    453     public String getConnectionService() {
    454         return connectionService;
    455     }
    456 
    457     public boolean isCreatedFromExistingConnection() {
    458         return isCreatedFromExistingConnection;
    459     }
    460 
    461     public List<AnalyticsEvent> analyticsEvents() {
    462         return analyticsEvents;
    463     }
    464 
    465     public List<EventTiming> getEventTimings() {
    466         return eventTimings;
    467     }
    468 
    469     /** {@hide} */
    470     public boolean isVideoCall() {
    471         return isVideoCall;
    472     }
    473 
    474     /** {@hide} */
    475     public List<VideoEvent> getVideoEvents() {
    476         return videoEvents;
    477     }
    478 
    479     /** {@hide} */
    480     public int getCallSource() {
    481         return callSource;
    482     }
    483 
    484     @Override
    485     public int describeContents() {
    486         return 0;
    487     }
    488 
    489     private static void writeBooleanAsByte(Parcel out, boolean b) {
    490         out.writeByte((byte) (b ? 1 : 0));
    491     }
    492 
    493     private static boolean readByteAsBoolean(Parcel in) {
    494         return (in.readByte() == 1);
    495     }
    496 }
    497