1/*
2 * Copyright (C) 2013 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.phone;
18
19import android.os.AsyncResult;
20import android.os.Handler;
21import android.os.Message;
22import android.os.SystemProperties;
23import android.util.Log;
24
25import com.android.internal.telephony.CallManager;
26
27import java.util.ArrayList;
28import java.util.LinkedList;
29import java.util.List;
30
31
32/**
33 * Dedicated Call state monitoring class.  This class communicates directly with
34 * the call manager to listen for call state events and notifies registered
35 * handlers.
36 * It works as an inverse multiplexor for all classes wanted Call State updates
37 * so that there exists only one channel to the telephony layer.
38 *
39 * TODO: Add manual phone state checks (getState(), etc.).
40 */
41class CallStateMonitor extends Handler {
42    private static final String LOG_TAG = CallStateMonitor.class.getSimpleName();
43    private static final boolean DBG =
44            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
45
46    // Events from the Phone object:
47    public static final int PHONE_STATE_CHANGED = 1;
48    public static final int PHONE_NEW_RINGING_CONNECTION = 2;
49    public static final int PHONE_DISCONNECT = 3;
50    public static final int PHONE_UNKNOWN_CONNECTION_APPEARED = 4;
51    public static final int PHONE_STATE_DISPLAYINFO = 6;
52    public static final int PHONE_STATE_SIGNALINFO = 7;
53    public static final int PHONE_CDMA_CALL_WAITING = 8;
54    public static final int PHONE_ENHANCED_VP_ON = 9;
55    public static final int PHONE_ENHANCED_VP_OFF = 10;
56    public static final int PHONE_RINGBACK_TONE = 11;
57    public static final int PHONE_RESEND_MUTE = 12;
58    public static final int PHONE_ON_DIAL_CHARS = 13;
59    public static final int PHONE_SUPP_SERVICE_FAILED = 14;
60    public static final int PHONE_TTY_MODE_RECEIVED = 15;
61    // Events generated internally.
62    // We should store all the possible event type values in one place to make sure that
63    // they don't step on each others' toes.
64    public static final int INTERNAL_SHOW_MESSAGE_NOTIFICATION_DONE = 22;
65    public static final int INTERNAL_UPDATE_IN_CALL_NOTIFICATION = 23;
66
67    // Other events from call manager
68    public static final int EVENT_OTA_PROVISION_CHANGE = 20;
69
70    private CallManager callManager;
71    private ArrayList<Handler> registeredHandlers;
72
73    // Events generated internally:
74    public CallStateMonitor(CallManager callManager) {
75        this.callManager = callManager;
76        registeredHandlers = new ArrayList<Handler>();
77
78        registerForNotifications();
79    }
80
81    /**
82     * Register for call state notifications with the CallManager.
83     */
84    private void registerForNotifications() {
85        //
86        // TODO: The lines commented out here can be removed as their associated functionality in
87        // other files is removed.
88        //
89        //callManager.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null);
90        //callManager.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null);
91        //callManager.registerForDisconnect(this, PHONE_DISCONNECT, null);
92        //callManager.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null);
93        callManager.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null);
94        //callManager.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null);
95        callManager.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null);
96        callManager.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null);
97        callManager.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null);
98        callManager.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null);
99        callManager.registerForSuppServiceFailed(this, PHONE_SUPP_SERVICE_FAILED, null);
100        //callManager.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null);
101        //callManager.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null);
102        //callManager.registerForPostDialCharacter(this, PHONE_ON_DIAL_CHARS, null);
103        callManager.registerForTtyModeReceived(this, PHONE_TTY_MODE_RECEIVED, null);
104    }
105
106    public void addListener(Handler handler) {
107        if (handler != null && !registeredHandlers.contains(handler)) {
108            if (DBG) {
109                Log.d(LOG_TAG, "Adding Handler: " + handler);
110            }
111
112            registeredHandlers.add(handler);
113        }
114    }
115
116    @Override
117    public void handleMessage(Message msg) {
118        if (DBG) {
119            Log.d(LOG_TAG, "handleMessage(" + msg.what + ")");
120        }
121
122        for (Handler handler : registeredHandlers) {
123            handler.handleMessage(msg);
124        }
125    }
126
127    /**
128     * When radio technology changes, we need to to reregister for all the events which are
129     * all tied to the old radio.
130     */
131    public void updateAfterRadioTechnologyChange() {
132        if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange...");
133
134        // Unregister all events from the old obsolete phone
135        //callManager.unregisterForNewRingingConnection(this);
136        //callManager.unregisterForPreciseCallStateChanged(this);
137        //callManager.unregisterForDisconnect(this);
138        //callManager.unregisterForUnknownConnection(this);
139        //callManager.unregisterForCallWaiting(this);
140        callManager.unregisterForDisplayInfo(this);
141        callManager.unregisterForSignalInfo(this);
142        callManager.unregisterForCdmaOtaStatusChange(this);
143        //callManager.unregisterForRingbackTone(this);
144        //callManager.unregisterForResendIncallMute(this);
145        callManager.unregisterForInCallVoicePrivacyOn(this);
146        callManager.unregisterForInCallVoicePrivacyOff(this);
147        //callManager.unregisterForPostDialCharacter(this);
148        callManager.unregisterForSuppServiceFailed(this);
149        callManager.unregisterForTtyModeReceived(this);
150
151        registerForNotifications();
152    }
153
154}
155