DefaultPhoneNotifier.java revision 1fc8906caa9ee879f0343dd3a120cde6d695798b
1/*
2 * Copyright (C) 2006 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;
18
19import android.net.LinkProperties;
20import android.net.NetworkCapabilities;
21import android.os.Bundle;
22import android.os.RemoteException;
23import android.os.ServiceManager;
24import android.telephony.CellInfo;
25import android.telephony.DataConnectionRealTimeInfo;
26import android.telephony.Rlog;
27import android.telephony.VoLteServiceState;
28import android.telephony.ServiceState;
29import android.telephony.SubscriptionManager;
30import android.telephony.TelephonyManager;
31import android.telephony.PreciseCallState;
32import android.telephony.DisconnectCause;
33
34import com.android.internal.telephony.Call;
35import com.android.internal.telephony.CallManager;
36import com.android.internal.telephony.Phone;
37import com.android.internal.telephony.ITelephonyRegistry;
38import com.android.internal.telephony.PhoneConstants;
39
40import java.util.List;
41
42/**
43 * broadcast intents
44 */
45public class DefaultPhoneNotifier implements PhoneNotifier {
46    private static final String LOG_TAG = "DefaultPhoneNotifier";
47    private static final boolean DBG = false; // STOPSHIP if true
48
49    protected ITelephonyRegistry mRegistry;
50
51    /*package*/
52    protected DefaultPhoneNotifier() {
53        mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
54                    "telephony.registry"));
55    }
56
57    @Override
58    public void notifyPhoneState(Phone sender) {
59        Call ringingCall = sender.getRingingCall();
60        long subId = sender.getSubId();
61        String incomingNumber = "";
62        if (ringingCall != null && ringingCall.getEarliestConnection() != null){
63            incomingNumber = ringingCall.getEarliestConnection().getAddress();
64        }
65        try {
66            if (mRegistry != null) {
67                  mRegistry.notifyCallStateForSubscriber(subId,
68                        convertCallState(sender.getState()), incomingNumber);
69            }
70        } catch (RemoteException ex) {
71            // system process is dead
72        }
73    }
74
75    @Override
76    public void notifyServiceState(Phone sender) {
77        ServiceState ss = sender.getServiceState();
78        int phoneId = sender.getPhoneId();
79        long subId = sender.getSubId();
80
81        Rlog.d(LOG_TAG, "nofityServiceState: mRegistry=" + mRegistry + " ss=" + ss
82                + " sender=" + sender + " phondId=" + phoneId + " subId=" + subId);
83        if (ss == null) {
84            ss = new ServiceState();
85            ss.setStateOutOfService();
86        }
87        try {
88            if (mRegistry != null) {
89                mRegistry.notifyServiceStateForPhoneId(phoneId, subId, ss);
90            }
91        } catch (RemoteException ex) {
92            // system process is dead
93        }
94    }
95
96    @Override
97    public void notifySignalStrength(Phone sender) {
98        long subId = sender.getSubId();
99        Rlog.d(LOG_TAG, "notifySignalStrength: mRegistry=" + mRegistry
100                + " ss=" + sender.getSignalStrength() + " sender=" + sender);
101        try {
102            if (mRegistry != null) {
103                mRegistry.notifySignalStrengthForSubscriber(subId, sender.getSignalStrength());
104            }
105        } catch (RemoteException ex) {
106            // system process is dead
107        }
108    }
109
110    @Override
111    public void notifyMessageWaitingChanged(Phone sender) {
112        int phoneId = sender.getPhoneId();
113        long subId = sender.getSubId();
114
115        try {
116            if (mRegistry != null) {
117                mRegistry.notifyMessageWaitingChangedForPhoneId(phoneId, subId,
118                        sender.getMessageWaitingIndicator());
119            }
120        } catch (RemoteException ex) {
121            // system process is dead
122        }
123    }
124
125    @Override
126    public void notifyCallForwardingChanged(Phone sender) {
127        long subId = sender.getSubId();
128        try {
129            if (mRegistry != null) {
130                mRegistry.notifyCallForwardingChangedForSubscriber(subId,
131                        sender.getCallForwardingIndicator());
132            }
133        } catch (RemoteException ex) {
134            // system process is dead
135        }
136    }
137
138    @Override
139    public void notifyDataActivity(Phone sender) {
140        long subId = sender.getSubId();
141        try {
142            if (mRegistry != null) {
143                mRegistry.notifyDataActivityForSubscriber(subId,
144                        convertDataActivityState(sender.getDataActivityState()));
145            }
146        } catch (RemoteException ex) {
147            // system process is dead
148        }
149    }
150
151    @Override
152    public void notifyDataConnection(Phone sender, String reason, String apnType,
153            PhoneConstants.DataState state) {
154        doNotifyDataConnection(sender, reason, apnType, state);
155    }
156
157    private void doNotifyDataConnection(Phone sender, String reason, String apnType,
158            PhoneConstants.DataState state) {
159        long subId = sender.getSubId();
160        long dds = SubscriptionManager.getDefaultDataSubId();
161        if (DBG) log("subId = " + subId + ", DDS = " + dds);
162
163        // TODO
164        // use apnType as the key to which connection we're talking about.
165        // pass apnType back up to fetch particular for this one.
166        TelephonyManager telephony = TelephonyManager.getDefault();
167        LinkProperties linkProperties = null;
168        NetworkCapabilities networkCapabilities = null;
169        boolean roaming = false;
170
171        if (state == PhoneConstants.DataState.CONNECTED) {
172            linkProperties = sender.getLinkProperties(apnType);
173            networkCapabilities = sender.getNetworkCapabilities(apnType);
174        }
175        ServiceState ss = sender.getServiceState();
176        if (ss != null) roaming = ss.getRoaming();
177
178        try {
179            if (mRegistry != null) {
180                mRegistry.notifyDataConnectionForSubscriber(subId,
181                    convertDataState(state),
182                    sender.isDataConnectivityPossible(apnType), reason,
183                    sender.getActiveApnHost(apnType),
184                    apnType,
185                    linkProperties,
186                    networkCapabilities,
187                    ((telephony!=null) ? telephony.getNetworkType() :
188                    TelephonyManager.NETWORK_TYPE_UNKNOWN),
189                    roaming);
190            }
191        } catch (RemoteException ex) {
192            // system process is dead
193        }
194    }
195
196    @Override
197    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
198        long subId = sender.getSubId();
199        try {
200            if (mRegistry != null) {
201                mRegistry.notifyDataConnectionFailedForSubscriber(subId, reason, apnType);
202            }
203        } catch (RemoteException ex) {
204            // system process is dead
205        }
206    }
207
208    @Override
209    public void notifyCellLocation(Phone sender) {
210        long subId = sender.getSubId();
211        Bundle data = new Bundle();
212        sender.getCellLocation().fillInNotifierBundle(data);
213        try {
214            if (mRegistry != null) {
215                mRegistry.notifyCellLocationForSubscriber(subId, data);
216            }
217        } catch (RemoteException ex) {
218            // system process is dead
219        }
220    }
221
222    @Override
223    public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo) {
224        long subId = sender.getSubId();
225        try {
226            if (mRegistry != null) {
227                mRegistry.notifyCellInfoForSubscriber(subId, cellInfo);
228            }
229        } catch (RemoteException ex) {
230
231        }
232    }
233
234    @Override
235    public void notifyDataConnectionRealTimeInfo(Phone sender,
236                                                 DataConnectionRealTimeInfo dcRtInfo) {
237        try {
238            mRegistry.notifyDataConnectionRealTimeInfo(dcRtInfo);
239        } catch (RemoteException ex) {
240
241        }
242    }
243
244    @Override
245    public void notifyOtaspChanged(Phone sender, int otaspMode) {
246        // FIXME: subId?
247        try {
248            if (mRegistry != null) {
249                mRegistry.notifyOtaspChanged(otaspMode);
250            }
251        } catch (RemoteException ex) {
252            // system process is dead
253        }
254    }
255
256    public void notifyPreciseCallState(Phone sender) {
257        // FIXME: subId?
258        Call ringingCall = sender.getRingingCall();
259        Call foregroundCall = sender.getForegroundCall();
260        Call backgroundCall = sender.getBackgroundCall();
261        if (ringingCall != null && foregroundCall != null && backgroundCall != null) {
262            try {
263                mRegistry.notifyPreciseCallState(
264                        convertPreciseCallState(ringingCall.getState()),
265                        convertPreciseCallState(foregroundCall.getState()),
266                        convertPreciseCallState(backgroundCall.getState()));
267            } catch (RemoteException ex) {
268                // system process is dead
269            }
270        }
271    }
272
273    public void notifyDisconnectCause(int cause, int preciseCause) {
274        // FIXME: subId?
275        try {
276            mRegistry.notifyDisconnectCause(cause, preciseCause);
277        } catch (RemoteException ex) {
278            // system process is dead
279        }
280    }
281
282    public void notifyPreciseDataConnectionFailed(Phone sender, String reason, String apnType,
283            String apn, String failCause) {
284        // FIXME: subId?
285        try {
286            mRegistry.notifyPreciseDataConnectionFailed(reason, apnType, apn, failCause);
287        } catch (RemoteException ex) {
288            // system process is dead
289        }
290    }
291
292    @Override
293    public void notifyVoLteServiceStateChanged(Phone sender, VoLteServiceState lteState) {
294        // FIXME: subID
295        try {
296            mRegistry.notifyVoLteServiceStateChanged(lteState);
297        } catch (RemoteException ex) {
298            // system process is dead
299        }
300    }
301
302    /**
303     * Convert the {@link PhoneConstants.State} enum into the TelephonyManager.CALL_STATE_*
304     * constants for the public API.
305     */
306    public static int convertCallState(PhoneConstants.State state) {
307        switch (state) {
308            case RINGING:
309                return TelephonyManager.CALL_STATE_RINGING;
310            case OFFHOOK:
311                return TelephonyManager.CALL_STATE_OFFHOOK;
312            default:
313                return TelephonyManager.CALL_STATE_IDLE;
314        }
315    }
316
317    /**
318     * Convert the TelephonyManager.CALL_STATE_* constants into the
319     * {@link PhoneConstants.State} enum for the public API.
320     */
321    public static PhoneConstants.State convertCallState(int state) {
322        switch (state) {
323            case TelephonyManager.CALL_STATE_RINGING:
324                return PhoneConstants.State.RINGING;
325            case TelephonyManager.CALL_STATE_OFFHOOK:
326                return PhoneConstants.State.OFFHOOK;
327            default:
328                return PhoneConstants.State.IDLE;
329        }
330    }
331
332    /**
333     * Convert the {@link PhoneConstants.DataState} enum into the TelephonyManager.DATA_* constants
334     * for the public API.
335     */
336    public static int convertDataState(PhoneConstants.DataState state) {
337        switch (state) {
338            case CONNECTING:
339                return TelephonyManager.DATA_CONNECTING;
340            case CONNECTED:
341                return TelephonyManager.DATA_CONNECTED;
342            case SUSPENDED:
343                return TelephonyManager.DATA_SUSPENDED;
344            default:
345                return TelephonyManager.DATA_DISCONNECTED;
346        }
347    }
348
349    /**
350     * Convert the TelephonyManager.DATA_* constants into {@link PhoneConstants.DataState} enum
351     * for the public API.
352     */
353    public static PhoneConstants.DataState convertDataState(int state) {
354        switch (state) {
355            case TelephonyManager.DATA_CONNECTING:
356                return PhoneConstants.DataState.CONNECTING;
357            case TelephonyManager.DATA_CONNECTED:
358                return PhoneConstants.DataState.CONNECTED;
359            case TelephonyManager.DATA_SUSPENDED:
360                return PhoneConstants.DataState.SUSPENDED;
361            default:
362                return PhoneConstants.DataState.DISCONNECTED;
363        }
364    }
365
366    /**
367     * Convert the {@link Phone.DataActivityState} enum into the TelephonyManager.DATA_* constants
368     * for the public API.
369     */
370    public static int convertDataActivityState(Phone.DataActivityState state) {
371        switch (state) {
372            case DATAIN:
373                return TelephonyManager.DATA_ACTIVITY_IN;
374            case DATAOUT:
375                return TelephonyManager.DATA_ACTIVITY_OUT;
376            case DATAINANDOUT:
377                return TelephonyManager.DATA_ACTIVITY_INOUT;
378            case DORMANT:
379                return TelephonyManager.DATA_ACTIVITY_DORMANT;
380            default:
381                return TelephonyManager.DATA_ACTIVITY_NONE;
382        }
383    }
384
385    /**
386     * Convert the TelephonyManager.DATA_* constants into the {@link Phone.DataActivityState} enum
387     * for the public API.
388     */
389    public static Phone.DataActivityState convertDataActivityState(int state) {
390        switch (state) {
391            case TelephonyManager.DATA_ACTIVITY_IN:
392                return Phone.DataActivityState.DATAIN;
393            case TelephonyManager.DATA_ACTIVITY_OUT:
394                return Phone.DataActivityState.DATAOUT;
395            case TelephonyManager.DATA_ACTIVITY_INOUT:
396                return Phone.DataActivityState.DATAINANDOUT;
397            case TelephonyManager.DATA_ACTIVITY_DORMANT:
398                return Phone.DataActivityState.DORMANT;
399            default:
400                return Phone.DataActivityState.NONE;
401        }
402    }
403
404    /**
405     * Convert the {@link State} enum into the PreciseCallState.PRECISE_CALL_STATE_* constants
406     * for the public API.
407     */
408    public static int convertPreciseCallState(Call.State state) {
409        switch (state) {
410            case ACTIVE:
411                return PreciseCallState.PRECISE_CALL_STATE_ACTIVE;
412            case HOLDING:
413                return PreciseCallState.PRECISE_CALL_STATE_HOLDING;
414            case DIALING:
415                return PreciseCallState.PRECISE_CALL_STATE_DIALING;
416            case ALERTING:
417                return PreciseCallState.PRECISE_CALL_STATE_ALERTING;
418            case INCOMING:
419                return PreciseCallState.PRECISE_CALL_STATE_INCOMING;
420            case WAITING:
421                return PreciseCallState.PRECISE_CALL_STATE_WAITING;
422            case DISCONNECTED:
423                return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED;
424            case DISCONNECTING:
425                return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING;
426            default:
427                return PreciseCallState.PRECISE_CALL_STATE_IDLE;
428        }
429    }
430
431    /**
432     * Convert the Call.State.* constants into the {@link State} enum
433     * for the public API.
434     */
435    public static Call.State convertPreciseCallState(int state) {
436        switch (state) {
437            case PreciseCallState.PRECISE_CALL_STATE_ACTIVE:
438                return Call.State.ACTIVE;
439            case PreciseCallState.PRECISE_CALL_STATE_HOLDING:
440                return Call.State.HOLDING;
441            case PreciseCallState.PRECISE_CALL_STATE_DIALING:
442                return Call.State.DIALING;
443            case PreciseCallState.PRECISE_CALL_STATE_ALERTING:
444                return Call.State.ALERTING;
445            case PreciseCallState.PRECISE_CALL_STATE_INCOMING:
446                return Call.State.INCOMING;
447            case PreciseCallState.PRECISE_CALL_STATE_WAITING:
448                return Call.State.WAITING;
449            case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED:
450                return Call.State.DISCONNECTED;
451            case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING:
452                return Call.State.DISCONNECTING;
453            default:
454                return Call.State.IDLE;
455        }
456    }
457
458    public interface IDataStateChangedCallback {
459        void onDataStateChanged(long subId, String state, String reason, String apnName,
460            String apnType, boolean unavailable);
461    }
462
463    private void log(String s) {
464        Rlog.d(LOG_TAG, s);
465    }
466}
467