Migrating PhoneInterface (Irrigation and SpeakerLocator) from old to new Nexus 5X...
[iot2.git] / benchmarks / other / PhoneInterface / SpeakerLocator / app / src / main / java / com / example / xub3 / speakerlocator / PhonecallReceiver.java
1 package com.example.xub3.speakerlocator;
2
3 /**
4  * Created by xub3 on 4/14/16.
5  */
6 import java.util.Date;
7
8 import android.content.BroadcastReceiver;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.telephony.TelephonyManager;
12
13 public abstract class PhonecallReceiver extends BroadcastReceiver {
14
15         //The receiver will be recreated whenever android feels like it.  We need a static variable to remember data between instantiations
16
17         private static int lastState = TelephonyManager.CALL_STATE_IDLE;
18         private static Date callStartTime;
19         private static boolean isIncoming;
20         private static String savedNumber;
21         protected Helper helper = MainActivity.helper;
22         //because the passed incoming is only valid in ringing
23
24
25         @Override
26         public void onReceive(Context context, Intent intent) {
27                 //We listen to two intents.  The new outgoing call only tells us of an outgoing call.  We use it to get the number.
28                 if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
29                         savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
30                 } else {
31                         String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
32                         String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
33                         int state = 0;
34                         if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
35                                 state = TelephonyManager.CALL_STATE_IDLE;
36                         } else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
37                                 state = TelephonyManager.CALL_STATE_OFFHOOK;
38                         } else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
39                                 state = TelephonyManager.CALL_STATE_RINGING;
40                         }
41
42
43                         onCallStateChanged(context, state, number);
44                 }
45         }
46
47         //Derived classes should override these to respond to specific events of interest
48         protected abstract void onIncomingCallReceived(Context ctx, String number, Date start);
49         protected abstract void onIncomingCallAnswered(Context ctx, String number, Date start);
50         protected abstract void onIncomingCallEnded(Context ctx, String number, Date start, Date end);
51
52         protected abstract void onOutgoingCallStarted(Context ctx, String number, Date start);
53         protected abstract void onOutgoingCallEnded(Context ctx, String number, Date start, Date end);
54
55         protected abstract void onMissedCall(Context ctx, String number, Date start);
56
57         //Deals with actual events
58
59         //Incoming call-  goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
60         //Outgoing call-  goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
61         public void onCallStateChanged(Context context, int state, String number) {
62                 if(lastState == state) {
63                         //No change, debounce extras
64                         return;
65                 }
66                 switch (state) {
67                 case TelephonyManager.CALL_STATE_RINGING:
68                         isIncoming = true;
69                         callStartTime = new Date();
70                         savedNumber = number;
71                         onIncomingCallReceived(context, number, callStartTime);
72                         break;
73
74                 case TelephonyManager.CALL_STATE_OFFHOOK:
75                         //Transition of ringing->offhook are pickups of incoming calls.  Nothing done on them
76                         if(lastState != TelephonyManager.CALL_STATE_RINGING) {
77                                 isIncoming = false;
78                                 callStartTime = new Date();
79                                 onOutgoingCallStarted(context, savedNumber, callStartTime);
80                         } else
81                         {
82                                 isIncoming = true;
83                                 callStartTime = new Date();
84                                 onIncomingCallAnswered(context, savedNumber, callStartTime);
85                         }
86
87                         break;
88
89                 case TelephonyManager.CALL_STATE_IDLE:
90                         //Went to idle-  this is the end of a call.  What type depends on previous state(s)
91                         if(lastState == TelephonyManager.CALL_STATE_RINGING) {
92                                 //Ring but no pickup-  a miss
93                                 onMissedCall(context, savedNumber, callStartTime);
94                         } else if(isIncoming) {
95                                 onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
96                         } else {
97                                 onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
98                         }
99                         break;
100                 }
101                 lastState = state;
102         }
103 }