blob: 7ccf210f77be7569f2aa0dd89a0ed1cb0703ac8f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Joe Onorato798ac4c2010-05-27 16:39:00 -040017package com.android.systemui.statusbar.policy;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Joe Onorato798ac4c2010-05-27 16:39:00 -040019import android.app.StatusBarManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.app.AlertDialog;
21import android.bluetooth.BluetoothA2dp;
Nick Pellybd022f42009-08-14 18:33:38 -070022import android.bluetooth.BluetoothAdapter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.bluetooth.BluetoothHeadset;
Jiafa Liu3f416732009-07-02 16:36:02 +080024import android.bluetooth.BluetoothPbap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.BroadcastReceiver;
Daniel Sandler0e9d2af2010-01-25 11:33:03 -050026import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.content.Context;
28import android.content.DialogInterface;
29import android.content.Intent;
30import android.content.IntentFilter;
31import android.content.res.TypedArray;
32import android.graphics.PixelFormat;
Daniel Sandler2c195f72010-05-21 15:42:06 -040033import android.graphics.Typeface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.graphics.drawable.Drawable;
Mike Lockwood00b74272010-03-26 10:41:48 -040035import android.location.LocationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.media.AudioManager;
Daniel Sandler0e9d2af2010-01-25 11:33:03 -050037import android.media.Ringtone;
38import android.media.RingtoneManager;
Robert Greenwaltd7085fc2010-09-08 15:24:47 -070039import android.net.ConnectivityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.net.NetworkInfo;
Daniel Sandler0e9d2af2010-01-25 11:33:03 -050041import android.net.Uri;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.net.wifi.WifiManager;
Dianne Hackborn4840e142009-03-24 22:40:29 -070043import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.os.Message;
Dianne Hackborn4840e142009-03-24 22:40:29 -070046import android.os.RemoteException;
San Mehat4154c072010-02-09 18:37:54 -080047import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.provider.Settings;
49import android.telephony.PhoneStateListener;
50import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070051import android.telephony.SignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.telephony.TelephonyManager;
53import android.text.format.DateFormat;
Daniel Sandler2c195f72010-05-21 15:42:06 -040054import android.text.style.CharacterStyle;
Eric Fischer36e136c2010-01-14 17:42:48 -080055import android.text.style.RelativeSizeSpan;
Daniel Sandler2c195f72010-05-21 15:42:06 -040056import android.text.style.ForegroundColorSpan;
57import android.text.style.StyleSpan;
Eric Fischer36e136c2010-01-14 17:42:48 -080058import android.text.Spannable;
59import android.text.SpannableStringBuilder;
Joe Onorato8a9b2202010-02-26 18:56:32 -080060import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.view.View;
62import android.view.ViewGroup;
63import android.view.WindowManager;
64import android.view.WindowManagerImpl;
65import android.widget.ImageView;
66import android.widget.LinearLayout;
67import android.widget.TextView;
68
Wink Saville04e71b32009-04-02 11:00:54 -070069import com.android.internal.app.IBatteryStats;
Wink Saville04e71b32009-04-02 11:00:54 -070070import com.android.internal.telephony.IccCard;
71import com.android.internal.telephony.TelephonyIntents;
Wink Savillee9b06d72009-05-18 21:47:50 -070072import com.android.internal.telephony.cdma.EriInfo;
Wink Saville04e71b32009-04-02 11:00:54 -070073import com.android.internal.telephony.cdma.TtyIntent;
74import com.android.server.am.BatteryStatsService;
75
Joe Onorato798ac4c2010-05-27 16:39:00 -040076import com.android.systemui.R;
77
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078/**
79 * This class contains all of the policy about which icons are installed in the status
Joe Onorato798ac4c2010-05-27 16:39:00 -040080 * bar at boot time. It goes through the normal API for icons, even though it probably
81 * strictly doesn't need to.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 */
83public class StatusBarPolicy {
84 private static final String TAG = "StatusBarPolicy";
85
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 // message codes for the handler
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 private static final int EVENT_BATTERY_CLOSE = 4;
88
Daniel Sandler2c195f72010-05-21 15:42:06 -040089 private static final int AM_PM_STYLE_NORMAL = 0;
90 private static final int AM_PM_STYLE_SMALL = 1;
91 private static final int AM_PM_STYLE_GONE = 2;
92
93 private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
94
Robert Greenwaltd7085fc2010-09-08 15:24:47 -070095 private static final int INET_CONDITION_THRESHOLD = 50;
96
Dianne Hackborn4840e142009-03-24 22:40:29 -070097 private final Context mContext;
Joe Onorato798ac4c2010-05-27 16:39:00 -040098 private final StatusBarManager mService;
Dianne Hackborn4840e142009-03-24 22:40:29 -070099 private final Handler mHandler = new StatusBarHandler();
100 private final IBatteryStats mBatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101
San Mehat4154c072010-02-09 18:37:54 -0800102 // storage
103 private StorageManager mStorageManager;
104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 // battery
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 private boolean mBatteryFirst = true;
107 private boolean mBatteryPlugged;
108 private int mBatteryLevel;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 private AlertDialog mLowBatteryDialog;
110 private TextView mBatteryLevelTextView;
111 private View mBatteryView;
112 private int mBatteryViewSequence;
113 private boolean mBatteryShowLowOnEndCall = false;
114 private static final boolean SHOW_LOW_BATTERY_WARNING = true;
Daniel Sandler0e9d2af2010-01-25 11:33:03 -0500115 private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116
117 // phone
118 private TelephonyManager mPhone;
Joe Onorato0cbda992010-05-02 16:28:15 -0700119 private int mPhoneSignalIconId;
Wink Saville04e71b32009-04-02 11:00:54 -0700120
121 //***** Signal strength icons
Wink Saville04e71b32009-04-02 11:00:54 -0700122 //GSM/UMTS
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700123 private static final int[][] sSignalImages = {
124 { R.drawable.stat_sys_signal_0,
125 R.drawable.stat_sys_signal_1,
126 R.drawable.stat_sys_signal_2,
127 R.drawable.stat_sys_signal_3,
128 R.drawable.stat_sys_signal_4 },
129 { R.drawable.stat_sys_signal_0_fully,
130 R.drawable.stat_sys_signal_1_fully,
131 R.drawable.stat_sys_signal_2_fully,
132 R.drawable.stat_sys_signal_3_fully,
133 R.drawable.stat_sys_signal_4_fully }
Wink Savillee9b06d72009-05-18 21:47:50 -0700134 };
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700135 private static final int[][] sSignalImages_r = {
136 { R.drawable.stat_sys_r_signal_0,
137 R.drawable.stat_sys_r_signal_1,
138 R.drawable.stat_sys_r_signal_2,
139 R.drawable.stat_sys_r_signal_3,
140 R.drawable.stat_sys_r_signal_4 },
141 { R.drawable.stat_sys_r_signal_0_fully,
142 R.drawable.stat_sys_r_signal_1_fully,
143 R.drawable.stat_sys_r_signal_2_fully,
144 R.drawable.stat_sys_r_signal_3_fully,
145 R.drawable.stat_sys_r_signal_4_fully }
Wink Savillee9b06d72009-05-18 21:47:50 -0700146 };
Wink Savillee9b06d72009-05-18 21:47:50 -0700147 private static final int[] sRoamingIndicatorImages_cdma = new int[] {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400148 R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator
Wink Savillee9b06d72009-05-18 21:47:50 -0700149 // 1 is Standard Roaming Indicator OFF
150 // TODO T: image never used, remove and put 0 instead?
Joe Onorato798ac4c2010-05-27 16:39:00 -0400151 R.drawable.stat_sys_roaming_cdma_0,
Wink Savillee9b06d72009-05-18 21:47:50 -0700152
153 // 2 is Standard Roaming Indicator FLASHING
154 // TODO T: image never used, remove and put 0 instead?
Joe Onorato798ac4c2010-05-27 16:39:00 -0400155 R.drawable.stat_sys_roaming_cdma_0,
Wink Savillee9b06d72009-05-18 21:47:50 -0700156
157 // 3-12 Standard ERI
Joe Onorato798ac4c2010-05-27 16:39:00 -0400158 R.drawable.stat_sys_roaming_cdma_0, //3
159 R.drawable.stat_sys_roaming_cdma_0,
160 R.drawable.stat_sys_roaming_cdma_0,
161 R.drawable.stat_sys_roaming_cdma_0,
162 R.drawable.stat_sys_roaming_cdma_0,
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,
Wink Savillee9b06d72009-05-18 21:47:50 -0700168
169 // 13-63 Reserved for Standard ERI
Joe Onorato798ac4c2010-05-27 16:39:00 -0400170 R.drawable.stat_sys_roaming_cdma_0, //13
171 R.drawable.stat_sys_roaming_cdma_0,
172 R.drawable.stat_sys_roaming_cdma_0,
173 R.drawable.stat_sys_roaming_cdma_0,
174 R.drawable.stat_sys_roaming_cdma_0,
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,
Wink Savillee9b06d72009-05-18 21:47:50 -0700221
222 // 64-127 Reserved for Non Standard (Operator Specific) ERI
Joe Onorato798ac4c2010-05-27 16:39:00 -0400223 R.drawable.stat_sys_roaming_cdma_0, //64
224 R.drawable.stat_sys_roaming_cdma_0,
225 R.drawable.stat_sys_roaming_cdma_0,
226 R.drawable.stat_sys_roaming_cdma_0,
227 R.drawable.stat_sys_roaming_cdma_0,
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 //83
Wink Savillee9b06d72009-05-18 21:47:50 -0700243
244 // 128-255 Reserved
Wink Saville04e71b32009-04-02 11:00:54 -0700245 };
Wink Saville04e71b32009-04-02 11:00:54 -0700246
247 //***** Data connection icons
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700248 private int[] mDataIconList = sDataNetType_g[0];
Wink Saville04e71b32009-04-02 11:00:54 -0700249 //GSM/UMTS
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700250 private static final int[][] sDataNetType_g = {
251 { R.drawable.stat_sys_data_connected_g,
252 R.drawable.stat_sys_data_in_g,
253 R.drawable.stat_sys_data_out_g,
254 R.drawable.stat_sys_data_inandout_g },
Robert Greenwalt26faee32010-09-10 09:36:43 -0700255 { R.drawable.stat_sys_data_fully_connected_g,
256 R.drawable.stat_sys_data_fully_in_g,
257 R.drawable.stat_sys_data_fully_out_g,
258 R.drawable.stat_sys_data_fully_inandout_g }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 };
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700260 private static final int[][] sDataNetType_3g = {
261 { R.drawable.stat_sys_data_connected_3g,
262 R.drawable.stat_sys_data_in_3g,
263 R.drawable.stat_sys_data_out_3g,
264 R.drawable.stat_sys_data_inandout_3g },
Robert Greenwalt26faee32010-09-10 09:36:43 -0700265 { R.drawable.stat_sys_data_fully_connected_3g,
266 R.drawable.stat_sys_data_fully_in_3g,
267 R.drawable.stat_sys_data_fully_out_3g,
268 R.drawable.stat_sys_data_fully_inandout_3g }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 };
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700270 private static final int[][] sDataNetType_e = {
271 { R.drawable.stat_sys_data_connected_e,
272 R.drawable.stat_sys_data_in_e,
273 R.drawable.stat_sys_data_out_e,
274 R.drawable.stat_sys_data_inandout_e },
Robert Greenwalt26faee32010-09-10 09:36:43 -0700275 { R.drawable.stat_sys_data_fully_connected_e,
276 R.drawable.stat_sys_data_fully_in_e,
277 R.drawable.stat_sys_data_fully_out_e,
278 R.drawable.stat_sys_data_fully_inandout_e }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 };
Li Zheebe66342009-08-14 19:22:16 +0800280 //3.5G
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700281 private static final int[][] sDataNetType_h = {
282 { R.drawable.stat_sys_data_connected_h,
283 R.drawable.stat_sys_data_in_h,
284 R.drawable.stat_sys_data_out_h,
285 R.drawable.stat_sys_data_inandout_h },
Robert Greenwalt26faee32010-09-10 09:36:43 -0700286 { R.drawable.stat_sys_data_fully_connected_h,
287 R.drawable.stat_sys_data_fully_in_h,
288 R.drawable.stat_sys_data_fully_out_h,
289 R.drawable.stat_sys_data_fully_inandout_h }
Li Zheebe66342009-08-14 19:22:16 +0800290 };
291
Wink Saville04e71b32009-04-02 11:00:54 -0700292 //CDMA
johnwang9f87cb22009-08-25 15:25:37 -0700293 // Use 3G icons for EVDO data and 1x icons for 1XRTT data
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700294 private static final int[][] sDataNetType_1x = {
295 { R.drawable.stat_sys_data_connected_1x,
296 R.drawable.stat_sys_data_in_1x,
297 R.drawable.stat_sys_data_out_1x,
298 R.drawable.stat_sys_data_inandout_1x },
Robert Greenwalt26faee32010-09-10 09:36:43 -0700299 { R.drawable.stat_sys_data_fully_connected_1x,
300 R.drawable.stat_sys_data_fully_in_1x,
301 R.drawable.stat_sys_data_fully_out_1x,
302 R.drawable.stat_sys_data_fully_inandout_1x }
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700303 };
Wink Saville04e71b32009-04-02 11:00:54 -0700304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 // Assume it's all good unless we hear otherwise. We don't always seem
306 // to get broadcasts that it *is* there.
Wink Saville04e71b32009-04-02 11:00:54 -0700307 IccCard.State mSimState = IccCard.State.READY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
309 int mDataState = TelephonyManager.DATA_DISCONNECTED;
310 int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
311 ServiceState mServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -0700312 SignalStrength mSignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 // data connection
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 private boolean mDataIconVisible;
John Wang33e21fc2009-10-08 10:35:27 -0700316 private boolean mHspaDataDistinguishable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317
318 // ringer volume
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 private boolean mVolumeVisible;
Wink Saville04e71b32009-04-02 11:00:54 -0700320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 // bluetooth device status
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 private int mBluetoothHeadsetState;
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800323 private boolean mBluetoothA2dpConnected;
Jiafa Liu3f416732009-07-02 16:36:02 +0800324 private int mBluetoothPbapState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 private boolean mBluetoothEnabled;
326
327 // wifi
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700328 private static final int[][] sWifiSignalImages = {
329 { R.drawable.stat_sys_wifi_signal_1,
330 R.drawable.stat_sys_wifi_signal_2,
331 R.drawable.stat_sys_wifi_signal_3,
332 R.drawable.stat_sys_wifi_signal_4 },
Robert Greenwalt26faee32010-09-10 09:36:43 -0700333 { R.drawable.stat_sys_wifi_signal_1_fully,
334 R.drawable.stat_sys_wifi_signal_2_fully,
335 R.drawable.stat_sys_wifi_signal_3_fully,
336 R.drawable.stat_sys_wifi_signal_4_fully }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 };
338 private static final int sWifiTemporarilyNotConnectedImage =
Joe Onorato798ac4c2010-05-27 16:39:00 -0400339 R.drawable.stat_sys_wifi_signal_0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340
341 private int mLastWifiSignalLevel = -1;
342 private boolean mIsWifiConnected = false;
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700343
344 // state of inet connection - 0 not connected, 100 connected
345 private int mInetCondition = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346
347 // sync state
348 // If sync is active the SyncActive icon is displayed. If sync is not active but
349 // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed.
Wink Savillee9b06d72009-05-18 21:47:50 -0700350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
352 @Override
353 public void onReceive(Context context, Intent intent) {
354 String action = intent.getAction();
Joe Onorato263700d2010-05-14 11:54:53 -0700355 if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700356 updateBattery(intent);
357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 else if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
359 updateAlarm(intent);
360 }
361 else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
362 updateSyncState(intent);
363 }
Mihai Predaa82842f2009-04-29 15:05:56 +0200364 else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
365 onBatteryLow(intent);
366 }
Mike Lockwood69eb0bf2009-08-01 23:02:28 -0400367 else if (action.equals(Intent.ACTION_BATTERY_OKAY)
368 || action.equals(Intent.ACTION_POWER_CONNECTED)) {
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700369 onBatteryOkay(intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 }
Nick Pellyde893f52009-09-08 13:15:33 -0700371 else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
Nick Pelly005b2282009-09-10 10:21:56 -0700372 action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) ||
373 action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ||
Jiafa Liu3f416732009-07-02 16:36:02 +0800374 action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 updateBluetooth(intent);
376 }
377 else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) ||
378 action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) ||
379 action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
380 updateWifi(intent);
381 }
Mike Lockwood00b74272010-03-26 10:41:48 -0400382 else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) ||
383 action.equals(LocationManager.GPS_FIX_CHANGE_ACTION)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 updateGps(intent);
385 }
386 else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
387 action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
388 updateVolume();
389 }
390 else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
391 updateSimState(intent);
392 }
Wink Saville04e71b32009-04-02 11:00:54 -0700393 else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
394 updateTTY(intent);
395 }
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700396 else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
397 action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700398 // TODO - stop using other means to get wifi/mobile info
399 updateConnectivity(intent);
400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 }
402 };
403
Joe Onorato798ac4c2010-05-27 16:39:00 -0400404 public StatusBarPolicy(Context context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 mContext = context;
Joe Onorato798ac4c2010-05-27 16:39:00 -0400406 mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
Wink Savillee9b06d72009-05-18 21:47:50 -0700407 mSignalStrength = new SignalStrength();
Dianne Hackborn4840e142009-03-24 22:40:29 -0700408 mBatteryStats = BatteryStatsService.getService();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409
San Mehat4154c072010-02-09 18:37:54 -0800410 // storage
411 mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
412 mStorageManager.registerListener(
Joe Onoratofe4f3ae2010-06-04 11:25:26 -0700413 new com.android.systemui.usb.StorageNotification(context));
San Mehat4154c072010-02-09 18:37:54 -0800414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 // battery
Joe Onorato798ac4c2010-05-27 16:39:00 -0400416 mService.setIcon("battery", com.android.internal.R.drawable.stat_sys_battery_unknown, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417
418 // phone_signal
419 mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Joe Onorato798ac4c2010-05-27 16:39:00 -0400420 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
421 mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
Wink Savillee9b06d72009-05-18 21:47:50 -0700422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 // register for phone state notifications.
424 ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
425 .listen(mPhoneStateListener,
426 PhoneStateListener.LISTEN_SERVICE_STATE
Wink Savillee9b06d72009-05-18 21:47:50 -0700427 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 | PhoneStateListener.LISTEN_CALL_STATE
429 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
430 | PhoneStateListener.LISTEN_DATA_ACTIVITY);
431
432 // data_connection
Joe Onorato798ac4c2010-05-27 16:39:00 -0400433 mService.setIcon("data_connection", R.drawable.stat_sys_data_connected_g, 0);
434 mService.setIconVisibility("data_connection", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435
436 // wifi
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700437 mService.setIcon("wifi", sWifiSignalImages[0][0], 0);
Joe Onorato798ac4c2010-05-27 16:39:00 -0400438 mService.setIconVisibility("wifi", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 // wifi will get updated by the sticky intents
Wink Saville04e71b32009-04-02 11:00:54 -0700440
441 // TTY status
Joe Onorato798ac4c2010-05-27 16:39:00 -0400442 mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0);
443 mService.setIconVisibility("tty", false);
Wink Saville04e71b32009-04-02 11:00:54 -0700444
Wink Savillee9b06d72009-05-18 21:47:50 -0700445 // Cdma Roaming Indicator, ERI
Joe Onorato798ac4c2010-05-27 16:39:00 -0400446 mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0);
447 mService.setIconVisibility("cdma_eri", false);
Wink Savillee9b06d72009-05-18 21:47:50 -0700448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 // bluetooth status
Joe Onorato798ac4c2010-05-27 16:39:00 -0400450 mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0);
Nick Pellyf242b7b2009-10-08 00:12:45 +0200451 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Nick Pellybd022f42009-08-14 18:33:38 -0700452 if (adapter != null) {
453 mBluetoothEnabled = adapter.isEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 } else {
455 mBluetoothEnabled = false;
456 }
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800457 mBluetoothA2dpConnected = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
Jiafa Liu3f416732009-07-02 16:36:02 +0800459 mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
Joe Onorato0cbda992010-05-02 16:28:15 -0700460 mService.setIconVisibility("bluetooth", mBluetoothEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461
462 // Gps status
Joe Onorato798ac4c2010-05-27 16:39:00 -0400463 mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
464 mService.setIconVisibility("gps", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465
466 // Alarm clock
Joe Onorato798ac4c2010-05-27 16:39:00 -0400467 mService.setIcon("alarm_clock", R.drawable.stat_notify_alarm, 0);
468 mService.setIconVisibility("alarm_clock", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469
470 // Sync state
Joe Onorato798ac4c2010-05-27 16:39:00 -0400471 mService.setIcon("sync_active", com.android.internal.R.drawable.stat_notify_sync_anim0, 0);
472 mService.setIcon("sync_failing", com.android.internal.R.drawable.stat_notify_sync_error, 0);
473 mService.setIconVisibility("sync_active", false);
474 mService.setIconVisibility("sync_failing", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475
476 // volume
Joe Onorato798ac4c2010-05-27 16:39:00 -0400477 mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0);
478 mService.setIconVisibility("volume", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 updateVolume();
johnwang347c5a22009-08-24 22:11:11 -0700480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 IntentFilter filter = new IntentFilter();
482
483 // Register for Intent broadcasts for...
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Mihai Predaa82842f2009-04-29 15:05:56 +0200485 filter.addAction(Intent.ACTION_BATTERY_LOW);
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700486 filter.addAction(Intent.ACTION_BATTERY_OKAY);
Mike Lockwood69eb0bf2009-08-01 23:02:28 -0400487 filter.addAction(Intent.ACTION_POWER_CONNECTED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 filter.addAction(Intent.ACTION_ALARM_CHANGED);
489 filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
490 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
491 filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
Nick Pellyde893f52009-09-08 13:15:33 -0700492 filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
Nick Pelly005b2282009-09-10 10:21:56 -0700493 filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
494 filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
Jiafa Liu3f416732009-07-02 16:36:02 +0800495 filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
497 filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
498 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
499 filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
Mike Lockwood00b74272010-03-26 10:41:48 -0400500 filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION);
501 filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Wink Saville04e71b32009-04-02 11:00:54 -0700503 filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700504 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700505 filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
John Wang33e21fc2009-10-08 10:35:27 -0700507
508 // load config to determine if to distinguish Hspa data icon
509 try {
510 mHspaDataDistinguishable = mContext.getResources().getBoolean(
Joe Onorato798ac4c2010-05-27 16:39:00 -0400511 R.bool.config_hspa_data_distinguishable);
John Wang33e21fc2009-10-08 10:35:27 -0700512 } catch (Exception e) {
513 mHspaDataDistinguishable = false;
514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 }
516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 private final void updateAlarm(Intent intent) {
518 boolean alarmSet = intent.getBooleanExtra("alarmSet", false);
Joe Onorato0cbda992010-05-02 16:28:15 -0700519 mService.setIconVisibility("alarm_clock", alarmSet);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 }
521
522 private final void updateSyncState(Intent intent) {
523 boolean isActive = intent.getBooleanExtra("active", false);
524 boolean isFailing = intent.getBooleanExtra("failing", false);
Joe Onorato0cbda992010-05-02 16:28:15 -0700525 mService.setIconVisibility("sync_active", isActive);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
Joe Onorato0cbda992010-05-02 16:28:15 -0700527 //mService.setIconVisibility("sync_failing", isFailing && !isActive);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 }
529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 private final void updateBattery(Intent intent) {
Joe Onorato0cbda992010-05-02 16:28:15 -0700531 final int id = intent.getIntExtra("icon-small", 0);
532 int level = intent.getIntExtra("level", 0);
Joe Onorato798ac4c2010-05-27 16:39:00 -0400533 mService.setIcon("battery", id, level);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534
535 boolean plugged = intent.getIntExtra("plugged", 0) != 0;
Joe Onorato0cbda992010-05-02 16:28:15 -0700536 level = intent.getIntExtra("level", -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800538 Slog.d(TAG, "updateBattery level=" + level
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539 + " plugged=" + plugged
540 + " mBatteryPlugged=" + mBatteryPlugged
541 + " mBatteryLevel=" + mBatteryLevel
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 + " mBatteryFirst=" + mBatteryFirst);
543 }
544
545 boolean oldPlugged = mBatteryPlugged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546
547 mBatteryPlugged = plugged;
548 mBatteryLevel = level;
549
550 if (mBatteryFirst) {
551 mBatteryFirst = false;
552 }
553 /*
554 * No longer showing the battery view because it draws attention away
555 * from the USB storage notification. We could still show it when
556 * connected to a brick, but that could lead to the user into thinking
557 * the device does not charge when plugged into USB (since he/she would
558 * not see the same battery screen on USB as he sees on brick).
559 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800561 Slog.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 }
Mihai Predaa82842f2009-04-29 15:05:56 +0200563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564
Mihai Predaa82842f2009-04-29 15:05:56 +0200565 private void onBatteryLow(Intent intent) {
566 if (SHOW_LOW_BATTERY_WARNING) {
567 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800568 Slog.d(TAG, "mPhoneState=" + mPhoneState
Mihai Predaa82842f2009-04-29 15:05:56 +0200569 + " mLowBatteryDialog=" + mLowBatteryDialog
570 + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 }
Mihai Predaa82842f2009-04-29 15:05:56 +0200572
Daniel Sandler0e9d2af2010-01-25 11:33:03 -0500573 if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
Mihai Predaa82842f2009-04-29 15:05:56 +0200574 showLowBatteryWarning();
575 } else {
576 mBatteryShowLowOnEndCall = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 }
578 }
579 }
580
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700581 private void onBatteryOkay(Intent intent) {
582 if (mLowBatteryDialog != null
583 && SHOW_LOW_BATTERY_WARNING) {
584 mLowBatteryDialog.dismiss();
585 mBatteryShowLowOnEndCall = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 }
587 }
588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 private void setBatteryLevel(View parent, int id, int height, int background, int level) {
590 ImageView v = (ImageView)parent.findViewById(id);
591 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams();
592 lp.weight = height;
593 if (background != 0) {
594 v.setBackgroundResource(background);
595 Drawable bkg = v.getBackground();
596 bkg.setLevel(level);
597 }
598 }
599
600 private void showLowBatteryWarning() {
601 closeLastBatteryView();
602
Mike Lockwoodd81b1f42009-09-25 09:32:19 -0400603 // Show exact battery level.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 CharSequence levelText = mContext.getString(
Joe Onorato798ac4c2010-05-27 16:39:00 -0400605 R.string.battery_low_percent_format, mBatteryLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606
607 if (mBatteryLevelTextView != null) {
608 mBatteryLevelTextView.setText(levelText);
609 } else {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400610 View v = View.inflate(mContext, R.layout.battery_low, null);
611 mBatteryLevelTextView=(TextView)v.findViewById(R.id.level_percent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612
613 mBatteryLevelTextView.setText(levelText);
614
615 AlertDialog.Builder b = new AlertDialog.Builder(mContext);
616 b.setCancelable(true);
Joe Onorato798ac4c2010-05-27 16:39:00 -0400617 b.setTitle(R.string.battery_low_title);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 b.setView(v);
619 b.setIcon(android.R.drawable.ic_dialog_alert);
620 b.setPositiveButton(android.R.string.ok, null);
johnwang347c5a22009-08-24 22:11:11 -0700621
Dianne Hackborn3d74bb42009-06-19 10:35:21 -0700622 final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
623 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
624 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
625 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
626 | Intent.FLAG_ACTIVITY_NO_HISTORY);
627 if (intent.resolveActivity(mContext.getPackageManager()) != null) {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400628 b.setNegativeButton(R.string.battery_low_why,
Dianne Hackborn3d74bb42009-06-19 10:35:21 -0700629 new DialogInterface.OnClickListener() {
630 public void onClick(DialogInterface dialog, int which) {
631 mContext.startActivity(intent);
632 if (mLowBatteryDialog != null) {
633 mLowBatteryDialog.dismiss();
634 }
635 }
636 });
637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638
639 AlertDialog d = b.create();
640 d.setOnDismissListener(mLowBatteryListener);
641 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
642 d.show();
643 mLowBatteryDialog = d;
644 }
Daniel Sandler0e9d2af2010-01-25 11:33:03 -0500645
646 final ContentResolver cr = mContext.getContentResolver();
647 if (Settings.System.getInt(cr,
John Wang56c2d2f2010-04-07 08:57:17 -0700648 Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)
Daniel Sandler0e9d2af2010-01-25 11:33:03 -0500649 {
650 final String soundPath = Settings.System.getString(cr,
651 Settings.System.LOW_BATTERY_SOUND);
652 if (soundPath != null) {
653 final Uri soundUri = Uri.parse("file://" + soundPath);
654 if (soundUri != null) {
655 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
Daniel Sandlerec2c88d2010-02-20 01:04:57 -0500656 if (sfx != null) {
657 sfx.setStreamType(AudioManager.STREAM_SYSTEM);
658 sfx.play();
659 }
Daniel Sandler0e9d2af2010-01-25 11:33:03 -0500660 }
661 }
662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 }
664
665 private final void updateCallState(int state) {
666 mPhoneState = state;
667 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800668 Slog.d(TAG, "mPhoneState=" + mPhoneState
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669 + " mLowBatteryDialog=" + mLowBatteryDialog
670 + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
671 }
672 if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
673 if (mBatteryShowLowOnEndCall) {
674 if (!mBatteryPlugged) {
675 showLowBatteryWarning();
676 }
677 mBatteryShowLowOnEndCall = false;
678 }
679 } else {
680 if (mLowBatteryDialog != null) {
681 mLowBatteryDialog.dismiss();
682 mBatteryShowLowOnEndCall = true;
683 }
684 }
685 }
686
687 private DialogInterface.OnDismissListener mLowBatteryListener
688 = new DialogInterface.OnDismissListener() {
689 public void onDismiss(DialogInterface dialog) {
690 mLowBatteryDialog = null;
691 mBatteryLevelTextView = null;
692 }
693 };
694
695 private void scheduleCloseBatteryView() {
696 Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE);
697 m.arg1 = (++mBatteryViewSequence);
698 mHandler.sendMessageDelayed(m, 3000);
699 }
700
701 private void closeLastBatteryView() {
702 if (mBatteryView != null) {
703 //mBatteryView.debug();
704 WindowManagerImpl.getDefault().removeView(mBatteryView);
705 mBatteryView = null;
706 }
707 }
708
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700709 private void updateConnectivity(Intent intent) {
710 NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra(
711 ConnectivityManager.EXTRA_NETWORK_INFO));
712 int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
713 Slog.d(TAG, "got CONNECTIVITY_ACTION - info=" + info + ", status = " + connectionStatus);
714 if (info.isConnected() == false) return;
715
716 switch (info.getType()) {
717 case ConnectivityManager.TYPE_MOBILE:
718 if (info.isConnected()) {
719 updateDataNetType(info.getSubtype(), connectionStatus);
720 updateDataIcon();
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700721 updateSignalStrength(); // apply any change in connectionStatus
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700722 }
723 break;
724 case ConnectivityManager.TYPE_WIFI:
725 if (info.isConnected()) {
726 mIsWifiConnected = true;
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700727 mInetCondition =
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700728 (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
729 int iconId;
730 if (mLastWifiSignalLevel == -1) {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700731 iconId = sWifiSignalImages[mInetCondition][0];
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700732 } else {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700733 iconId = sWifiSignalImages[mInetCondition][mLastWifiSignalLevel];
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700734 }
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700735 mService.setIcon("wifi", iconId, 0);
736 // Show the icon since wi-fi is connected
737 mService.setIconVisibility("wifi", true);
738 } else {
739 mLastWifiSignalLevel = -1;
740 mIsWifiConnected = false;
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700741 mInetCondition = 0;
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700742 int iconId = sWifiSignalImages[0][0];
743
744 mService.setIcon("wifi", iconId, 0);
745 // Hide the icon since we're not connected
746 mService.setIconVisibility("wifi", false);
747 }
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700748 updateSignalStrength(); // apply any change in mInetCondition
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700749 break;
750 }
751 }
752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
754 @Override
Wink Savillee9b06d72009-05-18 21:47:50 -0700755 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
756 mSignalStrength = signalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 updateSignalStrength();
758 }
759
760 @Override
761 public void onServiceStateChanged(ServiceState state) {
762 mServiceState = state;
763 updateSignalStrength();
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700764 updateCdmaRoamingIcon(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 updateDataIcon();
766 }
767
768 @Override
769 public void onCallStateChanged(int state, String incomingNumber) {
770 updateCallState(state);
johnwang347c5a22009-08-24 22:11:11 -0700771 // In cdma, if a voice call is made, RSSI should switch to 1x.
772 if (isCdma()) {
773 updateSignalStrength();
774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 }
776
777 @Override
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700778 public void onDataConnectionStateChanged(int state, int networkType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 mDataState = state;
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700780 updateDataNetType(networkType, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 updateDataIcon();
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700782 updateSignalStrength(); // apply the change in connection status
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 }
784
785 @Override
786 public void onDataActivity(int direction) {
787 mDataActivity = direction;
788 updateDataIcon();
789 }
790 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791
792 private final void updateSimState(Intent intent) {
Wink Saville04e71b32009-04-02 11:00:54 -0700793 String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
794 if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
795 mSimState = IccCard.State.ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
Wink Saville04e71b32009-04-02 11:00:54 -0700797 else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
798 mSimState = IccCard.State.READY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
Wink Saville04e71b32009-04-02 11:00:54 -0700800 else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
801 final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
802 if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
803 mSimState = IccCard.State.PIN_REQUIRED;
johnwang347c5a22009-08-24 22:11:11 -0700804 }
Wink Saville04e71b32009-04-02 11:00:54 -0700805 else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
806 mSimState = IccCard.State.PUK_REQUIRED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 }
808 else {
Wink Saville04e71b32009-04-02 11:00:54 -0700809 mSimState = IccCard.State.NETWORK_LOCKED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 }
811 } else {
Wink Saville04e71b32009-04-02 11:00:54 -0700812 mSimState = IccCard.State.UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 }
814 updateDataIcon();
815 }
816
Wink Savillee9b06d72009-05-18 21:47:50 -0700817 private boolean isCdma() {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700818 return (mSignalStrength != null) && !mSignalStrength.isGsm();
Wink Savillee9b06d72009-05-18 21:47:50 -0700819 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820
johnwang347c5a22009-08-24 22:11:11 -0700821 private boolean isEvdo() {
822 return ( (mServiceState != null)
823 && ((mServiceState.getRadioTechnology()
824 == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
825 || (mServiceState.getRadioTechnology()
Naveen Kalla0a5174a2010-04-21 14:48:03 -0700826 == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
827 || (mServiceState.getRadioTechnology()
828 == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
johnwang347c5a22009-08-24 22:11:11 -0700829 }
830
Wink Savillee9b06d72009-05-18 21:47:50 -0700831 private boolean hasService() {
832 if (mServiceState != null) {
833 switch (mServiceState.getState()) {
834 case ServiceState.STATE_OUT_OF_SERVICE:
835 case ServiceState.STATE_POWER_OFF:
836 return false;
837 default:
838 return true;
839 }
840 } else {
841 return false;
842 }
843 }
844
845 private final void updateSignalStrength() {
846 int iconLevel = -1;
Wink Savillee9b06d72009-05-18 21:47:50 -0700847 int[] iconList;
Wink Savillee9b06d72009-05-18 21:47:50 -0700848
John Wang56c2d2f2010-04-07 08:57:17 -0700849 // Display signal strength while in "emergency calls only" mode
850 if (!hasService() && !mServiceState.isEmergencyOnly()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800851 //Slog.d(TAG, "updateSignalStrength: no service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 if (Settings.System.getInt(mContext.getContentResolver(),
853 Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400854 mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 } else {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400856 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 }
Joe Onorato798ac4c2010-05-27 16:39:00 -0400858 mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 return;
860 }
861
Wink Savillee9b06d72009-05-18 21:47:50 -0700862 if (!isCdma()) {
863 int asu = mSignalStrength.getGsmSignalStrength();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864
Wink Savillee9b06d72009-05-18 21:47:50 -0700865 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
866 // asu = 0 (-113dB or less) is very weak
867 // signal, its better to show 0 bars to the user in such cases.
868 // asu = 99 is a special case, where the signal strength is unknown.
jshee63e472010-03-18 11:14:42 -0700869 if (asu <= 2 || asu == 99) iconLevel = 0;
870 else if (asu >= 12) iconLevel = 4;
Wink Savillee9b06d72009-05-18 21:47:50 -0700871 else if (asu >= 8) iconLevel = 3;
jshee63e472010-03-18 11:14:42 -0700872 else if (asu >= 5) iconLevel = 2;
Wink Savillee9b06d72009-05-18 21:47:50 -0700873 else iconLevel = 1;
874
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700875 // Though mPhone is a Manager, this call is not an IPC
Wink Savillee9b06d72009-05-18 21:47:50 -0700876 if (mPhone.isNetworkRoaming()) {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700877 iconList = sSignalImages_r[mInetCondition];
Wink Savillee9b06d72009-05-18 21:47:50 -0700878 } else {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700879 iconList = sSignalImages[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 } else {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700882 iconList = sSignalImages[mInetCondition];
Wink Savillee9b06d72009-05-18 21:47:50 -0700883
johnwang347c5a22009-08-24 22:11:11 -0700884 // If 3G(EV) and 1x network are available than 3G should be
885 // displayed, displayed RSSI should be from the EV side.
886 // If a voice call is made then RSSI should switch to 1x.
887 if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
888 iconLevel = getEvdoLevel();
889 if (false) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800890 Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel());
johnwang347c5a22009-08-24 22:11:11 -0700891 }
892 } else {
893 iconLevel = getCdmaLevel();
894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 }
Joe Onorato0cbda992010-05-02 16:28:15 -0700896 mPhoneSignalIconId = iconList[iconLevel];
Joe Onorato798ac4c2010-05-27 16:39:00 -0400897 mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 }
899
johnwang347c5a22009-08-24 22:11:11 -0700900 private int getCdmaLevel() {
901 final int cdmaDbm = mSignalStrength.getCdmaDbm();
902 final int cdmaEcio = mSignalStrength.getCdmaEcio();
903 int levelDbm = 0;
904 int levelEcio = 0;
905
906 if (cdmaDbm >= -75) levelDbm = 4;
907 else if (cdmaDbm >= -85) levelDbm = 3;
908 else if (cdmaDbm >= -95) levelDbm = 2;
909 else if (cdmaDbm >= -100) levelDbm = 1;
910 else levelDbm = 0;
911
912 // Ec/Io are in dB*10
913 if (cdmaEcio >= -90) levelEcio = 4;
914 else if (cdmaEcio >= -110) levelEcio = 3;
915 else if (cdmaEcio >= -130) levelEcio = 2;
916 else if (cdmaEcio >= -150) levelEcio = 1;
917 else levelEcio = 0;
918
919 return (levelDbm < levelEcio) ? levelDbm : levelEcio;
920 }
921
922 private int getEvdoLevel() {
923 int evdoDbm = mSignalStrength.getEvdoDbm();
924 int evdoSnr = mSignalStrength.getEvdoSnr();
925 int levelEvdoDbm = 0;
926 int levelEvdoSnr = 0;
927
928 if (evdoDbm >= -65) levelEvdoDbm = 4;
929 else if (evdoDbm >= -75) levelEvdoDbm = 3;
930 else if (evdoDbm >= -90) levelEvdoDbm = 2;
931 else if (evdoDbm >= -105) levelEvdoDbm = 1;
932 else levelEvdoDbm = 0;
933
John Michelau1336a562009-09-28 10:41:02 -0500934 if (evdoSnr >= 7) levelEvdoSnr = 4;
935 else if (evdoSnr >= 5) levelEvdoSnr = 3;
936 else if (evdoSnr >= 3) levelEvdoSnr = 2;
937 else if (evdoSnr >= 1) levelEvdoSnr = 1;
johnwang347c5a22009-08-24 22:11:11 -0700938 else levelEvdoSnr = 0;
939
940 return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
941 }
942
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700943 private final void updateDataNetType(int net, int inetCondition) {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700944 mInetCondition = (inetCondition > INET_CONDITION_THRESHOLD ? 1 : 0);
Wink Saville04e71b32009-04-02 11:00:54 -0700945 switch (net) {
Wink Saville04e71b32009-04-02 11:00:54 -0700946 case TelephonyManager.NETWORK_TYPE_EDGE:
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700947 mDataIconList = sDataNetType_e[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700948 break;
949 case TelephonyManager.NETWORK_TYPE_UMTS:
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700950 mDataIconList = sDataNetType_3g[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700951 break;
Li Zheebe66342009-08-14 19:22:16 +0800952 case TelephonyManager.NETWORK_TYPE_HSDPA:
953 case TelephonyManager.NETWORK_TYPE_HSUPA:
954 case TelephonyManager.NETWORK_TYPE_HSPA:
John Wang33e21fc2009-10-08 10:35:27 -0700955 if (mHspaDataDistinguishable) {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700956 mDataIconList = sDataNetType_h[mInetCondition];
John Wang33e21fc2009-10-08 10:35:27 -0700957 } else {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700958 mDataIconList = sDataNetType_3g[mInetCondition];
John Wang33e21fc2009-10-08 10:35:27 -0700959 }
Li Zheebe66342009-08-14 19:22:16 +0800960 break;
Wink Saville04e71b32009-04-02 11:00:54 -0700961 case TelephonyManager.NETWORK_TYPE_CDMA:
962 // display 1xRTT for IS95A/B
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700963 mDataIconList = sDataNetType_1x[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700964 break;
965 case TelephonyManager.NETWORK_TYPE_1xRTT:
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700966 mDataIconList = sDataNetType_1x[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700967 break;
968 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
969 case TelephonyManager.NETWORK_TYPE_EVDO_A:
Naveen Kalla0a5174a2010-04-21 14:48:03 -0700970 case TelephonyManager.NETWORK_TYPE_EVDO_B:
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700971 mDataIconList = sDataNetType_3g[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700972 break;
973 default:
Robert Greenwalt1e9aac22010-09-15 17:36:33 -0700974 mDataIconList = sDataNetType_g[mInetCondition];
Wink Saville04e71b32009-04-02 11:00:54 -0700975 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 }
977 }
978
979 private final void updateDataIcon() {
980 int iconId;
981 boolean visible = true;
982
Wink Savillee9b06d72009-05-18 21:47:50 -0700983 if (!isCdma()) {
984 // GSM case, we have to check also the sim state
985 if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
986 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
987 switch (mDataActivity) {
988 case TelephonyManager.DATA_ACTIVITY_IN:
989 iconId = mDataIconList[1];
990 break;
991 case TelephonyManager.DATA_ACTIVITY_OUT:
992 iconId = mDataIconList[2];
993 break;
994 case TelephonyManager.DATA_ACTIVITY_INOUT:
995 iconId = mDataIconList[3];
996 break;
997 default:
998 iconId = mDataIconList[0];
999 break;
1000 }
Joe Onorato798ac4c2010-05-27 16:39:00 -04001001 mService.setIcon("data_connection", iconId, 0);
Wink Savillee9b06d72009-05-18 21:47:50 -07001002 } else {
1003 visible = false;
1004 }
1005 } else {
Joe Onorato798ac4c2010-05-27 16:39:00 -04001006 iconId = R.drawable.stat_sys_no_sim;
1007 mService.setIcon("data_connection", iconId, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001009 } else {
1010 // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
1011 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 switch (mDataActivity) {
1013 case TelephonyManager.DATA_ACTIVITY_IN:
Wink Savillee9b06d72009-05-18 21:47:50 -07001014 iconId = mDataIconList[1];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 break;
1016 case TelephonyManager.DATA_ACTIVITY_OUT:
Wink Savillee9b06d72009-05-18 21:47:50 -07001017 iconId = mDataIconList[2];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 break;
1019 case TelephonyManager.DATA_ACTIVITY_INOUT:
Wink Savillee9b06d72009-05-18 21:47:50 -07001020 iconId = mDataIconList[3];
1021 break;
1022 case TelephonyManager.DATA_ACTIVITY_DORMANT:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 default:
Wink Savillee9b06d72009-05-18 21:47:50 -07001024 iconId = mDataIconList[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 break;
1026 }
Joe Onorato798ac4c2010-05-27 16:39:00 -04001027 mService.setIcon("data_connection", iconId, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 } else {
1029 visible = false;
1030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001032
Dianne Hackborn4840e142009-03-24 22:40:29 -07001033 long ident = Binder.clearCallingIdentity();
1034 try {
Wink Saville04e71b32009-04-02 11:00:54 -07001035 mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
Dianne Hackborn4840e142009-03-24 22:40:29 -07001036 } catch (RemoteException e) {
1037 } finally {
1038 Binder.restoreCallingIdentity(ident);
1039 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 if (mDataIconVisible != visible) {
Joe Onorato0cbda992010-05-02 16:28:15 -07001042 mService.setIconVisibility("data_connection", visible);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 mDataIconVisible = visible;
1044 }
1045 }
1046
1047 private final void updateVolume() {
1048 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
1049 final int ringerMode = audioManager.getRingerMode();
1050 final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
Wink Savillee9b06d72009-05-18 21:47:50 -07001051 ringerMode == AudioManager.RINGER_MODE_VIBRATE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
Joe Onorato798ac4c2010-05-27 16:39:00 -04001053 ? R.drawable.stat_sys_ringer_vibrate
1054 : R.drawable.stat_sys_ringer_silent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055
1056 if (visible) {
Joe Onorato798ac4c2010-05-27 16:39:00 -04001057 mService.setIcon("volume", iconId, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 }
1059 if (visible != mVolumeVisible) {
Joe Onorato0cbda992010-05-02 16:28:15 -07001060 mService.setIconVisibility("volume", visible);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 mVolumeVisible = visible;
1062 }
1063 }
1064
1065 private final void updateBluetooth(Intent intent) {
Joe Onorato798ac4c2010-05-27 16:39:00 -04001066 int iconId = R.drawable.stat_sys_data_bluetooth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 String action = intent.getAction();
Nick Pellyde893f52009-09-08 13:15:33 -07001068 if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
Nick Pellyb24e11b2009-09-08 17:40:43 -07001069 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
Nick Pellyde893f52009-09-08 13:15:33 -07001070 mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
Nick Pelly005b2282009-09-10 10:21:56 -07001071 } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
1072 mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001073 BluetoothHeadset.STATE_ERROR);
Nick Pelly005b2282009-09-10 10:21:56 -07001074 } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
Jaikumar Ganesh084c6652009-12-07 10:58:18 -08001075 BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
1076 if (a2dp.getConnectedSinks().size() != 0) {
1077 mBluetoothA2dpConnected = true;
1078 } else {
1079 mBluetoothA2dpConnected = false;
1080 }
Jiafa Liu3f416732009-07-02 16:36:02 +08001081 } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
1082 mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
1083 BluetoothPbap.STATE_DISCONNECTED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 } else {
1085 return;
1086 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001087
Jaikumar Ganesh084c6652009-12-07 10:58:18 -08001088 if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
Jiafa Liu3f416732009-07-02 16:36:02 +08001089 mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
Joe Onorato798ac4c2010-05-27 16:39:00 -04001090 iconId = R.drawable.stat_sys_data_bluetooth_connected;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 }
1092
Joe Onorato798ac4c2010-05-27 16:39:00 -04001093 mService.setIcon("bluetooth", iconId, 0);
Joe Onorato0cbda992010-05-02 16:28:15 -07001094 mService.setIconVisibility("bluetooth", mBluetoothEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 }
1096
1097 private final void updateWifi(Intent intent) {
1098 final String action = intent.getAction();
1099 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
Wink Savillee9b06d72009-05-18 21:47:50 -07001100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
1102 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
Wink Savillee9b06d72009-05-18 21:47:50 -07001103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 if (!enabled) {
1105 // If disabled, hide the icon. (We show icon when connected.)
Joe Onorato0cbda992010-05-02 16:28:15 -07001106 mService.setIconVisibility("wifi", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
1110 final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED,
1111 false);
1112 if (!enabled) {
Joe Onorato0cbda992010-05-02 16:28:15 -07001113 mService.setIconVisibility("wifi", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
Joe Onorato0cbda992010-05-02 16:28:15 -07001116 int iconId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
1118 int newSignalLevel = WifiManager.calculateSignalLevel(newRssi,
Robert Greenwaltfa974c52010-09-13 15:53:26 -07001119 sWifiSignalImages[0].length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 if (newSignalLevel != mLastWifiSignalLevel) {
1121 mLastWifiSignalLevel = newSignalLevel;
1122 if (mIsWifiConnected) {
Robert Greenwalt1e9aac22010-09-15 17:36:33 -07001123 iconId = sWifiSignalImages[mInetCondition][newSignalLevel];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 } else {
Joe Onorato0cbda992010-05-02 16:28:15 -07001125 iconId = sWifiTemporarilyNotConnectedImage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 }
Joe Onorato798ac4c2010-05-27 16:39:00 -04001127 mService.setIcon("wifi", iconId, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 }
1129 }
1130 }
1131
1132 private final void updateGps(Intent intent) {
1133 final String action = intent.getAction();
Mike Lockwood00b74272010-03-26 10:41:48 -04001134 final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135
Mike Lockwood00b74272010-03-26 10:41:48 -04001136 if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 // GPS is getting fixes
Joe Onorato798ac4c2010-05-27 16:39:00 -04001138 mService.setIcon("gps", com.android.internal.R.drawable.stat_sys_gps_on, 0);
Joe Onorato0cbda992010-05-02 16:28:15 -07001139 mService.setIconVisibility("gps", true);
Mike Lockwood00b74272010-03-26 10:41:48 -04001140 } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 // GPS is off
Joe Onorato0cbda992010-05-02 16:28:15 -07001142 mService.setIconVisibility("gps", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 } else {
1144 // GPS is on, but not receiving fixes
Joe Onorato798ac4c2010-05-27 16:39:00 -04001145 mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
Joe Onorato0cbda992010-05-02 16:28:15 -07001146 mService.setIconVisibility("gps", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 }
1148 }
1149
Wink Savillee9b06d72009-05-18 21:47:50 -07001150 private final void updateTTY(Intent intent) {
Wink Saville04e71b32009-04-02 11:00:54 -07001151 final String action = intent.getAction();
1152 final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
1153
Joe Onorato8a9b2202010-02-26 18:56:32 -08001154 if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled);
Wink Saville04e71b32009-04-02 11:00:54 -07001155
1156 if (enabled) {
1157 // TTY is on
Joe Onorato8a9b2202010-02-26 18:56:32 -08001158 if (false) Slog.v(TAG, "updateTTY: set TTY on");
Joe Onorato798ac4c2010-05-27 16:39:00 -04001159 mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0);
Joe Onorato0cbda992010-05-02 16:28:15 -07001160 mService.setIconVisibility("tty", true);
Wink Saville04e71b32009-04-02 11:00:54 -07001161 } else {
1162 // TTY is off
Joe Onorato8a9b2202010-02-26 18:56:32 -08001163 if (false) Slog.v(TAG, "updateTTY: set TTY off");
Joe Onorato0cbda992010-05-02 16:28:15 -07001164 mService.setIconVisibility("tty", false);
Wink Saville04e71b32009-04-02 11:00:54 -07001165 }
1166 }
1167
Robert Greenwalt98e0b142009-10-08 21:15:52 -07001168 private final void updateCdmaRoamingIcon(ServiceState state) {
Wink Savillee9b06d72009-05-18 21:47:50 -07001169 if (!hasService()) {
Joe Onorato0cbda992010-05-02 16:28:15 -07001170 mService.setIconVisibility("cdma_eri", false);
Wink Savillef3152382009-06-01 14:39:20 -07001171 return;
Wink Savillee9b06d72009-05-18 21:47:50 -07001172 }
1173
1174 if (!isCdma()) {
Joe Onorato0cbda992010-05-02 16:28:15 -07001175 mService.setIconVisibility("cdma_eri", false);
Wink Savillef3152382009-06-01 14:39:20 -07001176 return;
Wink Savillee9b06d72009-05-18 21:47:50 -07001177 }
1178
1179 int[] iconList = sRoamingIndicatorImages_cdma;
Robert Greenwalt98e0b142009-10-08 21:15:52 -07001180 int iconIndex = state.getCdmaEriIconIndex();
1181 int iconMode = state.getCdmaEriIconMode();
Wink Savillee9b06d72009-05-18 21:47:50 -07001182
1183 if (iconIndex == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001184 Slog.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update");
Wink Savillee9b06d72009-05-18 21:47:50 -07001185 return;
1186 }
1187
1188 if (iconMode == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001189 Slog.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update");
Wink Savillee9b06d72009-05-18 21:47:50 -07001190 return;
1191 }
1192
1193 if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001194 if (false) Slog.v(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon");
Joe Onorato0cbda992010-05-02 16:28:15 -07001195 mService.setIconVisibility("cdma_eri", false);
Wink Savillee9b06d72009-05-18 21:47:50 -07001196 return;
1197 }
1198
1199 switch (iconMode) {
1200 case EriInfo.ROAMING_ICON_MODE_NORMAL:
Joe Onorato798ac4c2010-05-27 16:39:00 -04001201 mService.setIcon("cdma_eri", iconList[iconIndex], 0);
Joe Onorato0cbda992010-05-02 16:28:15 -07001202 mService.setIconVisibility("cdma_eri", true);
Wink Savillee9b06d72009-05-18 21:47:50 -07001203 break;
1204 case EriInfo.ROAMING_ICON_MODE_FLASH:
Joe Onorato798ac4c2010-05-27 16:39:00 -04001205 mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_flash, 0);
Joe Onorato0cbda992010-05-02 16:28:15 -07001206 mService.setIconVisibility("cdma_eri", true);
Wink Savillee9b06d72009-05-18 21:47:50 -07001207 break;
1208
1209 }
Joe Onorato798ac4c2010-05-27 16:39:00 -04001210 mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
Wink Savillee9b06d72009-05-18 21:47:50 -07001211 }
1212
1213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 private class StatusBarHandler extends Handler {
1215 @Override
1216 public void handleMessage(Message msg) {
1217 switch (msg.what) {
1218 case EVENT_BATTERY_CLOSE:
1219 if (msg.arg1 == mBatteryViewSequence) {
1220 closeLastBatteryView();
1221 }
1222 break;
1223 }
1224 }
1225 }
1226}