DefaultPhoneNotifier.java revision aa577d3b49f32ce6c5e7956da662056ca765031f
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.Rlog;
26import android.telephony.VoLteServiceState;
27import android.telephony.ServiceState;
28import android.telephony.SubscriptionManager;
29import android.telephony.TelephonyManager;
30import android.telephony.PreciseCallState;
31
32import com.android.internal.telephony.PhoneConstantConversions;
33import com.android.internal.telephony.PhoneConstants;
34
35import java.util.List;
36
37/**
38 * broadcast intents
39 */
40public class DefaultPhoneNotifier implements PhoneNotifier {
41    private static final String LOG_TAG = "DefaultPhoneNotifier";
42    private static final boolean DBG = false; // STOPSHIP if true
43
44    protected ITelephonyRegistry mRegistry;
45
46    public DefaultPhoneNotifier() {
47        mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
48                    "telephony.registry"));
49    }
50
51    @Override
52    public void notifyPhoneState(Phone sender) {
53        Call ringingCall = sender.getRingingCall();
54        int subId = sender.getSubId();
55        int phoneId = sender.getPhoneId();
56        String incomingNumber = "";
57        if (ringingCall != null && ringingCall.getEarliestConnection() != null) {
58            incomingNumber = ringingCall.getEarliestConnection().getAddress();
59        }
60        try {
61            if (mRegistry != null) {
62                  mRegistry.notifyCallStateForPhoneId(phoneId, subId,
63                        PhoneConstantConversions.convertCallState(
64                            sender.getState()), incomingNumber);
65            }
66        } catch (RemoteException ex) {
67            // system process is dead
68        }
69    }
70
71    @Override
72    public void notifyServiceState(Phone sender) {
73        ServiceState ss = sender.getServiceState();
74        int phoneId = sender.getPhoneId();
75        int subId = sender.getSubId();
76
77        Rlog.d(LOG_TAG, "nofityServiceState: mRegistry=" + mRegistry + " ss=" + ss
78                + " sender=" + sender + " phondId=" + phoneId + " subId=" + subId);
79        if (ss == null) {
80            ss = new ServiceState();
81            ss.setStateOutOfService();
82        }
83        try {
84            if (mRegistry != null) {
85                mRegistry.notifyServiceStateForPhoneId(phoneId, subId, ss);
86            }
87        } catch (RemoteException ex) {
88            // system process is dead
89        }
90    }
91
92    @Override
93    public void notifySignalStrength(Phone sender) {
94        int phoneId = sender.getPhoneId();
95        int subId = sender.getSubId();
96        if (DBG) {
97            // too chatty to log constantly
98            Rlog.d(LOG_TAG, "notifySignalStrength: mRegistry=" + mRegistry
99                    + " ss=" + sender.getSignalStrength() + " sender=" + sender);
100        }
101        try {
102            if (mRegistry != null) {
103                mRegistry.notifySignalStrengthForPhoneId(phoneId, subId,
104                        sender.getSignalStrength());
105            }
106        } catch (RemoteException ex) {
107            // system process is dead
108        }
109    }
110
111    @Override
112    public void notifyMessageWaitingChanged(Phone sender) {
113        int phoneId = sender.getPhoneId();
114        int subId = sender.getSubId();
115
116        try {
117            if (mRegistry != null) {
118                mRegistry.notifyMessageWaitingChangedForPhoneId(phoneId, subId,
119                        sender.getMessageWaitingIndicator());
120            }
121        } catch (RemoteException ex) {
122            // system process is dead
123        }
124    }
125
126    @Override
127    public void notifyCallForwardingChanged(Phone sender) {
128        int subId = sender.getSubId();
129        try {
130            if (mRegistry != null) {
131                mRegistry.notifyCallForwardingChangedForSubscriber(subId,
132                        sender.getCallForwardingIndicator());
133            }
134        } catch (RemoteException ex) {
135            // system process is dead
136        }
137    }
138
139    @Override
140    public void notifyDataActivity(Phone sender) {
141        int subId = sender.getSubId();
142        try {
143            if (mRegistry != null) {
144                mRegistry.notifyDataActivityForSubscriber(subId,
145                        convertDataActivityState(sender.getDataActivityState()));
146            }
147        } catch (RemoteException ex) {
148            // system process is dead
149        }
150    }
151
152    @Override
153    public void notifyDataConnection(Phone sender, String reason, String apnType,
154            PhoneConstants.DataState state) {
155        doNotifyDataConnection(sender, reason, apnType, state);
156    }
157
158    private void doNotifyDataConnection(Phone sender, String reason, String apnType,
159            PhoneConstants.DataState state) {
160        int subId = sender.getSubId();
161        long dds = SubscriptionManager.getDefaultDataSubscriptionId();
162        if (DBG) log("subId = " + subId + ", DDS = " + dds);
163
164        // TODO
165        // use apnType as the key to which connection we're talking about.
166        // pass apnType back up to fetch particular for this one.
167        TelephonyManager telephony = TelephonyManager.getDefault();
168        LinkProperties linkProperties = null;
169        NetworkCapabilities networkCapabilities = null;
170        boolean roaming = false;
171
172        if (state == PhoneConstants.DataState.CONNECTED) {
173            linkProperties = sender.getLinkProperties(apnType);
174            networkCapabilities = sender.getNetworkCapabilities(apnType);
175        }
176        ServiceState ss = sender.getServiceState();
177        if (ss != null) roaming = ss.getDataRoaming();
178
179        try {
180            if (mRegistry != null) {
181                mRegistry.notifyDataConnectionForSubscriber(subId,
182                    PhoneConstantConversions.convertDataState(state),
183                    sender.isDataConnectivityPossible(apnType), reason,
184                    sender.getActiveApnHost(apnType),
185                    apnType,
186                    linkProperties,
187                    networkCapabilities,
188                    ((telephony!=null) ? telephony.getDataNetworkType(subId) :
189                    TelephonyManager.NETWORK_TYPE_UNKNOWN),
190                    roaming);
191            }
192        } catch (RemoteException ex) {
193            // system process is dead
194        }
195    }
196
197    @Override
198    public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
199        int subId = sender.getSubId();
200        try {
201            if (mRegistry != null) {
202                mRegistry.notifyDataConnectionFailedForSubscriber(subId, reason, apnType);
203            }
204        } catch (RemoteException ex) {
205            // system process is dead
206        }
207    }
208
209    @Override
210    public void notifyCellLocation(Phone sender) {
211        int subId = sender.getSubId();
212        Bundle data = new Bundle();
213        sender.getCellLocation().fillInNotifierBundle(data);
214        try {
215            if (mRegistry != null) {
216                mRegistry.notifyCellLocationForSubscriber(subId, data);
217            }
218        } catch (RemoteException ex) {
219            // system process is dead
220        }
221    }
222
223    @Override
224    public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo) {
225        int subId = sender.getSubId();
226        try {
227            if (mRegistry != null) {
228                mRegistry.notifyCellInfoForSubscriber(subId, cellInfo);
229            }
230        } catch (RemoteException ex) {
231
232        }
233    }
234
235    @Override
236    public void notifyOtaspChanged(Phone sender, int otaspMode) {
237        // FIXME: subId?
238        try {
239            if (mRegistry != null) {
240                mRegistry.notifyOtaspChanged(otaspMode);
241            }
242        } catch (RemoteException ex) {
243            // system process is dead
244        }
245    }
246
247    public void notifyPreciseCallState(Phone sender) {
248        // FIXME: subId?
249        Call ringingCall = sender.getRingingCall();
250        Call foregroundCall = sender.getForegroundCall();
251        Call backgroundCall = sender.getBackgroundCall();
252        if (ringingCall != null && foregroundCall != null && backgroundCall != null) {
253            try {
254                mRegistry.notifyPreciseCallState(
255                        convertPreciseCallState(ringingCall.getState()),
256                        convertPreciseCallState(foregroundCall.getState()),
257                        convertPreciseCallState(backgroundCall.getState()));
258            } catch (RemoteException ex) {
259                // system process is dead
260            }
261        }
262    }
263
264    public void notifyDisconnectCause(int cause, int preciseCause) {
265        // FIXME: subId?
266        try {
267            mRegistry.notifyDisconnectCause(cause, preciseCause);
268        } catch (RemoteException ex) {
269            // system process is dead
270        }
271    }
272
273    public void notifyPreciseDataConnectionFailed(Phone sender, String reason, String apnType,
274            String apn, String failCause) {
275        // FIXME: subId?
276        try {
277            mRegistry.notifyPreciseDataConnectionFailed(reason, apnType, apn, failCause);
278        } catch (RemoteException ex) {
279            // system process is dead
280        }
281    }
282
283    @Override
284    public void notifyVoLteServiceStateChanged(Phone sender, VoLteServiceState lteState) {
285        // FIXME: subID
286        try {
287            mRegistry.notifyVoLteServiceStateChanged(lteState);
288        } catch (RemoteException ex) {
289            // system process is dead
290        }
291    }
292
293    @Override
294    public void notifyDataActivationStateChanged(Phone sender, int activationState) {
295        try {
296            mRegistry.notifySimActivationStateChangedForPhoneId(sender.getPhoneId(),
297                    sender.getSubId(), PhoneConstants.SIM_ACTIVATION_TYPE_DATA, activationState);
298        } catch (RemoteException ex) {
299            // system process is dead
300        }
301    }
302
303    @Override
304    public void notifyVoiceActivationStateChanged(Phone sender, int activationState) {
305        try {
306            mRegistry.notifySimActivationStateChangedForPhoneId(sender.getPhoneId(),
307                    sender.getSubId(), PhoneConstants.SIM_ACTIVATION_TYPE_VOICE, activationState);
308        } catch (RemoteException ex) {
309            // system process is dead
310        }
311    }
312
313    @Override
314    public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) {
315        try {
316            mRegistry.notifyOemHookRawEventForSubscriber(subId, rawData);
317        } catch (RemoteException ex) {
318            // system process is dead
319        }
320    }
321
322    /**
323     * Convert the {@link Phone.DataActivityState} enum into the TelephonyManager.DATA_* constants
324     * for the public API.
325     */
326    public static int convertDataActivityState(Phone.DataActivityState state) {
327        switch (state) {
328            case DATAIN:
329                return TelephonyManager.DATA_ACTIVITY_IN;
330            case DATAOUT:
331                return TelephonyManager.DATA_ACTIVITY_OUT;
332            case DATAINANDOUT:
333                return TelephonyManager.DATA_ACTIVITY_INOUT;
334            case DORMANT:
335                return TelephonyManager.DATA_ACTIVITY_DORMANT;
336            default:
337                return TelephonyManager.DATA_ACTIVITY_NONE;
338        }
339    }
340
341    /**
342     * Convert the {@link Call.State} enum into the PreciseCallState.PRECISE_CALL_STATE_* constants
343     * for the public API.
344     */
345    public static int convertPreciseCallState(Call.State state) {
346        switch (state) {
347            case ACTIVE:
348                return PreciseCallState.PRECISE_CALL_STATE_ACTIVE;
349            case HOLDING:
350                return PreciseCallState.PRECISE_CALL_STATE_HOLDING;
351            case DIALING:
352                return PreciseCallState.PRECISE_CALL_STATE_DIALING;
353            case ALERTING:
354                return PreciseCallState.PRECISE_CALL_STATE_ALERTING;
355            case INCOMING:
356                return PreciseCallState.PRECISE_CALL_STATE_INCOMING;
357            case WAITING:
358                return PreciseCallState.PRECISE_CALL_STATE_WAITING;
359            case DISCONNECTED:
360                return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED;
361            case DISCONNECTING:
362                return PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING;
363            default:
364                return PreciseCallState.PRECISE_CALL_STATE_IDLE;
365        }
366    }
367
368    private void log(String s) {
369        Rlog.d(LOG_TAG, s);
370    }
371}
372