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