[picopc] Added ethernet patch based on Yi Sun <beyounn@gmail.com> from android-x86.org
[picopc-android-gingerbread:frameworks-base.git] / packages / SystemUI / src / com / android / systemui / statusbar / StatusBarPolicy.java
1 /*
2  * Copyright (C) 2008 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
17 package com.android.systemui.statusbar.policy;
18
19 import android.app.StatusBarManager;
20 import android.app.AlertDialog;
21 import android.bluetooth.BluetoothA2dp;
22 import android.bluetooth.BluetoothAdapter;
23 import android.bluetooth.BluetoothHeadset;
24 import android.bluetooth.BluetoothPbap;
25 import android.content.BroadcastReceiver;
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.content.DialogInterface;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.res.TypedArray;
32 import android.graphics.PixelFormat;
33 import android.graphics.Typeface;
34 import android.graphics.drawable.Drawable;
35 import android.location.LocationManager;
36 import android.media.AudioManager;
37 import android.media.Ringtone;
38 import android.media.RingtoneManager;
39 import android.net.ConnectivityManager;
40 import android.net.NetworkInfo;
41 import android.net.Uri;
42 import android.net.wifi.WifiManager;
43 import android.net.ethernet.EthernetManager;
44 import android.net.ethernet.EthernetStateTracker;
45 import android.os.Binder;
46 import android.os.Handler;
47 import android.os.Message;
48 import android.os.RemoteException;
49 import android.os.storage.StorageManager;
50 import android.os.SystemProperties;
51 import android.provider.Settings;
52 import android.telephony.PhoneStateListener;
53 import android.telephony.ServiceState;
54 import android.telephony.SignalStrength;
55 import android.telephony.TelephonyManager;
56 import android.text.format.DateFormat;
57 import android.text.style.CharacterStyle;
58 import android.text.style.RelativeSizeSpan;
59 import android.text.style.ForegroundColorSpan;
60 import android.text.style.StyleSpan;
61 import android.text.Spannable;
62 import android.text.SpannableStringBuilder;
63 import android.util.Slog;
64 import android.view.View;
65 import android.view.ViewGroup;
66 import android.view.WindowManager;
67 import android.view.WindowManagerImpl;
68 import android.widget.ImageView;
69 import android.widget.LinearLayout;
70 import android.widget.TextView;
71
72 import com.android.internal.app.IBatteryStats;
73 import com.android.internal.telephony.IccCard;
74 import com.android.internal.telephony.TelephonyIntents;
75 import com.android.internal.telephony.cdma.EriInfo;
76 import com.android.internal.telephony.cdma.TtyIntent;
77 import com.android.server.am.BatteryStatsService;
78
79 import com.android.systemui.R;
80 import android.net.wimax.WimaxManagerConstants;
81
82 /**
83  * This class contains all of the policy about which icons are installed in the status
84  * bar at boot time.  It goes through the normal API for icons, even though it probably
85  * strictly doesn't need to.
86  */
87 public class StatusBarPolicy {
88     private static final String TAG = "StatusBarPolicy";
89
90     // message codes for the handler
91     private static final int EVENT_BATTERY_CLOSE = 4;
92
93     private static final int AM_PM_STYLE_NORMAL  = 0;
94     private static final int AM_PM_STYLE_SMALL   = 1;
95     private static final int AM_PM_STYLE_GONE    = 2;
96
97     private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
98
99     private static final int INET_CONDITION_THRESHOLD = 50;
100
101     private final Context mContext;
102     private final StatusBarManager mService;
103     private final Handler mHandler = new StatusBarHandler();
104     private final IBatteryStats mBatteryStats;
105
106     // storage
107     private StorageManager mStorageManager;
108
109     // battery
110     private boolean mBatteryFirst = true;
111     private boolean mBatteryPlugged;
112     private int mBatteryLevel;
113     private AlertDialog mLowBatteryDialog;
114     private TextView mBatteryLevelTextView;
115     private View mBatteryView;
116     private int mBatteryViewSequence;
117     private boolean mBatteryShowLowOnEndCall = false;
118     private static final boolean SHOW_LOW_BATTERY_WARNING = true;
119     private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;
120
121     // phone
122     private TelephonyManager mPhone;
123     private int mPhoneSignalIconId;
124
125     //***** Signal strength icons
126     //GSM/UMTS
127     private static final int[][] sSignalImages = {
128         { R.drawable.stat_sys_signal_0,
129           R.drawable.stat_sys_signal_1,
130           R.drawable.stat_sys_signal_2,
131           R.drawable.stat_sys_signal_3,
132           R.drawable.stat_sys_signal_4 },
133         { R.drawable.stat_sys_signal_0_fully,
134           R.drawable.stat_sys_signal_1_fully,
135           R.drawable.stat_sys_signal_2_fully,
136           R.drawable.stat_sys_signal_3_fully,
137           R.drawable.stat_sys_signal_4_fully }
138     };
139     private static final int[][] sSignalImages_r = {
140         { R.drawable.stat_sys_r_signal_0,
141           R.drawable.stat_sys_r_signal_1,
142           R.drawable.stat_sys_r_signal_2,
143           R.drawable.stat_sys_r_signal_3,
144           R.drawable.stat_sys_r_signal_4 },
145         { R.drawable.stat_sys_r_signal_0_fully,
146           R.drawable.stat_sys_r_signal_1_fully,
147           R.drawable.stat_sys_r_signal_2_fully,
148           R.drawable.stat_sys_r_signal_3_fully,
149           R.drawable.stat_sys_r_signal_4_fully }
150     };
151     private static final int[] sRoamingIndicatorImages_cdma = new int[] {
152         R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator
153         // 1 is Standard Roaming Indicator OFF
154         // TODO T: image never used, remove and put 0 instead?
155         R.drawable.stat_sys_roaming_cdma_0,
156
157         // 2 is Standard Roaming Indicator FLASHING
158         // TODO T: image never used, remove and put 0 instead?
159         R.drawable.stat_sys_roaming_cdma_0,
160
161         // 3-12 Standard ERI
162         R.drawable.stat_sys_roaming_cdma_0, //3
163         R.drawable.stat_sys_roaming_cdma_0,
164         R.drawable.stat_sys_roaming_cdma_0,
165         R.drawable.stat_sys_roaming_cdma_0,
166         R.drawable.stat_sys_roaming_cdma_0,
167         R.drawable.stat_sys_roaming_cdma_0,
168         R.drawable.stat_sys_roaming_cdma_0,
169         R.drawable.stat_sys_roaming_cdma_0,
170         R.drawable.stat_sys_roaming_cdma_0,
171         R.drawable.stat_sys_roaming_cdma_0,
172
173         // 13-63 Reserved for Standard ERI
174         R.drawable.stat_sys_roaming_cdma_0, //13
175         R.drawable.stat_sys_roaming_cdma_0,
176         R.drawable.stat_sys_roaming_cdma_0,
177         R.drawable.stat_sys_roaming_cdma_0,
178         R.drawable.stat_sys_roaming_cdma_0,
179         R.drawable.stat_sys_roaming_cdma_0,
180         R.drawable.stat_sys_roaming_cdma_0,
181         R.drawable.stat_sys_roaming_cdma_0,
182         R.drawable.stat_sys_roaming_cdma_0,
183         R.drawable.stat_sys_roaming_cdma_0,
184         R.drawable.stat_sys_roaming_cdma_0,
185         R.drawable.stat_sys_roaming_cdma_0,
186         R.drawable.stat_sys_roaming_cdma_0,
187         R.drawable.stat_sys_roaming_cdma_0,
188         R.drawable.stat_sys_roaming_cdma_0,
189         R.drawable.stat_sys_roaming_cdma_0,
190         R.drawable.stat_sys_roaming_cdma_0,
191         R.drawable.stat_sys_roaming_cdma_0,
192         R.drawable.stat_sys_roaming_cdma_0,
193         R.drawable.stat_sys_roaming_cdma_0,
194         R.drawable.stat_sys_roaming_cdma_0,
195         R.drawable.stat_sys_roaming_cdma_0,
196         R.drawable.stat_sys_roaming_cdma_0,
197         R.drawable.stat_sys_roaming_cdma_0,
198         R.drawable.stat_sys_roaming_cdma_0,
199         R.drawable.stat_sys_roaming_cdma_0,
200         R.drawable.stat_sys_roaming_cdma_0,
201         R.drawable.stat_sys_roaming_cdma_0,
202         R.drawable.stat_sys_roaming_cdma_0,
203         R.drawable.stat_sys_roaming_cdma_0,
204         R.drawable.stat_sys_roaming_cdma_0,
205         R.drawable.stat_sys_roaming_cdma_0,
206         R.drawable.stat_sys_roaming_cdma_0,
207         R.drawable.stat_sys_roaming_cdma_0,
208         R.drawable.stat_sys_roaming_cdma_0,
209         R.drawable.stat_sys_roaming_cdma_0,
210         R.drawable.stat_sys_roaming_cdma_0,
211         R.drawable.stat_sys_roaming_cdma_0,
212         R.drawable.stat_sys_roaming_cdma_0,
213         R.drawable.stat_sys_roaming_cdma_0,
214         R.drawable.stat_sys_roaming_cdma_0,
215         R.drawable.stat_sys_roaming_cdma_0,
216         R.drawable.stat_sys_roaming_cdma_0,
217         R.drawable.stat_sys_roaming_cdma_0,
218         R.drawable.stat_sys_roaming_cdma_0,
219         R.drawable.stat_sys_roaming_cdma_0,
220         R.drawable.stat_sys_roaming_cdma_0,
221         R.drawable.stat_sys_roaming_cdma_0,
222         R.drawable.stat_sys_roaming_cdma_0,
223         R.drawable.stat_sys_roaming_cdma_0,
224         R.drawable.stat_sys_roaming_cdma_0,
225
226         // 64-127 Reserved for Non Standard (Operator Specific) ERI
227         R.drawable.stat_sys_roaming_cdma_0, //64
228         R.drawable.stat_sys_roaming_cdma_0,
229         R.drawable.stat_sys_roaming_cdma_0,
230         R.drawable.stat_sys_roaming_cdma_0,
231         R.drawable.stat_sys_roaming_cdma_0,
232         R.drawable.stat_sys_roaming_cdma_0,
233         R.drawable.stat_sys_roaming_cdma_0,
234         R.drawable.stat_sys_roaming_cdma_0,
235         R.drawable.stat_sys_roaming_cdma_0,
236         R.drawable.stat_sys_roaming_cdma_0,
237         R.drawable.stat_sys_roaming_cdma_0,
238         R.drawable.stat_sys_roaming_cdma_0,
239         R.drawable.stat_sys_roaming_cdma_0,
240         R.drawable.stat_sys_roaming_cdma_0,
241         R.drawable.stat_sys_roaming_cdma_0,
242         R.drawable.stat_sys_roaming_cdma_0,
243         R.drawable.stat_sys_roaming_cdma_0,
244         R.drawable.stat_sys_roaming_cdma_0,
245         R.drawable.stat_sys_roaming_cdma_0,
246         R.drawable.stat_sys_roaming_cdma_0, //83
247         R.drawable.stat_sys_roaming_cdma_0,
248         R.drawable.stat_sys_roaming_cdma_0,
249         R.drawable.stat_sys_roaming_cdma_0,
250         R.drawable.stat_sys_roaming_cdma_0,
251         R.drawable.stat_sys_roaming_cdma_0,
252         R.drawable.stat_sys_roaming_cdma_0,
253         R.drawable.stat_sys_roaming_cdma_0,
254         R.drawable.stat_sys_roaming_cdma_0,
255         R.drawable.stat_sys_roaming_cdma_0,
256         R.drawable.stat_sys_roaming_cdma_0,
257         R.drawable.stat_sys_roaming_cdma_0,
258         R.drawable.stat_sys_roaming_cdma_0,
259         R.drawable.stat_sys_roaming_cdma_0,
260         R.drawable.stat_sys_roaming_cdma_0,
261         R.drawable.stat_sys_roaming_cdma_0,
262         R.drawable.stat_sys_roaming_cdma_0,
263         R.drawable.stat_sys_roaming_cdma_0,
264         R.drawable.stat_sys_roaming_cdma_0,
265         R.drawable.stat_sys_roaming_cdma_0,
266         R.drawable.stat_sys_roaming_cdma_0,
267         R.drawable.stat_sys_roaming_cdma_0,
268         R.drawable.stat_sys_roaming_cdma_0,
269         R.drawable.stat_sys_roaming_cdma_0,
270         R.drawable.stat_sys_roaming_cdma_0,
271         R.drawable.stat_sys_roaming_cdma_0,
272         R.drawable.stat_sys_roaming_cdma_0,
273         R.drawable.stat_sys_roaming_cdma_0,
274         R.drawable.stat_sys_roaming_cdma_0,
275         R.drawable.stat_sys_roaming_cdma_0,
276         R.drawable.stat_sys_roaming_cdma_0,
277         R.drawable.stat_sys_roaming_cdma_0,
278         R.drawable.stat_sys_roaming_cdma_0,
279         R.drawable.stat_sys_roaming_cdma_0,
280         R.drawable.stat_sys_roaming_cdma_0,
281         R.drawable.stat_sys_roaming_cdma_0,
282         R.drawable.stat_sys_roaming_cdma_0,
283         R.drawable.stat_sys_roaming_cdma_0,
284         R.drawable.stat_sys_roaming_cdma_0,
285         R.drawable.stat_sys_roaming_cdma_0,
286         R.drawable.stat_sys_roaming_cdma_0,
287         R.drawable.stat_sys_roaming_cdma_0,
288         R.drawable.stat_sys_roaming_cdma_0,
289         R.drawable.stat_sys_roaming_cdma_0,
290         R.drawable.stat_sys_roaming_cdma_0,
291         R.drawable.stat_sys_roaming_cdma_0,
292         R.drawable.stat_sys_roaming_cdma_0,
293         R.drawable.stat_sys_roaming_cdma_0,
294         R.drawable.stat_sys_roaming_cdma_0,
295         R.drawable.stat_sys_roaming_cdma_0,
296         R.drawable.stat_sys_roaming_cdma_0,
297         R.drawable.stat_sys_roaming_cdma_0,
298         R.drawable.stat_sys_roaming_cdma_0,
299         R.drawable.stat_sys_roaming_cdma_0,
300         R.drawable.stat_sys_roaming_cdma_0,
301         R.drawable.stat_sys_roaming_cdma_0,
302         R.drawable.stat_sys_roaming_cdma_0,
303         R.drawable.stat_sys_roaming_cdma_0,
304         R.drawable.stat_sys_roaming_cdma_0,
305         R.drawable.stat_sys_roaming_cdma_0,
306         R.drawable.stat_sys_roaming_cdma_0,
307         R.drawable.stat_sys_roaming_cdma_0,
308         R.drawable.stat_sys_roaming_cdma_0,
309         R.drawable.stat_sys_roaming_cdma_0,
310         R.drawable.stat_sys_roaming_cdma_0,
311         R.drawable.stat_sys_roaming_cdma_0,
312         R.drawable.stat_sys_roaming_cdma_0,
313         R.drawable.stat_sys_roaming_cdma_0,
314         R.drawable.stat_sys_roaming_cdma_0,
315         R.drawable.stat_sys_roaming_cdma_0,
316         R.drawable.stat_sys_roaming_cdma_0,
317         R.drawable.stat_sys_roaming_cdma_0,
318         R.drawable.stat_sys_roaming_cdma_0,
319         R.drawable.stat_sys_roaming_cdma_0,
320         R.drawable.stat_sys_roaming_cdma_0,
321         R.drawable.stat_sys_roaming_cdma_0,
322         R.drawable.stat_sys_roaming_cdma_0,
323         R.drawable.stat_sys_roaming_cdma_0,
324         R.drawable.stat_sys_roaming_cdma_0,
325         R.drawable.stat_sys_roaming_cdma_0,
326         R.drawable.stat_sys_roaming_cdma_0,
327         R.drawable.stat_sys_roaming_cdma_0,
328         R.drawable.stat_sys_roaming_cdma_0,
329         R.drawable.stat_sys_roaming_cdma_0,
330         R.drawable.stat_sys_roaming_cdma_0,
331         R.drawable.stat_sys_roaming_cdma_0,
332         R.drawable.stat_sys_roaming_cdma_0,
333         R.drawable.stat_sys_roaming_cdma_0,
334         R.drawable.stat_sys_roaming_cdma_0,
335         R.drawable.stat_sys_roaming_cdma_0,
336         R.drawable.stat_sys_roaming_cdma_0,
337         R.drawable.stat_sys_roaming_cdma_0,
338         R.drawable.stat_sys_roaming_cdma_0,
339         R.drawable.stat_sys_roaming_cdma_0,
340         R.drawable.stat_sys_roaming_cdma_0,
341         R.drawable.stat_sys_roaming_cdma_0,
342         R.drawable.stat_sys_roaming_cdma_0,
343         R.drawable.stat_sys_roaming_cdma_0,
344         R.drawable.stat_sys_roaming_cdma_0,
345         R.drawable.stat_sys_roaming_cdma_0,
346         R.drawable.stat_sys_roaming_cdma_0,
347         R.drawable.stat_sys_roaming_cdma_0,
348         R.drawable.stat_sys_roaming_cdma_0,
349         R.drawable.stat_sys_roaming_cdma_0,
350         R.drawable.stat_sys_roaming_cdma_0,
351         R.drawable.stat_sys_roaming_cdma_0,
352         R.drawable.stat_sys_roaming_cdma_0,
353         R.drawable.stat_sys_roaming_cdma_0,
354         R.drawable.stat_sys_roaming_cdma_0,
355         R.drawable.stat_sys_roaming_cdma_0,
356         R.drawable.stat_sys_roaming_cdma_0,
357         R.drawable.stat_sys_roaming_cdma_0,
358         R.drawable.stat_sys_roaming_cdma_0,
359         R.drawable.stat_sys_roaming_cdma_0,
360         R.drawable.stat_sys_roaming_cdma_0,
361         R.drawable.stat_sys_roaming_cdma_0,
362         R.drawable.stat_sys_roaming_cdma_0,
363         R.drawable.stat_sys_roaming_cdma_0,
364         R.drawable.stat_sys_roaming_cdma_0,
365         R.drawable.stat_sys_roaming_cdma_0,
366         R.drawable.stat_sys_roaming_cdma_0,
367         R.drawable.stat_sys_roaming_cdma_0,
368         R.drawable.stat_sys_roaming_cdma_0,
369         R.drawable.stat_sys_roaming_cdma_0,
370         R.drawable.stat_sys_roaming_cdma_0,
371         R.drawable.stat_sys_roaming_cdma_0,
372         R.drawable.stat_sys_roaming_cdma_0,
373         R.drawable.stat_sys_roaming_cdma_0,
374         R.drawable.stat_sys_roaming_cdma_0,
375         R.drawable.stat_sys_roaming_cdma_0,
376         R.drawable.stat_sys_roaming_cdma_0,
377         R.drawable.stat_sys_roaming_cdma_0,
378         R.drawable.stat_sys_roaming_cdma_0,
379         R.drawable.stat_sys_roaming_cdma_0,
380         R.drawable.stat_sys_roaming_cdma_0,
381         R.drawable.stat_sys_roaming_cdma_0,
382         R.drawable.stat_sys_roaming_cdma_0,
383         R.drawable.stat_sys_roaming_cdma_0,
384         R.drawable.stat_sys_roaming_cdma_0,
385         R.drawable.stat_sys_roaming_cdma_0,
386         R.drawable.stat_sys_roaming_cdma_0,
387         R.drawable.stat_sys_roaming_cdma_0,
388         R.drawable.stat_sys_roaming_cdma_0,
389         R.drawable.stat_sys_roaming_cdma_0,
390         R.drawable.stat_sys_roaming_cdma_0,
391         R.drawable.stat_sys_roaming_cdma_0,
392         R.drawable.stat_sys_roaming_cdma_0,
393         R.drawable.stat_sys_roaming_cdma_0,
394         R.drawable.stat_sys_roaming_cdma_0,
395         R.drawable.stat_sys_roaming_cdma_0,
396         R.drawable.stat_sys_roaming_cdma_0,
397         R.drawable.stat_sys_roaming_cdma_0,
398         R.drawable.stat_sys_roaming_cdma_0,
399         R.drawable.stat_sys_roaming_cdma_0,
400         R.drawable.stat_sys_roaming_cdma_0,
401         R.drawable.stat_sys_roaming_cdma_0,
402         R.drawable.stat_sys_roaming_cdma_0 //239
403
404         // 240-255 Reserved
405     };
406
407     //***** Data connection icons
408     private int[] mDataIconList = sDataNetType_g[0];
409     //GSM/UMTS
410     private static final int[][] sDataNetType_g = {
411             { R.drawable.stat_sys_data_connected_g,
412               R.drawable.stat_sys_data_in_g,
413               R.drawable.stat_sys_data_out_g,
414               R.drawable.stat_sys_data_inandout_g },
415             { R.drawable.stat_sys_data_fully_connected_g,
416               R.drawable.stat_sys_data_fully_in_g,
417               R.drawable.stat_sys_data_fully_out_g,
418               R.drawable.stat_sys_data_fully_inandout_g }
419         };
420     private static final int[][] sDataNetType_3g = {
421             { R.drawable.stat_sys_data_connected_3g,
422               R.drawable.stat_sys_data_in_3g,
423               R.drawable.stat_sys_data_out_3g,
424               R.drawable.stat_sys_data_inandout_3g },
425             { R.drawable.stat_sys_data_fully_connected_3g,
426               R.drawable.stat_sys_data_fully_in_3g,
427               R.drawable.stat_sys_data_fully_out_3g,
428               R.drawable.stat_sys_data_fully_inandout_3g }
429         };
430     private static final int[][] sDataNetType_e = {
431             { R.drawable.stat_sys_data_connected_e,
432               R.drawable.stat_sys_data_in_e,
433               R.drawable.stat_sys_data_out_e,
434               R.drawable.stat_sys_data_inandout_e },
435             { R.drawable.stat_sys_data_fully_connected_e,
436               R.drawable.stat_sys_data_fully_in_e,
437               R.drawable.stat_sys_data_fully_out_e,
438               R.drawable.stat_sys_data_fully_inandout_e }
439         };
440     //3.5G
441     private static final int[][] sDataNetType_h = {
442             { R.drawable.stat_sys_data_connected_h,
443               R.drawable.stat_sys_data_in_h,
444               R.drawable.stat_sys_data_out_h,
445               R.drawable.stat_sys_data_inandout_h },
446             { R.drawable.stat_sys_data_fully_connected_h,
447               R.drawable.stat_sys_data_fully_in_h,
448               R.drawable.stat_sys_data_fully_out_h,
449               R.drawable.stat_sys_data_fully_inandout_h }
450     };
451
452     //CDMA
453     // Use 3G icons for EVDO data and 1x icons for 1XRTT data
454     private static final int[][] sDataNetType_1x = {
455             { R.drawable.stat_sys_data_connected_1x,
456               R.drawable.stat_sys_data_in_1x,
457               R.drawable.stat_sys_data_out_1x,
458               R.drawable.stat_sys_data_inandout_1x },
459             { R.drawable.stat_sys_data_fully_connected_1x,
460               R.drawable.stat_sys_data_fully_in_1x,
461               R.drawable.stat_sys_data_fully_out_1x,
462               R.drawable.stat_sys_data_fully_inandout_1x }
463             };
464
465     // Assume it's all good unless we hear otherwise.  We don't always seem
466     // to get broadcasts that it *is* there.
467     IccCard.State mSimState = IccCard.State.READY;
468     int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
469     int mDataState = TelephonyManager.DATA_DISCONNECTED;
470     int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
471     ServiceState mServiceState;
472     SignalStrength mSignalStrength;
473
474     // data connection
475     private boolean mDataIconVisible;
476     private boolean mHspaDataDistinguishable;
477
478     // ringer volume
479     private boolean mVolumeVisible;
480
481     // bluetooth device status
482     private int mBluetoothHeadsetState;
483     private boolean mBluetoothA2dpConnected;
484     private int mBluetoothPbapState;
485     private boolean mBluetoothEnabled;
486
487     // wifi
488     private static final int[][] sWifiSignalImages = {
489             { R.drawable.stat_sys_wifi_signal_1,
490               R.drawable.stat_sys_wifi_signal_2,
491               R.drawable.stat_sys_wifi_signal_3,
492               R.drawable.stat_sys_wifi_signal_4 },
493             { R.drawable.stat_sys_wifi_signal_1_fully,
494               R.drawable.stat_sys_wifi_signal_2_fully,
495               R.drawable.stat_sys_wifi_signal_3_fully,
496               R.drawable.stat_sys_wifi_signal_4_fully }
497         };
498     private static final int sWifiTemporarilyNotConnectedImage =
499             R.drawable.stat_sys_wifi_signal_0;
500
501     private int mLastWifiSignalLevel = -1;
502     private boolean mIsWifiConnected = false;
503
504     //Ethernet
505     private static final int[] sEthImages = {
506             R.drawable.connect_established,
507             R.drawable.connect_no,
508             R.drawable.connect_creating
509         };
510
511     //4G
512     private static final int[][] sWimaxSignalImages = {
513             { R.drawable.stat_sys_data_wimax_signal_0,
514               R.drawable.stat_sys_data_wimax_signal_1,
515               R.drawable.stat_sys_data_wimax_signal_2,
516               R.drawable.stat_sys_data_wimax_signal_3 },
517             { R.drawable.stat_sys_data_wimax_signal_0_fully,
518               R.drawable.stat_sys_data_wimax_signal_1_fully,
519               R.drawable.stat_sys_data_wimax_signal_2_fully,
520               R.drawable.stat_sys_data_wimax_signal_3_fully }
521         };
522     private static final int sWimaxDisconnectedImg =
523             R.drawable.stat_sys_data_wimax_signal_disconnected;
524     private static final int sWimaxIdleImg = R.drawable.stat_sys_data_wimax_signal_idle;
525     private boolean mIsWimaxConnected = false;
526     private boolean mIsWimaxEnabled = false;
527     private int mWimaxSignal = 0;
528     private int mWimaxState = 0;
529
530     // state of inet connection - 0 not connected, 100 connected
531     private int mInetCondition = 0;
532
533     // sync state
534     // If sync is active the SyncActive icon is displayed. If sync is not active but
535     // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed.
536
537     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
538         @Override
539         public void onReceive(Context context, Intent intent) {
540             String action = intent.getAction();
541             if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
542                 updateBattery(intent);
543             }
544             else if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
545                 updateAlarm(intent);
546             }
547             else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
548                 updateSyncState(intent);
549             }
550             else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
551                 onBatteryLow(intent);
552             }
553             else if (action.equals(Intent.ACTION_BATTERY_OKAY)
554                     || action.equals(Intent.ACTION_POWER_CONNECTED)) {
555                 onBatteryOkay(intent);
556             }
557             else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
558                     action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) ||
559                     action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ||
560                     action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
561                 updateBluetooth(intent);
562             }
563             else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) ||
564                     action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) ||
565                     action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
566                 updateWifi(intent);
567             }  else if (action.equals(EthernetManager.ETHERNET_STATE_CHANGED_ACTION)) {
568                 updateEth(intent);
569             }
570             else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) ||
571                     action.equals(LocationManager.GPS_FIX_CHANGE_ACTION)) {
572                 updateGps(intent);
573             }
574             else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
575                     action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
576                 updateVolume();
577             }
578             else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
579                 updateSimState(intent);
580             }
581             else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
582                 updateTTY(intent);
583             }
584             else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
585                      action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
586                 // TODO - stop using other means to get wifi/mobile info
587                 updateConnectivity(intent);
588             }
589             else if (action.equals(WimaxManagerConstants.WIMAX_ENABLED_STATUS_CHANGED) ||
590                      action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION) ||
591                      action.equals(WimaxManagerConstants.WIMAX_STATE_CHANGED_ACTION)) {
592                 updateWiMAX(intent);
593             }
594         }
595     };
596
597     public StatusBarPolicy(Context context) {
598         mContext = context;
599         mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
600         mSignalStrength = new SignalStrength();
601         mBatteryStats = BatteryStatsService.getService();
602
603         // storage
604         mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
605         mStorageManager.registerListener(
606                 new com.android.systemui.usb.StorageNotification(context));
607
608         // battery
609         mService.setIcon("battery", com.android.internal.R.drawable.stat_sys_battery_unknown, 0);
610
611         // phone_signal
612         mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
613         mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
614         mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
615         mService.setIconVisibility("phone_signal", false);
616
617         // register for phone state notifications.
618         ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
619                 .listen(mPhoneStateListener,
620                           PhoneStateListener.LISTEN_SERVICE_STATE
621                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
622                         | PhoneStateListener.LISTEN_CALL_STATE
623                         | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
624                         | PhoneStateListener.LISTEN_DATA_ACTIVITY);
625
626         // data_connection
627         mService.setIcon("data_connection", R.drawable.stat_sys_data_connected_g, 0);
628         mService.setIconVisibility("data_connection", false);
629
630         // wifi
631         mService.setIcon("wifi", sWifiSignalImages[0][0], 0);
632         mService.setIconVisibility("wifi", false);
633         // wifi will get updated by the sticky intents
634
635         // ethernet
636         mService.setIcon("ethernet", sEthImages[0], 0);
637         mService.setIconVisibility("ethernet", false);
638
639         // wimax
640         //enable/disable wimax depending on the value in config.xml
641         boolean isWimaxEnabled = mContext.getResources().getBoolean(
642                 com.android.internal.R.bool.config_wimaxEnabled);
643         if (isWimaxEnabled) {
644             mService.setIcon("wimax", sWimaxDisconnectedImg, 0);
645             mService.setIconVisibility("wimax", false);
646         }
647
648         // TTY status
649         mService.setIcon("tty",  R.drawable.stat_sys_tty_mode, 0);
650         mService.setIconVisibility("tty", false);
651
652         // Cdma Roaming Indicator, ERI
653         mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0);
654         mService.setIconVisibility("cdma_eri", false);
655
656         // bluetooth status
657         mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0);
658         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
659         if (adapter != null) {
660             mBluetoothEnabled = adapter.isEnabled();
661         } else {
662             mBluetoothEnabled = false;
663         }
664         mBluetoothA2dpConnected = false;
665         mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
666         mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
667         mService.setIconVisibility("bluetooth", mBluetoothEnabled);
668
669         // Gps status
670         mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
671         mService.setIconVisibility("gps", false);
672
673         // Alarm clock
674         mService.setIcon("alarm_clock", R.drawable.stat_notify_alarm, 0);
675         mService.setIconVisibility("alarm_clock", false);
676
677         // Sync state
678         mService.setIcon("sync_active", com.android.internal.R.drawable.stat_notify_sync_anim0, 0);
679         mService.setIcon("sync_failing", com.android.internal.R.drawable.stat_notify_sync_error, 0);
680         mService.setIconVisibility("sync_active", false);
681         mService.setIconVisibility("sync_failing", false);
682
683         // volume
684         mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0);
685         mService.setIconVisibility("volume", false);
686         updateVolume();
687
688         IntentFilter filter = new IntentFilter();
689
690         // Register for Intent broadcasts for...
691         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
692         filter.addAction(Intent.ACTION_BATTERY_LOW);
693         filter.addAction(Intent.ACTION_BATTERY_OKAY);
694         filter.addAction(Intent.ACTION_POWER_CONNECTED);
695         filter.addAction(Intent.ACTION_ALARM_CHANGED);
696         filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
697         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
698         filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
699         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
700         filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
701         filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
702         filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
703         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
704         filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
705         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
706         filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
707         filter.addAction(EthernetManager.ETHERNET_STATE_CHANGED_ACTION);
708         filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION);
709         filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION);
710         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
711         filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
712         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
713         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
714         filter.addAction(WimaxManagerConstants.WIMAX_STATE_CHANGED_ACTION);
715         filter.addAction(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION);
716         filter.addAction(WimaxManagerConstants.WIMAX_ENABLED_STATUS_CHANGED);
717
718         mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
719
720         // load config to determine if to distinguish Hspa data icon
721         try {
722             mHspaDataDistinguishable = mContext.getResources().getBoolean(
723                     R.bool.config_hspa_data_distinguishable);
724         } catch (Exception e) {
725             mHspaDataDistinguishable = false;
726         }
727     }
728
729     private final void updateAlarm(Intent intent) {
730         boolean alarmSet = intent.getBooleanExtra("alarmSet", false);
731         mService.setIconVisibility("alarm_clock", alarmSet);
732     }
733
734     private final void updateSyncState(Intent intent) {
735         boolean isActive = intent.getBooleanExtra("active", false);
736         boolean isFailing = intent.getBooleanExtra("failing", false);
737         mService.setIconVisibility("sync_active", isActive);
738         // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
739         //mService.setIconVisibility("sync_failing", isFailing && !isActive);
740     }
741
742     private final void updateBattery(Intent intent) {
743         final int id = intent.getIntExtra("icon-small", 0);
744         int level = intent.getIntExtra("level", 0);
745         mService.setIcon("battery", id, level);
746
747         boolean plugged = intent.getIntExtra("plugged", 0) != 0;
748         level = intent.getIntExtra("level", -1);
749         if (false) {
750             Slog.d(TAG, "updateBattery level=" + level
751                     + " plugged=" + plugged
752                     + " mBatteryPlugged=" + mBatteryPlugged
753                     + " mBatteryLevel=" + mBatteryLevel
754                     + " mBatteryFirst=" + mBatteryFirst);
755         }
756
757         boolean oldPlugged = mBatteryPlugged;
758
759         mBatteryPlugged = plugged;
760         mBatteryLevel = level;
761
762         if (mBatteryFirst) {
763             mBatteryFirst = false;
764         }
765         /*
766          * No longer showing the battery view because it draws attention away
767          * from the USB storage notification. We could still show it when
768          * connected to a brick, but that could lead to the user into thinking
769          * the device does not charge when plugged into USB (since he/she would
770          * not see the same battery screen on USB as he sees on brick).
771          */
772         if (false) {
773             Slog.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level);
774         }
775     }
776
777     private void onBatteryLow(Intent intent) {
778         if (SHOW_LOW_BATTERY_WARNING) {
779             if (false) {
780                 Slog.d(TAG, "mPhoneState=" + mPhoneState
781                       + " mLowBatteryDialog=" + mLowBatteryDialog
782                       + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
783             }
784
785             if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
786                 showLowBatteryWarning();
787             } else {
788                 mBatteryShowLowOnEndCall = true;
789             }
790         }
791     }
792
793     private void onBatteryOkay(Intent intent) {
794         if (mLowBatteryDialog != null
795                 && SHOW_LOW_BATTERY_WARNING) {
796             mLowBatteryDialog.dismiss();
797             mBatteryShowLowOnEndCall = false;
798         }
799     }
800
801     private void setBatteryLevel(View parent, int id, int height, int background, int level) {
802         ImageView v = (ImageView)parent.findViewById(id);
803         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams();
804         lp.weight = height;
805         if (background != 0) {
806             v.setBackgroundResource(background);
807             Drawable bkg = v.getBackground();
808             bkg.setLevel(level);
809         }
810     }
811
812     private void showLowBatteryWarning() {
813         closeLastBatteryView();
814
815         // Show exact battery level.
816         CharSequence levelText = mContext.getString(
817                     R.string.battery_low_percent_format, mBatteryLevel);
818
819         if (mBatteryLevelTextView != null) {
820             mBatteryLevelTextView.setText(levelText);
821         } else {
822             View v = View.inflate(mContext, R.layout.battery_low, null);
823             mBatteryLevelTextView=(TextView)v.findViewById(R.id.level_percent);
824
825             mBatteryLevelTextView.setText(levelText);
826
827             AlertDialog.Builder b = new AlertDialog.Builder(mContext);
828                 b.setCancelable(true);
829                 b.setTitle(R.string.battery_low_title);
830                 b.setView(v);
831                 b.setIcon(android.R.drawable.ic_dialog_alert);
832                 b.setPositiveButton(android.R.string.ok, null);
833
834                 final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
835                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
836                         | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
837                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
838                         | Intent.FLAG_ACTIVITY_NO_HISTORY);
839                 if (intent.resolveActivity(mContext.getPackageManager()) != null) {
840                     b.setNegativeButton(R.string.battery_low_why,
841                             new DialogInterface.OnClickListener() {
842                         public void onClick(DialogInterface dialog, int which) {
843                             mContext.startActivity(intent);
844                             if (mLowBatteryDialog != null) {
845                                 mLowBatteryDialog.dismiss();
846                             }
847                         }
848                     });
849                 }
850
851             AlertDialog d = b.create();
852             d.setOnDismissListener(mLowBatteryListener);
853             d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
854             d.show();
855             mLowBatteryDialog = d;
856         }
857
858         final ContentResolver cr = mContext.getContentResolver();
859         if (Settings.System.getInt(cr,
860                 Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)
861         {
862             final String soundPath = Settings.System.getString(cr,
863                 Settings.System.LOW_BATTERY_SOUND);
864             if (soundPath != null) {
865                 final Uri soundUri = Uri.parse("file://" + soundPath);
866                 if (soundUri != null) {
867                     final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
868                     if (sfx != null) {
869                         sfx.setStreamType(AudioManager.STREAM_SYSTEM);
870                         sfx.play();
871                     }
872                 }
873             }
874         }
875     }
876
877     private final void updateCallState(int state) {
878         mPhoneState = state;
879         if (false) {
880             Slog.d(TAG, "mPhoneState=" + mPhoneState
881                     + " mLowBatteryDialog=" + mLowBatteryDialog
882                     + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
883         }
884         if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
885             if (mBatteryShowLowOnEndCall) {
886                 if (!mBatteryPlugged) {
887                     showLowBatteryWarning();
888                 }
889                 mBatteryShowLowOnEndCall = false;
890             }
891         } else {
892             if (mLowBatteryDialog != null) {
893                 mLowBatteryDialog.dismiss();
894                 mBatteryShowLowOnEndCall = true;
895             }
896         }
897     }
898
899     private DialogInterface.OnDismissListener mLowBatteryListener
900             = new DialogInterface.OnDismissListener() {
901         public void onDismiss(DialogInterface dialog) {
902             mLowBatteryDialog = null;
903             mBatteryLevelTextView = null;
904         }
905     };
906
907     private void scheduleCloseBatteryView() {
908         Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE);
909         m.arg1 = (++mBatteryViewSequence);
910         mHandler.sendMessageDelayed(m, 3000);
911     }
912
913     private void closeLastBatteryView() {
914         if (mBatteryView != null) {
915             //mBatteryView.debug();
916             WindowManagerImpl.getDefault().removeView(mBatteryView);
917             mBatteryView = null;
918         }
919     }
920
921     private void updateConnectivity(Intent intent) {
922         NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra(
923                 ConnectivityManager.EXTRA_NETWORK_INFO));
924         int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
925
926         int inetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
927
928         switch (info.getType()) {
929         case ConnectivityManager.TYPE_MOBILE:
930             mInetCondition = inetCondition;
931             updateDataNetType(info.getSubtype());
932             updateDataIcon();
933             updateSignalStrength(); // apply any change in connectionStatus
934             break;
935         case ConnectivityManager.TYPE_WIFI:
936             mInetCondition = inetCondition;
937             if (info.isConnected()) {
938                 mIsWifiConnected = true;
939                 int iconId;
940                 if (mLastWifiSignalLevel == -1) {
941                     iconId = sWifiSignalImages[mInetCondition][0];
942                 } else {
943                     iconId = sWifiSignalImages[mInetCondition][mLastWifiSignalLevel];
944                 }
945                 mService.setIcon("wifi", iconId, 0);
946                 // Show the icon since wi-fi is connected
947                 mService.setIconVisibility("wifi", true);
948             } else {
949                 mLastWifiSignalLevel = -1;
950                 mIsWifiConnected = false;
951                 int iconId = sWifiSignalImages[0][0];
952
953                 mService.setIcon("wifi", iconId, 0);
954                 // Hide the icon since we're not connected
955                 mService.setIconVisibility("wifi", false);
956             }
957             updateSignalStrength(); // apply any change in mInetCondition
958             break;
959         case ConnectivityManager.TYPE_ETHERNET:
960             if (info.isConnected()) {
961                 mService.setIcon("ethernet", sEthImages[0], 0);
962                 // Show the icon since ethernet is connected
963                 mService.setIconVisibility("ethernet", true);
964             } else {
965                 mService.setIcon("ethernet", sEthImages[1], 0);
966                 // Hide the icon since we're not connected
967                 mService.setIconVisibility("ethernet", false);
968             }
969             break;
970         case ConnectivityManager.TYPE_WIMAX:
971             mInetCondition = inetCondition;
972             if (info.isConnected()) {
973                 mIsWimaxConnected = true;
974                 mService.setIconVisibility("wimax", true);
975             } else {
976                 mIsWimaxConnected = false;
977             }
978             updateWiMAX(intent);
979             break;
980         }
981     }
982
983     private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
984         @Override
985         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
986             mSignalStrength = signalStrength;
987             updateSignalStrength();
988         }
989
990         @Override
991         public void onServiceStateChanged(ServiceState state) {
992             mServiceState = state;
993             updateSignalStrength();
994             updateCdmaRoamingIcon(state);
995             updateDataIcon();
996         }
997
998         @Override
999         public void onCallStateChanged(int state, String incomingNumber) {
1000             updateCallState(state);
1001             // In cdma, if a voice call is made, RSSI should switch to 1x.
1002             if (isCdma()) {
1003                 updateSignalStrength();
1004             }
1005         }
1006
1007         @Override
1008         public void onDataConnectionStateChanged(int state, int networkType) {
1009             mDataState = state;
1010             updateDataNetType(networkType);
1011             updateDataIcon();
1012         }
1013
1014         @Override
1015         public void onDataActivity(int direction) {
1016             mDataActivity = direction;
1017             updateDataIcon();
1018         }
1019     };
1020
1021     private final void updateSimState(Intent intent) {
1022         String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
1023         if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
1024             mSimState = IccCard.State.ABSENT;
1025         }
1026         else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1027             mSimState = IccCard.State.READY;
1028         }
1029         else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
1030             final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
1031             if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1032                 mSimState = IccCard.State.PIN_REQUIRED;
1033             }
1034             else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1035                 mSimState = IccCard.State.PUK_REQUIRED;
1036             }
1037             else {
1038                 mSimState = IccCard.State.NETWORK_LOCKED;
1039             }
1040         } else {
1041             mSimState = IccCard.State.UNKNOWN;
1042         }
1043         updateDataIcon();
1044     }
1045
1046     private boolean isCdma() {
1047         return (mSignalStrength != null) && !mSignalStrength.isGsm();
1048     }
1049
1050     private boolean isEvdo() {
1051         return ( (mServiceState != null)
1052                  && ((mServiceState.getRadioTechnology()
1053                         == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
1054                      || (mServiceState.getRadioTechnology()
1055                         == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
1056                      || (mServiceState.getRadioTechnology()
1057                         == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
1058     }
1059
1060     private boolean hasService() {
1061         if (mServiceState != null) {
1062             switch (mServiceState.getState()) {
1063                 case ServiceState.STATE_OUT_OF_SERVICE:
1064                 case ServiceState.STATE_POWER_OFF:
1065                     return false;
1066                 default:
1067                     return true;
1068             }
1069         } else {
1070             return false;
1071         }
1072     }
1073
1074     private final void updateSignalStrength() {
1075         int iconLevel = -1;
1076         int[] iconList;
1077
1078         if (!hasService())
1079         {
1080                 return;
1081         }
1082         // Display signal strength while in "emergency calls only" mode
1083         if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) {
1084             //Slog.d(TAG, "updateSignalStrength: no service");
1085             if (Settings.System.getInt(mContext.getContentResolver(),
1086                     Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
1087                 mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode;
1088             } else {
1089                 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
1090             }
1091             mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
1092             return;
1093         }
1094
1095         if (!isCdma()) {
1096             int asu = mSignalStrength.getGsmSignalStrength();
1097
1098             // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
1099             // asu = 0 (-113dB or less) is very weak
1100             // signal, its better to show 0 bars to the user in such cases.
1101             // asu = 99 is a special case, where the signal strength is unknown.
1102             if (asu <= 2 || asu == 99) iconLevel = 0;
1103             else if (asu >= 12) iconLevel = 4;
1104             else if (asu >= 8)  iconLevel = 3;
1105             else if (asu >= 5)  iconLevel = 2;
1106             else iconLevel = 1;
1107
1108             // Though mPhone is a Manager, this call is not an IPC
1109             if (mPhone.isNetworkRoaming()) {
1110                 iconList = sSignalImages_r[mInetCondition];
1111             } else {
1112                 iconList = sSignalImages[mInetCondition];
1113             }
1114         } else {
1115             iconList = sSignalImages[mInetCondition];
1116
1117             // If 3G(EV) and 1x network are available than 3G should be
1118             // displayed, displayed RSSI should be from the EV side.
1119             // If a voice call is made then RSSI should switch to 1x.
1120             if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
1121                 iconLevel = getEvdoLevel();
1122                 if (false) {
1123                     Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel());
1124                 }
1125             } else {
1126                 iconLevel = getCdmaLevel();
1127             }
1128         }
1129         mPhoneSignalIconId = iconList[iconLevel];
1130         mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
1131     }
1132
1133     private int getCdmaLevel() {
1134         final int cdmaDbm = mSignalStrength.getCdmaDbm();
1135         final int cdmaEcio = mSignalStrength.getCdmaEcio();
1136         int levelDbm = 0;
1137         int levelEcio = 0;
1138
1139         if (cdmaDbm >= -75) levelDbm = 4;
1140         else if (cdmaDbm >= -85) levelDbm = 3;
1141         else if (cdmaDbm >= -95) levelDbm = 2;
1142         else if (cdmaDbm >= -100) levelDbm = 1;
1143         else levelDbm = 0;
1144
1145         // Ec/Io are in dB*10
1146         if (cdmaEcio >= -90) levelEcio = 4;
1147         else if (cdmaEcio >= -110) levelEcio = 3;
1148         else if (cdmaEcio >= -130) levelEcio = 2;
1149         else if (cdmaEcio >= -150) levelEcio = 1;
1150         else levelEcio = 0;
1151
1152         return (levelDbm < levelEcio) ? levelDbm : levelEcio;
1153     }
1154
1155     private int getEvdoLevel() {
1156         int evdoDbm = mSignalStrength.getEvdoDbm();
1157         int evdoSnr = mSignalStrength.getEvdoSnr();
1158         int levelEvdoDbm = 0;
1159         int levelEvdoSnr = 0;
1160
1161         if (evdoDbm >= -65) levelEvdoDbm = 4;
1162         else if (evdoDbm >= -75) levelEvdoDbm = 3;
1163         else if (evdoDbm >= -90) levelEvdoDbm = 2;
1164         else if (evdoDbm >= -105) levelEvdoDbm = 1;
1165         else levelEvdoDbm = 0;
1166
1167         if (evdoSnr >= 7) levelEvdoSnr = 4;
1168         else if (evdoSnr >= 5) levelEvdoSnr = 3;
1169         else if (evdoSnr >= 3) levelEvdoSnr = 2;
1170         else if (evdoSnr >= 1) levelEvdoSnr = 1;
1171         else levelEvdoSnr = 0;
1172
1173         return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
1174     }
1175
1176     private final void updateDataNetType(int net) {
1177         switch (net) {
1178         case TelephonyManager.NETWORK_TYPE_EDGE:
1179             mDataIconList = sDataNetType_e[mInetCondition];
1180             break;
1181         case TelephonyManager.NETWORK_TYPE_UMTS:
1182             mDataIconList = sDataNetType_3g[mInetCondition];
1183             break;
1184         case TelephonyManager.NETWORK_TYPE_HSDPA:
1185         case TelephonyManager.NETWORK_TYPE_HSUPA:
1186         case TelephonyManager.NETWORK_TYPE_HSPA:
1187             if (mHspaDataDistinguishable) {
1188                 mDataIconList = sDataNetType_h[mInetCondition];
1189             } else {
1190                 mDataIconList = sDataNetType_3g[mInetCondition];
1191             }
1192             break;
1193         case TelephonyManager.NETWORK_TYPE_CDMA:
1194             // display 1xRTT for IS95A/B
1195             mDataIconList = sDataNetType_1x[mInetCondition];
1196             break;
1197         case TelephonyManager.NETWORK_TYPE_1xRTT:
1198             mDataIconList = sDataNetType_1x[mInetCondition];
1199             break;
1200         case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
1201         case TelephonyManager.NETWORK_TYPE_EVDO_A:
1202         case TelephonyManager.NETWORK_TYPE_EVDO_B:
1203             mDataIconList = sDataNetType_3g[mInetCondition];
1204             break;
1205         default:
1206             mDataIconList = sDataNetType_g[mInetCondition];
1207         break;
1208         }
1209     }
1210
1211     private final void updateDataIcon() {
1212         int iconId;
1213         boolean visible = true;
1214
1215         if (!isCdma()) {
1216             // GSM case, we have to check also the sim state
1217             if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
1218                 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
1219                     switch (mDataActivity) {
1220                         case TelephonyManager.DATA_ACTIVITY_IN:
1221                             iconId = mDataIconList[1];
1222                             break;
1223                         case TelephonyManager.DATA_ACTIVITY_OUT:
1224                             iconId = mDataIconList[2];
1225                             break;
1226                         case TelephonyManager.DATA_ACTIVITY_INOUT:
1227                             iconId = mDataIconList[3];
1228                             break;
1229                         default:
1230                             iconId = mDataIconList[0];
1231                             break;
1232                     }
1233                     mService.setIcon("data_connection", iconId, 0);
1234                 } else {
1235                     visible = false;
1236                 }
1237             } else {
1238                 iconId = R.drawable.stat_sys_no_sim;
1239                 mService.setIcon("data_connection", iconId, 0);
1240             }
1241         } else {
1242             // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
1243             if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
1244                 switch (mDataActivity) {
1245                     case TelephonyManager.DATA_ACTIVITY_IN:
1246                         iconId = mDataIconList[1];
1247                         break;
1248                     case TelephonyManager.DATA_ACTIVITY_OUT:
1249                         iconId = mDataIconList[2];
1250                         break;
1251                     case TelephonyManager.DATA_ACTIVITY_INOUT:
1252                         iconId = mDataIconList[3];
1253                         break;
1254                     case TelephonyManager.DATA_ACTIVITY_DORMANT:
1255                     default:
1256                         iconId = mDataIconList[0];
1257                         break;
1258                 }
1259                 mService.setIcon("data_connection", iconId, 0);
1260             } else {
1261                 visible = false;
1262             }
1263         }
1264
1265         long ident = Binder.clearCallingIdentity();
1266         try {
1267             mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
1268         } catch (RemoteException e) {
1269         } finally {
1270             Binder.restoreCallingIdentity(ident);
1271         }
1272
1273         if (mDataIconVisible != visible) {
1274             mService.setIconVisibility("data_connection", visible);
1275             mDataIconVisible = visible;
1276         }
1277     }
1278
1279     private final void updateVolume() {
1280         AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
1281         final int ringerMode = audioManager.getRingerMode();
1282         final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
1283                 ringerMode == AudioManager.RINGER_MODE_VIBRATE;
1284         final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
1285                 ? R.drawable.stat_sys_ringer_vibrate
1286                 : R.drawable.stat_sys_ringer_silent;
1287
1288         if (visible) {
1289             mService.setIcon("volume", iconId, 0);
1290         }
1291         if (visible != mVolumeVisible) {
1292             mService.setIconVisibility("volume", visible);
1293             mVolumeVisible = visible;
1294         }
1295     }
1296
1297     private final void updateBluetooth(Intent intent) {
1298         int iconId = R.drawable.stat_sys_data_bluetooth;
1299         String action = intent.getAction();
1300         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
1301             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
1302             mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
1303         } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
1304             mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
1305                     BluetoothHeadset.STATE_ERROR);
1306         } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
1307             BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
1308             if (a2dp.getConnectedSinks().size() != 0) {
1309                 mBluetoothA2dpConnected = true;
1310             } else {
1311                 mBluetoothA2dpConnected = false;
1312             }
1313         } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
1314             mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
1315                     BluetoothPbap.STATE_DISCONNECTED);
1316         } else {
1317             return;
1318         }
1319
1320         if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
1321                 mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
1322             iconId = R.drawable.stat_sys_data_bluetooth_connected;
1323         }
1324
1325         mService.setIcon("bluetooth", iconId, 0);
1326         mService.setIconVisibility("bluetooth", mBluetoothEnabled);
1327     }
1328
1329
1330     private final void updateEth(Intent intent) {
1331         final int event = intent.getIntExtra(EthernetManager.EXTRA_ETHERNET_STATE, EthernetManager.ETHERNET_STATE_UNKNOWN);
1332         int iconId;
1333         switch (event) {
1334             case EthernetStateTracker.EVENT_HW_CONNECTED:
1335             case EthernetStateTracker.EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:
1336                 mService.setIconVisibility("ethernet", true);
1337                 iconId = sEthImages[0];
1338                 break;
1339             case EthernetStateTracker.EVENT_HW_DISCONNECTED:
1340             case EthernetStateTracker.EVENT_INTERFACE_CONFIGURATION_FAILED:
1341                 mService.setIconVisibility("ethernet", false);
1342                 iconId = sEthImages[1];
1343                 return;
1344             default:
1345                 iconId = sEthImages[2];
1346         }
1347         mService.setIcon("ethernet", iconId, 0);
1348     }
1349
1350     private final void updateWifi(Intent intent) {
1351         final String action = intent.getAction();
1352         if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
1353
1354             final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
1355                     WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
1356
1357             if (!enabled) {
1358                 // If disabled, hide the icon. (We show icon when connected.)
1359                 mService.setIconVisibility("wifi", false);
1360             }
1361
1362         } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
1363             final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED,
1364                                                            false);
1365             if (!enabled) {
1366                 mService.setIconVisibility("wifi", false);
1367             }
1368         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
1369             int iconId;
1370             final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
1371             int newSignalLevel = WifiManager.calculateSignalLevel(newRssi,
1372                                                                   sWifiSignalImages[0].length);
1373             if (newSignalLevel != mLastWifiSignalLevel) {
1374                 mLastWifiSignalLevel = newSignalLevel;
1375                 if (mIsWifiConnected) {
1376                     iconId = sWifiSignalImages[mInetCondition][newSignalLevel];
1377                 } else {
1378                     iconId = sWifiTemporarilyNotConnectedImage;
1379                 }
1380                 mService.setIcon("wifi", iconId, 0);
1381             }
1382         }
1383     }
1384
1385     private final void updateWiMAX(Intent intent) {
1386         final String action = intent.getAction();
1387         int iconId = sWimaxDisconnectedImg;
1388
1389         if (action.equals(WimaxManagerConstants. WIMAX_ENABLED_STATUS_CHANGED)) {
1390             int mWimaxStatus = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATUS,
1391                     WimaxManagerConstants.WIMAX_STATUS_DISABLED);
1392             switch(mWimaxStatus) {
1393                 case WimaxManagerConstants.WIMAX_STATUS_ENABLED:
1394                     mIsWimaxEnabled = true;
1395                     break;
1396                 case WimaxManagerConstants.WIMAX_STATUS_DISABLED:
1397                     mIsWimaxEnabled = false;
1398                     break;
1399             }
1400         } else if (action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION)) {
1401             mWimaxSignal = intent.getIntExtra(WimaxManagerConstants.EXTRA_NEW_SIGNAL_LEVEL, 0);
1402         } else if (action.equals(WimaxManagerConstants.WIMAX_STATE_CHANGED_ACTION)) {
1403             mWimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATE,
1404                     WimaxManagerConstants.WIMAX_STATE_UNKNOWN);
1405             int mExtraWimaxState = intent.getIntExtra(
1406                     WimaxManagerConstants.EXTRA_WIMAX_STATE_DETAIL,
1407                     WimaxManagerConstants.WIMAX_DEREGISTRATION);
1408
1409             switch(mWimaxState) {
1410                 case WimaxManagerConstants.WIMAX_STATE_DISCONNECTED:
1411                     iconId = sWimaxDisconnectedImg;
1412                     break;
1413                 case WimaxManagerConstants.WIMAX_STATE_CONNECTED:
1414                     if(mExtraWimaxState == WimaxManagerConstants.WIMAX_IDLE) {
1415                         iconId = sWimaxIdleImg;
1416                     }
1417                     else {
1418                         iconId = sWimaxSignalImages[mInetCondition][mWimaxSignal];
1419                     }
1420                     break;
1421             }
1422             mService.setIcon("wimax", iconId, 0);
1423         }
1424         mService.setIconVisibility("wimax", mIsWimaxEnabled);
1425     }
1426
1427     private final void updateGps(Intent intent) {
1428         final String action = intent.getAction();
1429         final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false);
1430
1431         if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) {
1432             // GPS is getting fixes
1433             mService.setIcon("gps", com.android.internal.R.drawable.stat_sys_gps_on, 0);
1434             mService.setIconVisibility("gps", true);
1435         } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
1436             // GPS is off
1437             mService.setIconVisibility("gps", false);
1438         } else {
1439             // GPS is on, but not receiving fixes
1440             mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
1441             mService.setIconVisibility("gps", true);
1442         }
1443     }
1444
1445     private final void updateTTY(Intent intent) {
1446         final String action = intent.getAction();
1447         final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
1448
1449         if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled);
1450
1451         if (enabled) {
1452             // TTY is on
1453             if (false) Slog.v(TAG, "updateTTY: set TTY on");
1454             mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0);
1455             mService.setIconVisibility("tty", true);
1456         } else {
1457             // TTY is off
1458             if (false) Slog.v(TAG, "updateTTY: set TTY off");
1459             mService.setIconVisibility("tty", false);
1460         }
1461     }
1462
1463     private final void updateCdmaRoamingIcon(ServiceState state) {
1464         if (!hasService()) {
1465             mService.setIconVisibility("cdma_eri", false);
1466             return;
1467         }
1468
1469         if (!isCdma()) {
1470             mService.setIconVisibility("cdma_eri", false);
1471             return;
1472         }
1473
1474         int[] iconList = sRoamingIndicatorImages_cdma;
1475         int iconIndex = state.getCdmaEriIconIndex();
1476         int iconMode = state.getCdmaEriIconMode();
1477
1478         if (iconIndex == -1) {
1479             Slog.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update");
1480             return;
1481         }
1482
1483         if (iconMode == -1) {
1484             Slog.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update");
1485             return;
1486         }
1487
1488         if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) {
1489             if (false) Slog.v(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon");
1490             mService.setIconVisibility("cdma_eri", false);
1491             return;
1492         }
1493
1494         switch (iconMode) {
1495             case EriInfo.ROAMING_ICON_MODE_NORMAL:
1496                 if (iconIndex >= iconList.length) {
1497                     Slog.e(TAG, "unknown iconIndex " + iconIndex + ", skipping ERI icon update");
1498                     return;
1499                 }
1500                 mService.setIcon("cdma_eri", iconList[iconIndex], 0);
1501                 mService.setIconVisibility("cdma_eri", true);
1502                 break;
1503             case EriInfo.ROAMING_ICON_MODE_FLASH:
1504                 mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_flash, 0);
1505                 mService.setIconVisibility("cdma_eri", true);
1506                 break;
1507
1508         }
1509         mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
1510     }
1511
1512     private class StatusBarHandler extends Handler {
1513         @Override
1514         public void handleMessage(Message msg) {
1515             switch (msg.what) {
1516             case EVENT_BATTERY_CLOSE:
1517                 if (msg.arg1 == mBatteryViewSequence) {
1518                     closeLastBatteryView();
1519                 }
1520                 break;
1521             }
1522         }
1523     }
1524 }