blob: 42c02540dbc16cb9c056fd7a8caa7f23e281edd1 [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
17package com.android.server.status;
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.app.AlertDialog;
20import android.bluetooth.BluetoothA2dp;
Nick Pellybd022f42009-08-14 18:33:38 -070021import android.bluetooth.BluetoothAdapter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.bluetooth.BluetoothHeadset;
Jiafa Liu3f416732009-07-02 16:36:02 +080023import android.bluetooth.BluetoothPbap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.BroadcastReceiver;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.Intent;
28import android.content.IntentFilter;
29import android.content.res.TypedArray;
30import android.graphics.PixelFormat;
31import android.graphics.drawable.Drawable;
32import android.media.AudioManager;
33import android.net.NetworkInfo;
34import android.net.wifi.WifiManager;
Dianne Hackborn4840e142009-03-24 22:40:29 -070035import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.Handler;
37import android.os.IBinder;
38import android.os.Message;
Dianne Hackborn4840e142009-03-24 22:40:29 -070039import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.provider.Settings;
41import android.telephony.PhoneStateListener;
42import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070043import android.telephony.SignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.telephony.TelephonyManager;
45import android.text.format.DateFormat;
Eric Fischer36e136c2010-01-14 17:42:48 -080046import android.text.style.RelativeSizeSpan;
47import android.text.Spannable;
48import android.text.SpannableStringBuilder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.util.Log;
50import android.view.View;
51import android.view.ViewGroup;
52import android.view.WindowManager;
53import android.view.WindowManagerImpl;
54import android.widget.ImageView;
55import android.widget.LinearLayout;
56import android.widget.TextView;
57
Wink Saville04e71b32009-04-02 11:00:54 -070058import com.android.internal.R;
59import com.android.internal.app.IBatteryStats;
60import com.android.internal.location.GpsLocationProvider;
61import com.android.internal.telephony.IccCard;
62import com.android.internal.telephony.TelephonyIntents;
Wink Savillee9b06d72009-05-18 21:47:50 -070063import com.android.internal.telephony.cdma.EriInfo;
Wink Saville04e71b32009-04-02 11:00:54 -070064import com.android.internal.telephony.cdma.TtyIntent;
65import com.android.server.am.BatteryStatsService;
66
Eric Fischer36e136c2010-01-14 17:42:48 -080067import java.text.SimpleDateFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import java.util.Calendar;
69import java.util.TimeZone;
70
71/**
72 * This class contains all of the policy about which icons are installed in the status
73 * bar at boot time. In reality, it should go into the android.policy package, but
74 * putting it here is the first step from extracting it.
75 */
76public class StatusBarPolicy {
77 private static final String TAG = "StatusBarPolicy";
78
79 private static StatusBarPolicy sInstance;
80
81 // message codes for the handler
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 private static final int EVENT_BATTERY_CLOSE = 4;
83
Dianne Hackborn4840e142009-03-24 22:40:29 -070084 private final Context mContext;
85 private final StatusBarService mService;
86 private final Handler mHandler = new StatusBarHandler();
87 private final IBatteryStats mBatteryStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89 // clock
90 private Calendar mCalendar;
91 private IBinder mClockIcon;
92 private IconData mClockData;
93
94 // battery
95 private IBinder mBatteryIcon;
96 private IconData mBatteryData;
97 private boolean mBatteryFirst = true;
98 private boolean mBatteryPlugged;
99 private int mBatteryLevel;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 private AlertDialog mLowBatteryDialog;
101 private TextView mBatteryLevelTextView;
102 private View mBatteryView;
103 private int mBatteryViewSequence;
104 private boolean mBatteryShowLowOnEndCall = false;
105 private static final boolean SHOW_LOW_BATTERY_WARNING = true;
106
107 // phone
108 private TelephonyManager mPhone;
109 private IBinder mPhoneIcon;
Wink Saville04e71b32009-04-02 11:00:54 -0700110
111 //***** Signal strength icons
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 private IconData mPhoneData;
Wink Saville04e71b32009-04-02 11:00:54 -0700113 //GSM/UMTS
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 private static final int[] sSignalImages = new int[] {
Wink Savillee9b06d72009-05-18 21:47:50 -0700115 com.android.internal.R.drawable.stat_sys_signal_0,
116 com.android.internal.R.drawable.stat_sys_signal_1,
117 com.android.internal.R.drawable.stat_sys_signal_2,
118 com.android.internal.R.drawable.stat_sys_signal_3,
119 com.android.internal.R.drawable.stat_sys_signal_4
120 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 private static final int[] sSignalImages_r = new int[] {
Wink Savillee9b06d72009-05-18 21:47:50 -0700122 com.android.internal.R.drawable.stat_sys_r_signal_0,
123 com.android.internal.R.drawable.stat_sys_r_signal_1,
124 com.android.internal.R.drawable.stat_sys_r_signal_2,
125 com.android.internal.R.drawable.stat_sys_r_signal_3,
126 com.android.internal.R.drawable.stat_sys_r_signal_4
127 };
Wink Savillee9b06d72009-05-18 21:47:50 -0700128 private static final int[] sRoamingIndicatorImages_cdma = new int[] {
129 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator
130 // 1 is Standard Roaming Indicator OFF
131 // TODO T: image never used, remove and put 0 instead?
132 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
133
134 // 2 is Standard Roaming Indicator FLASHING
135 // TODO T: image never used, remove and put 0 instead?
136 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
137
138 // 3-12 Standard ERI
139 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //3
140 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
141 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
142 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
143 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
144 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
145 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
146 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
147 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
148 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
149
150 // 13-63 Reserved for Standard ERI
151 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //13
152 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
153 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
154 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
155 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
156 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
157 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
158 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
159 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
160 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
161 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
162 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
163 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
164 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
165 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
166 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
167 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
168 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
169 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
170 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
171 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
172 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
173 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
174 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
175 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
176 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
177 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
178 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
179 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
180 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
181 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
182 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
183 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
184 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
185 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
186 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
187 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
188 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
189 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
190 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
191 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
192 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
193 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
194 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
195 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
196 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
197 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
198 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
199 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
200 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
201 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
202
203 // 64-127 Reserved for Non Standard (Operator Specific) ERI
204 com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //64
205 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
206 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
207 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
208 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
209 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
210 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
211 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
212 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
213 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
214 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
215 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
216 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
217 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
218 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
219 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
220 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
221 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
222 com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
223 com.android.internal.R.drawable.stat_sys_roaming_cdma_0 //83
224
225 // 128-255 Reserved
Wink Saville04e71b32009-04-02 11:00:54 -0700226 };
Wink Saville04e71b32009-04-02 11:00:54 -0700227
228 //***** Data connection icons
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 private int[] mDataIconList = sDataNetType_g;
Wink Saville04e71b32009-04-02 11:00:54 -0700230 //GSM/UMTS
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 private static final int[] sDataNetType_g = new int[] {
232 com.android.internal.R.drawable.stat_sys_data_connected_g,
233 com.android.internal.R.drawable.stat_sys_data_in_g,
234 com.android.internal.R.drawable.stat_sys_data_out_g,
235 com.android.internal.R.drawable.stat_sys_data_inandout_g,
236 };
237 private static final int[] sDataNetType_3g = new int[] {
238 com.android.internal.R.drawable.stat_sys_data_connected_3g,
239 com.android.internal.R.drawable.stat_sys_data_in_3g,
240 com.android.internal.R.drawable.stat_sys_data_out_3g,
241 com.android.internal.R.drawable.stat_sys_data_inandout_3g,
242 };
243 private static final int[] sDataNetType_e = new int[] {
244 com.android.internal.R.drawable.stat_sys_data_connected_e,
245 com.android.internal.R.drawable.stat_sys_data_in_e,
246 com.android.internal.R.drawable.stat_sys_data_out_e,
247 com.android.internal.R.drawable.stat_sys_data_inandout_e,
248 };
Li Zheebe66342009-08-14 19:22:16 +0800249 //3.5G
250 private static final int[] sDataNetType_h = new int[] {
251 com.android.internal.R.drawable.stat_sys_data_connected_h,
252 com.android.internal.R.drawable.stat_sys_data_in_h,
253 com.android.internal.R.drawable.stat_sys_data_out_h,
254 com.android.internal.R.drawable.stat_sys_data_inandout_h,
255 };
256
Wink Saville04e71b32009-04-02 11:00:54 -0700257 //CDMA
johnwang9f87cb22009-08-25 15:25:37 -0700258 // Use 3G icons for EVDO data and 1x icons for 1XRTT data
259 private static final int[] sDataNetType_1x = new int[] {
260 com.android.internal.R.drawable.stat_sys_data_connected_1x,
261 com.android.internal.R.drawable.stat_sys_data_in_1x,
262 com.android.internal.R.drawable.stat_sys_data_out_1x,
263 com.android.internal.R.drawable.stat_sys_data_inandout_1x,
Wink Saville04e71b32009-04-02 11:00:54 -0700264 };
265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 // Assume it's all good unless we hear otherwise. We don't always seem
267 // to get broadcasts that it *is* there.
Wink Saville04e71b32009-04-02 11:00:54 -0700268 IccCard.State mSimState = IccCard.State.READY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
270 int mDataState = TelephonyManager.DATA_DISCONNECTED;
271 int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
272 ServiceState mServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -0700273 SignalStrength mSignalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274
275 // data connection
276 private IBinder mDataIcon;
277 private IconData mDataData;
278 private boolean mDataIconVisible;
John Wang33e21fc2009-10-08 10:35:27 -0700279 private boolean mHspaDataDistinguishable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
281 // ringer volume
282 private IBinder mVolumeIcon;
283 private IconData mVolumeData;
284 private boolean mVolumeVisible;
Wink Saville04e71b32009-04-02 11:00:54 -0700285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 // bluetooth device status
287 private IBinder mBluetoothIcon;
288 private IconData mBluetoothData;
289 private int mBluetoothHeadsetState;
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800290 private boolean mBluetoothA2dpConnected;
Jiafa Liu3f416732009-07-02 16:36:02 +0800291 private int mBluetoothPbapState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 private boolean mBluetoothEnabled;
293
294 // wifi
295 private static final int[] sWifiSignalImages = new int[] {
296 com.android.internal.R.drawable.stat_sys_wifi_signal_1,
297 com.android.internal.R.drawable.stat_sys_wifi_signal_2,
298 com.android.internal.R.drawable.stat_sys_wifi_signal_3,
299 com.android.internal.R.drawable.stat_sys_wifi_signal_4,
300 };
301 private static final int sWifiTemporarilyNotConnectedImage =
302 com.android.internal.R.drawable.stat_sys_wifi_signal_0;
303
304 private int mLastWifiSignalLevel = -1;
305 private boolean mIsWifiConnected = false;
306 private IBinder mWifiIcon;
307 private IconData mWifiData;
308
309 // gps
310 private IBinder mGpsIcon;
311 private IconData mGpsEnabledIconData;
312 private IconData mGpsFixIconData;
313
314 // alarm clock
315 // Icon lit when clock is set
316 private IBinder mAlarmClockIcon;
317 private IconData mAlarmClockIconData;
318
319 // sync state
320 // If sync is active the SyncActive icon is displayed. If sync is not active but
321 // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed.
322 private IBinder mSyncActiveIcon;
323 private IBinder mSyncFailingIcon;
324
Wink Saville04e71b32009-04-02 11:00:54 -0700325 // TTY mode
326 // Icon lit when TTY mode is enabled
327 private IBinder mTTYModeIcon;
328 private IconData mTTYModeEnableIconData;
329
Wink Savillee9b06d72009-05-18 21:47:50 -0700330 // Cdma Roaming Indicator, ERI
331 private IBinder mCdmaRoamingIndicatorIcon;
332 private IconData mCdmaRoamingIndicatorIconData;
333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
335 @Override
336 public void onReceive(Context context, Intent intent) {
337 String action = intent.getAction();
338 if (action.equals(Intent.ACTION_TIME_TICK)) {
339 updateClock();
340 }
341 else if (action.equals(Intent.ACTION_TIME_CHANGED)) {
342 updateClock();
343 }
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700344 else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
345 updateBattery(intent);
346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
348 updateClock();
349 }
350 else if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
351 String tz = intent.getStringExtra("time-zone");
352 mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz));
353 updateClock();
354 }
355 else if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
356 updateAlarm(intent);
357 }
358 else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
359 updateSyncState(intent);
360 }
Mihai Predaa82842f2009-04-29 15:05:56 +0200361 else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
362 onBatteryLow(intent);
363 }
Mike Lockwood69eb0bf2009-08-01 23:02:28 -0400364 else if (action.equals(Intent.ACTION_BATTERY_OKAY)
365 || action.equals(Intent.ACTION_POWER_CONNECTED)) {
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700366 onBatteryOkay(intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 }
Nick Pellyde893f52009-09-08 13:15:33 -0700368 else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
Nick Pelly005b2282009-09-10 10:21:56 -0700369 action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) ||
370 action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ||
Jiafa Liu3f416732009-07-02 16:36:02 +0800371 action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 updateBluetooth(intent);
373 }
374 else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) ||
375 action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) ||
376 action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
377 updateWifi(intent);
378 }
379 else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION) ||
380 action.equals(GpsLocationProvider.GPS_FIX_CHANGE_ACTION)) {
381 updateGps(intent);
382 }
383 else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
384 action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
385 updateVolume();
386 }
387 else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
388 updateSimState(intent);
389 }
Wink Saville04e71b32009-04-02 11:00:54 -0700390 else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
391 updateTTY(intent);
392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 }
394 };
395
396 private StatusBarPolicy(Context context, StatusBarService service) {
397 mContext = context;
398 mService = service;
Wink Savillee9b06d72009-05-18 21:47:50 -0700399 mSignalStrength = new SignalStrength();
Dianne Hackborn4840e142009-03-24 22:40:29 -0700400 mBatteryStats = BatteryStatsService.getService();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401
402 // clock
403 mCalendar = Calendar.getInstance(TimeZone.getDefault());
404 mClockData = IconData.makeText("clock", "");
405 mClockIcon = service.addIcon(mClockData, null);
406 updateClock();
407
408 // battery
409 mBatteryData = IconData.makeIcon("battery",
410 null, com.android.internal.R.drawable.stat_sys_battery_unknown, 0, 0);
411 mBatteryIcon = service.addIcon(mBatteryData, null);
412
413 // phone_signal
414 mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Wink Savillee9b06d72009-05-18 21:47:50 -0700415 mPhoneData = IconData.makeIcon("phone_signal",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0);
417 mPhoneIcon = service.addIcon(mPhoneData, null);
Wink Savillee9b06d72009-05-18 21:47:50 -0700418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 // register for phone state notifications.
420 ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
421 .listen(mPhoneStateListener,
422 PhoneStateListener.LISTEN_SERVICE_STATE
Wink Savillee9b06d72009-05-18 21:47:50 -0700423 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 | PhoneStateListener.LISTEN_CALL_STATE
425 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
426 | PhoneStateListener.LISTEN_DATA_ACTIVITY);
427
428 // data_connection
429 mDataData = IconData.makeIcon("data_connection",
430 null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0);
431 mDataIcon = service.addIcon(mDataData, null);
432 service.setIconVisibility(mDataIcon, false);
433
434 // wifi
435 mWifiData = IconData.makeIcon("wifi", null, sWifiSignalImages[0], 0, 0);
436 mWifiIcon = service.addIcon(mWifiData, null);
437 service.setIconVisibility(mWifiIcon, false);
438 // wifi will get updated by the sticky intents
Wink Saville04e71b32009-04-02 11:00:54 -0700439
440 // TTY status
441 mTTYModeEnableIconData = IconData.makeIcon("tty",
442 null, com.android.internal.R.drawable.stat_sys_tty_mode, 0, 0);
443 mTTYModeIcon = service.addIcon(mTTYModeEnableIconData, null);
444 service.setIconVisibility(mTTYModeIcon, false);
445
Wink Savillee9b06d72009-05-18 21:47:50 -0700446 // Cdma Roaming Indicator, ERI
447 mCdmaRoamingIndicatorIconData = IconData.makeIcon("cdma_eri",
448 null, com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 0, 0);
449 mCdmaRoamingIndicatorIcon = service.addIcon(mCdmaRoamingIndicatorIconData, null);
450 service.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 // bluetooth status
453 mBluetoothData = IconData.makeIcon("bluetooth",
454 null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
455 mBluetoothIcon = service.addIcon(mBluetoothData, null);
Nick Pellyf242b7b2009-10-08 00:12:45 +0200456 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Nick Pellybd022f42009-08-14 18:33:38 -0700457 if (adapter != null) {
458 mBluetoothEnabled = adapter.isEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 } else {
460 mBluetoothEnabled = false;
461 }
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800462 mBluetoothA2dpConnected = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
Jiafa Liu3f416732009-07-02 16:36:02 +0800464 mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled);
466
467 // Gps status
468 mGpsEnabledIconData = IconData.makeIcon("gps",
469 null, com.android.internal.R.drawable.stat_sys_gps_acquiring_anim, 0, 0);
470 mGpsFixIconData = IconData.makeIcon("gps",
471 null, com.android.internal.R.drawable.stat_sys_gps_on, 0, 0);
472 mGpsIcon = service.addIcon(mGpsEnabledIconData, null);
johnwang347c5a22009-08-24 22:11:11 -0700473 service.setIconVisibility(mGpsIcon, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474
475 // Alarm clock
476 mAlarmClockIconData = IconData.makeIcon(
477 "alarm_clock",
478 null, com.android.internal.R.drawable.stat_notify_alarm, 0, 0);
479 mAlarmClockIcon = service.addIcon(mAlarmClockIconData, null);
480 service.setIconVisibility(mAlarmClockIcon, false);
481
482 // Sync state
483 mSyncActiveIcon = service.addIcon(IconData.makeIcon("sync_active",
484 null, R.drawable.stat_notify_sync_anim0, 0, 0), null);
485 mSyncFailingIcon = service.addIcon(IconData.makeIcon("sync_failing",
486 null, R.drawable.stat_notify_sync_error, 0, 0), null);
487 service.setIconVisibility(mSyncActiveIcon, false);
488 service.setIconVisibility(mSyncFailingIcon, false);
489
490 // volume
491 mVolumeData = IconData.makeIcon("volume",
492 null, com.android.internal.R.drawable.stat_sys_ringer_silent, 0, 0);
493 mVolumeIcon = service.addIcon(mVolumeData, null);
494 service.setIconVisibility(mVolumeIcon, false);
495 updateVolume();
johnwang347c5a22009-08-24 22:11:11 -0700496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 IntentFilter filter = new IntentFilter();
498
499 // Register for Intent broadcasts for...
500 filter.addAction(Intent.ACTION_TIME_TICK);
501 filter.addAction(Intent.ACTION_TIME_CHANGED);
502 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
503 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
Mihai Predaa82842f2009-04-29 15:05:56 +0200504 filter.addAction(Intent.ACTION_BATTERY_LOW);
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700505 filter.addAction(Intent.ACTION_BATTERY_OKAY);
Mike Lockwood69eb0bf2009-08-01 23:02:28 -0400506 filter.addAction(Intent.ACTION_POWER_CONNECTED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
508 filter.addAction(Intent.ACTION_ALARM_CHANGED);
509 filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
510 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
511 filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
Nick Pellyde893f52009-09-08 13:15:33 -0700512 filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
Nick Pelly005b2282009-09-10 10:21:56 -0700513 filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
514 filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
Jiafa Liu3f416732009-07-02 16:36:02 +0800515 filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
517 filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
518 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
519 filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
520 filter.addAction(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION);
521 filter.addAction(GpsLocationProvider.GPS_FIX_CHANGE_ACTION);
522 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Wink Saville04e71b32009-04-02 11:00:54 -0700523 filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
John Wang33e21fc2009-10-08 10:35:27 -0700525
526 // load config to determine if to distinguish Hspa data icon
527 try {
528 mHspaDataDistinguishable = mContext.getResources().getBoolean(
529 com.android.internal.R.bool.config_hspa_data_distinguishable);
530 } catch (Exception e) {
531 mHspaDataDistinguishable = false;
532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 }
534
535 public static void installIcons(Context context, StatusBarService service) {
536 sInstance = new StatusBarPolicy(context, service);
537 }
538
Eric Fischer36e136c2010-01-14 17:42:48 -0800539 private final CharSequence getSmallTime() {
540 boolean b24 = DateFormat.is24HourFormat(mContext);
541 int res;
542
543 if (b24) {
544 res = R.string.twenty_four_hour_time_format;
545 } else {
546 res = R.string.twelve_hour_time_format;
547 }
548
549 String format = mContext.getString(res);
550
551 /*
552 * Search for an unquoted "a" in the format string, so we can
553 * add dummy characters around it to let us find it again after
554 * formatting and change its size.
555 */
556 int a = -1;
557 boolean quoted = false;
558 for (int i = 0; i < format.length(); i++) {
559 char c = format.charAt(i);
560
561 if (c == '\'') {
562 quoted = !quoted;
563 }
564
565 if (!quoted && c == 'a') {
566 a = i;
567 break;
568 }
569 }
570
571 final char MAGIC1 = '\uEF00';
572 final char MAGIC2 = '\uEF01';
573
574 if (a >= 0) {
575 format = format.substring(0, a) + MAGIC1 + "a" + MAGIC2 +
576 format.substring(a + 1);
577 }
578
579 String result = new SimpleDateFormat(format).format(mCalendar.getTime());
580
581 int magic1 = result.indexOf(MAGIC1);
582 int magic2 = result.indexOf(MAGIC2);
583
584 if (magic1 >= 0 && magic2 > magic1) {
585 SpannableStringBuilder formatted = new SpannableStringBuilder(result);
586
587 formatted.setSpan(new RelativeSizeSpan(0.7f), magic1, magic2,
588 Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
589
590 formatted.delete(magic2, magic2 + 1);
591 formatted.delete(magic1, magic1 + 1);
592
593 return formatted;
594 } else {
595 return result;
596 }
597 }
598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 private final void updateClock() {
600 mCalendar.setTimeInMillis(System.currentTimeMillis());
Eric Fischer36e136c2010-01-14 17:42:48 -0800601 mClockData.text = getSmallTime();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 mService.updateIcon(mClockIcon, mClockData, null);
603 }
604
605 private final void updateAlarm(Intent intent) {
606 boolean alarmSet = intent.getBooleanExtra("alarmSet", false);
607 mService.setIconVisibility(mAlarmClockIcon, alarmSet);
608 }
609
610 private final void updateSyncState(Intent intent) {
611 boolean isActive = intent.getBooleanExtra("active", false);
612 boolean isFailing = intent.getBooleanExtra("failing", false);
613 mService.setIconVisibility(mSyncActiveIcon, isActive);
614 // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
615 //mService.setIconVisibility(mSyncFailingIcon, isFailing && !isActive);
616 }
617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 private final void updateBattery(Intent intent) {
619 mBatteryData.iconId = intent.getIntExtra("icon-small", 0);
620 mBatteryData.iconLevel = intent.getIntExtra("level", 0);
621 mService.updateIcon(mBatteryIcon, mBatteryData, null);
622
623 boolean plugged = intent.getIntExtra("plugged", 0) != 0;
624 int level = intent.getIntExtra("level", -1);
625 if (false) {
626 Log.d(TAG, "updateBattery level=" + level
627 + " plugged=" + plugged
628 + " mBatteryPlugged=" + mBatteryPlugged
629 + " mBatteryLevel=" + mBatteryLevel
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 + " mBatteryFirst=" + mBatteryFirst);
631 }
632
633 boolean oldPlugged = mBatteryPlugged;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634
635 mBatteryPlugged = plugged;
636 mBatteryLevel = level;
637
638 if (mBatteryFirst) {
639 mBatteryFirst = false;
640 }
641 /*
642 * No longer showing the battery view because it draws attention away
643 * from the USB storage notification. We could still show it when
644 * connected to a brick, but that could lead to the user into thinking
645 * the device does not charge when plugged into USB (since he/she would
646 * not see the same battery screen on USB as he sees on brick).
647 */
648 /* else {
649 if (plugged && !oldPlugged) {
650 showBatteryView();
651 }
652 }
653 */
654 if (false) {
Mihai Predaa82842f2009-04-29 15:05:56 +0200655 Log.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 }
Mihai Predaa82842f2009-04-29 15:05:56 +0200657 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658
Mihai Predaa82842f2009-04-29 15:05:56 +0200659 private void onBatteryLow(Intent intent) {
660 if (SHOW_LOW_BATTERY_WARNING) {
661 if (false) {
662 Log.d(TAG, "mPhoneState=" + mPhoneState
663 + " mLowBatteryDialog=" + mLowBatteryDialog
664 + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 }
Mihai Predaa82842f2009-04-29 15:05:56 +0200666
667 if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
668 showLowBatteryWarning();
669 } else {
670 mBatteryShowLowOnEndCall = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 }
672 }
673 }
674
Dianne Hackborn8ec5b832009-07-01 21:19:35 -0700675 private void onBatteryOkay(Intent intent) {
676 if (mLowBatteryDialog != null
677 && SHOW_LOW_BATTERY_WARNING) {
678 mLowBatteryDialog.dismiss();
679 mBatteryShowLowOnEndCall = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 }
681 }
682
johnwang347c5a22009-08-24 22:11:11 -0700683 private void showBatteryView() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 closeLastBatteryView();
685 if (mLowBatteryDialog != null) {
686 mLowBatteryDialog.dismiss();
687 }
688
689 int level = mBatteryLevel;
690
691 View v = View.inflate(mContext, com.android.internal.R.layout.battery_status, null);
692 mBatteryView = v;
693 int pixelFormat = PixelFormat.TRANSLUCENT;
694 Drawable bg = v.getBackground();
695 if (bg != null) {
696 pixelFormat = bg.getOpacity();
697 }
698
Dianne Hackborn568cae52009-10-07 16:13:39 -0700699 int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
700 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
701 | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800702
Dianne Hackborn568cae52009-10-07 16:13:39 -0700703 if (!mContext.getResources().getBoolean(
704 com.android.internal.R.bool.config_sf_slowBlur)) {
705 flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
706 }
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
709 ViewGroup.LayoutParams.WRAP_CONTENT,
710 ViewGroup.LayoutParams.WRAP_CONTENT,
711 WindowManager.LayoutParams.TYPE_TOAST,
Dianne Hackborn568cae52009-10-07 16:13:39 -0700712 flags, pixelFormat);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713
714 // Get the dim amount from the theme
715 TypedArray a = mContext.obtainStyledAttributes(
716 com.android.internal.R.styleable.Theme);
717 lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f);
718 a.recycle();
Wink Saville04e71b32009-04-02 11:00:54 -0700719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 lp.setTitle("Battery");
721
722 TextView levelTextView = (TextView)v.findViewById(com.android.internal.R.id.level_percent);
723 levelTextView.setText(mContext.getString(
724 com.android.internal.R.string.battery_status_text_percent_format, level));
725
726 setBatteryLevel(v, com.android.internal.R.id.spacer, 100-level, 0, 0);
727 setBatteryLevel(v, com.android.internal.R.id.level, level,
728 com.android.internal.R.drawable.battery_charge_fill, level);
729
730 WindowManagerImpl.getDefault().addView(v, lp);
731
732 scheduleCloseBatteryView();
733 }
734
735 private void setBatteryLevel(View parent, int id, int height, int background, int level) {
736 ImageView v = (ImageView)parent.findViewById(id);
737 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams();
738 lp.weight = height;
739 if (background != 0) {
740 v.setBackgroundResource(background);
741 Drawable bkg = v.getBackground();
742 bkg.setLevel(level);
743 }
744 }
745
746 private void showLowBatteryWarning() {
747 closeLastBatteryView();
748
Mike Lockwoodd81b1f42009-09-25 09:32:19 -0400749 // Show exact battery level.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 CharSequence levelText = mContext.getString(
Mike Lockwoodd81b1f42009-09-25 09:32:19 -0400751 com.android.internal.R.string.battery_low_percent_format, mBatteryLevel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752
753 if (mBatteryLevelTextView != null) {
754 mBatteryLevelTextView.setText(levelText);
755 } else {
756 View v = View.inflate(mContext, com.android.internal.R.layout.battery_low, null);
757 mBatteryLevelTextView=(TextView)v.findViewById(com.android.internal.R.id.level_percent);
758
759 mBatteryLevelTextView.setText(levelText);
760
761 AlertDialog.Builder b = new AlertDialog.Builder(mContext);
762 b.setCancelable(true);
763 b.setTitle(com.android.internal.R.string.battery_low_title);
764 b.setView(v);
765 b.setIcon(android.R.drawable.ic_dialog_alert);
766 b.setPositiveButton(android.R.string.ok, null);
johnwang347c5a22009-08-24 22:11:11 -0700767
Dianne Hackborn3d74bb42009-06-19 10:35:21 -0700768 final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
769 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
770 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
771 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
772 | Intent.FLAG_ACTIVITY_NO_HISTORY);
773 if (intent.resolveActivity(mContext.getPackageManager()) != null) {
774 b.setNegativeButton(com.android.internal.R.string.battery_low_why,
775 new DialogInterface.OnClickListener() {
776 public void onClick(DialogInterface dialog, int which) {
777 mContext.startActivity(intent);
778 if (mLowBatteryDialog != null) {
779 mLowBatteryDialog.dismiss();
780 }
781 }
782 });
783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784
785 AlertDialog d = b.create();
786 d.setOnDismissListener(mLowBatteryListener);
787 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
788 d.show();
789 mLowBatteryDialog = d;
790 }
791 }
792
793 private final void updateCallState(int state) {
794 mPhoneState = state;
795 if (false) {
796 Log.d(TAG, "mPhoneState=" + mPhoneState
797 + " mLowBatteryDialog=" + mLowBatteryDialog
798 + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
799 }
800 if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
801 if (mBatteryShowLowOnEndCall) {
802 if (!mBatteryPlugged) {
803 showLowBatteryWarning();
804 }
805 mBatteryShowLowOnEndCall = false;
806 }
807 } else {
808 if (mLowBatteryDialog != null) {
809 mLowBatteryDialog.dismiss();
810 mBatteryShowLowOnEndCall = true;
811 }
812 }
813 }
814
815 private DialogInterface.OnDismissListener mLowBatteryListener
816 = new DialogInterface.OnDismissListener() {
817 public void onDismiss(DialogInterface dialog) {
818 mLowBatteryDialog = null;
819 mBatteryLevelTextView = null;
820 }
821 };
822
823 private void scheduleCloseBatteryView() {
824 Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE);
825 m.arg1 = (++mBatteryViewSequence);
826 mHandler.sendMessageDelayed(m, 3000);
827 }
828
829 private void closeLastBatteryView() {
830 if (mBatteryView != null) {
831 //mBatteryView.debug();
832 WindowManagerImpl.getDefault().removeView(mBatteryView);
833 mBatteryView = null;
834 }
835 }
836
837 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
838 @Override
Wink Savillee9b06d72009-05-18 21:47:50 -0700839 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
840 mSignalStrength = signalStrength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 updateSignalStrength();
842 }
843
844 @Override
845 public void onServiceStateChanged(ServiceState state) {
846 mServiceState = state;
847 updateSignalStrength();
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700848 updateCdmaRoamingIcon(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 updateDataIcon();
850 }
851
852 @Override
853 public void onCallStateChanged(int state, String incomingNumber) {
854 updateCallState(state);
johnwang347c5a22009-08-24 22:11:11 -0700855 // In cdma, if a voice call is made, RSSI should switch to 1x.
856 if (isCdma()) {
857 updateSignalStrength();
858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 }
860
861 @Override
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700862 public void onDataConnectionStateChanged(int state, int networkType) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 mDataState = state;
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700864 updateDataNetType(networkType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 updateDataIcon();
866 }
867
868 @Override
869 public void onDataActivity(int direction) {
870 mDataActivity = direction;
871 updateDataIcon();
872 }
873 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874
875 private final void updateSimState(Intent intent) {
Wink Saville04e71b32009-04-02 11:00:54 -0700876 String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
877 if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
878 mSimState = IccCard.State.ABSENT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 }
Wink Saville04e71b32009-04-02 11:00:54 -0700880 else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
881 mSimState = IccCard.State.READY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 }
Wink Saville04e71b32009-04-02 11:00:54 -0700883 else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
884 final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
885 if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
886 mSimState = IccCard.State.PIN_REQUIRED;
johnwang347c5a22009-08-24 22:11:11 -0700887 }
Wink Saville04e71b32009-04-02 11:00:54 -0700888 else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
889 mSimState = IccCard.State.PUK_REQUIRED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 }
891 else {
Wink Saville04e71b32009-04-02 11:00:54 -0700892 mSimState = IccCard.State.NETWORK_LOCKED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 }
894 } else {
Wink Saville04e71b32009-04-02 11:00:54 -0700895 mSimState = IccCard.State.UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 }
897 updateDataIcon();
898 }
899
Wink Savillee9b06d72009-05-18 21:47:50 -0700900 private boolean isCdma() {
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700901 return (mSignalStrength != null) && !mSignalStrength.isGsm();
Wink Savillee9b06d72009-05-18 21:47:50 -0700902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903
johnwang347c5a22009-08-24 22:11:11 -0700904 private boolean isEvdo() {
905 return ( (mServiceState != null)
906 && ((mServiceState.getRadioTechnology()
907 == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
908 || (mServiceState.getRadioTechnology()
909 == ServiceState.RADIO_TECHNOLOGY_EVDO_A)));
910 }
911
Wink Savillee9b06d72009-05-18 21:47:50 -0700912 private boolean hasService() {
913 if (mServiceState != null) {
914 switch (mServiceState.getState()) {
915 case ServiceState.STATE_OUT_OF_SERVICE:
916 case ServiceState.STATE_POWER_OFF:
917 return false;
918 default:
919 return true;
920 }
921 } else {
922 return false;
923 }
924 }
925
926 private final void updateSignalStrength() {
927 int iconLevel = -1;
Wink Savillee9b06d72009-05-18 21:47:50 -0700928 int[] iconList;
Wink Savillee9b06d72009-05-18 21:47:50 -0700929
930 if (!hasService()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 //Log.d(TAG, "updateSignalStrength: no service");
932 if (Settings.System.getInt(mContext.getContentResolver(),
933 Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
934 mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_flightmode;
935 } else {
936 mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_null;
937 }
938 mService.updateIcon(mPhoneIcon, mPhoneData, null);
939 return;
940 }
941
Wink Savillee9b06d72009-05-18 21:47:50 -0700942 if (!isCdma()) {
943 int asu = mSignalStrength.getGsmSignalStrength();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944
Wink Savillee9b06d72009-05-18 21:47:50 -0700945 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
946 // asu = 0 (-113dB or less) is very weak
947 // signal, its better to show 0 bars to the user in such cases.
948 // asu = 99 is a special case, where the signal strength is unknown.
949 if (asu <= 0 || asu == 99) iconLevel = 0;
950 else if (asu >= 16) iconLevel = 4;
951 else if (asu >= 8) iconLevel = 3;
952 else if (asu >= 4) iconLevel = 2;
953 else iconLevel = 1;
954
Robert Greenwalt98e0b142009-10-08 21:15:52 -0700955 // Though mPhone is a Manager, this call is not an IPC
Wink Savillee9b06d72009-05-18 21:47:50 -0700956 if (mPhone.isNetworkRoaming()) {
957 iconList = sSignalImages_r;
958 } else {
959 iconList = sSignalImages;
Wink Saville04e71b32009-04-02 11:00:54 -0700960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 } else {
johnwang347c5a22009-08-24 22:11:11 -0700962 iconList = this.sSignalImages;
Wink Savillee9b06d72009-05-18 21:47:50 -0700963
johnwang347c5a22009-08-24 22:11:11 -0700964 // If 3G(EV) and 1x network are available than 3G should be
965 // displayed, displayed RSSI should be from the EV side.
966 // If a voice call is made then RSSI should switch to 1x.
967 if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
968 iconLevel = getEvdoLevel();
969 if (false) {
970 Log.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel());
971 }
972 } else {
973 iconLevel = getCdmaLevel();
974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700976 mPhoneData.iconId = iconList[iconLevel];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 mService.updateIcon(mPhoneIcon, mPhoneData, null);
978 }
979
johnwang347c5a22009-08-24 22:11:11 -0700980 private int getCdmaLevel() {
981 final int cdmaDbm = mSignalStrength.getCdmaDbm();
982 final int cdmaEcio = mSignalStrength.getCdmaEcio();
983 int levelDbm = 0;
984 int levelEcio = 0;
985
986 if (cdmaDbm >= -75) levelDbm = 4;
987 else if (cdmaDbm >= -85) levelDbm = 3;
988 else if (cdmaDbm >= -95) levelDbm = 2;
989 else if (cdmaDbm >= -100) levelDbm = 1;
990 else levelDbm = 0;
991
992 // Ec/Io are in dB*10
993 if (cdmaEcio >= -90) levelEcio = 4;
994 else if (cdmaEcio >= -110) levelEcio = 3;
995 else if (cdmaEcio >= -130) levelEcio = 2;
996 else if (cdmaEcio >= -150) levelEcio = 1;
997 else levelEcio = 0;
998
999 return (levelDbm < levelEcio) ? levelDbm : levelEcio;
1000 }
1001
1002 private int getEvdoLevel() {
1003 int evdoDbm = mSignalStrength.getEvdoDbm();
1004 int evdoSnr = mSignalStrength.getEvdoSnr();
1005 int levelEvdoDbm = 0;
1006 int levelEvdoSnr = 0;
1007
1008 if (evdoDbm >= -65) levelEvdoDbm = 4;
1009 else if (evdoDbm >= -75) levelEvdoDbm = 3;
1010 else if (evdoDbm >= -90) levelEvdoDbm = 2;
1011 else if (evdoDbm >= -105) levelEvdoDbm = 1;
1012 else levelEvdoDbm = 0;
1013
John Michelau1336a562009-09-28 10:41:02 -05001014 if (evdoSnr >= 7) levelEvdoSnr = 4;
1015 else if (evdoSnr >= 5) levelEvdoSnr = 3;
1016 else if (evdoSnr >= 3) levelEvdoSnr = 2;
1017 else if (evdoSnr >= 1) levelEvdoSnr = 1;
johnwang347c5a22009-08-24 22:11:11 -07001018 else levelEvdoSnr = 0;
1019
1020 return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
1021 }
1022
Robert Greenwalt98e0b142009-10-08 21:15:52 -07001023 private final void updateDataNetType(int net) {
Wink Saville04e71b32009-04-02 11:00:54 -07001024
1025 switch (net) {
Wink Saville04e71b32009-04-02 11:00:54 -07001026 case TelephonyManager.NETWORK_TYPE_EDGE:
1027 mDataIconList = sDataNetType_e;
1028 break;
1029 case TelephonyManager.NETWORK_TYPE_UMTS:
1030 mDataIconList = sDataNetType_3g;
1031 break;
Li Zheebe66342009-08-14 19:22:16 +08001032 case TelephonyManager.NETWORK_TYPE_HSDPA:
1033 case TelephonyManager.NETWORK_TYPE_HSUPA:
1034 case TelephonyManager.NETWORK_TYPE_HSPA:
John Wang33e21fc2009-10-08 10:35:27 -07001035 if (mHspaDataDistinguishable) {
1036 mDataIconList = sDataNetType_h;
1037 } else {
1038 mDataIconList = sDataNetType_3g;
1039 }
Li Zheebe66342009-08-14 19:22:16 +08001040 break;
Wink Saville04e71b32009-04-02 11:00:54 -07001041 case TelephonyManager.NETWORK_TYPE_CDMA:
1042 // display 1xRTT for IS95A/B
johnwang9f87cb22009-08-25 15:25:37 -07001043 mDataIconList = this.sDataNetType_1x;
Wink Saville04e71b32009-04-02 11:00:54 -07001044 break;
1045 case TelephonyManager.NETWORK_TYPE_1xRTT:
johnwang9f87cb22009-08-25 15:25:37 -07001046 mDataIconList = this.sDataNetType_1x;
Wink Saville04e71b32009-04-02 11:00:54 -07001047 break;
1048 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
1049 case TelephonyManager.NETWORK_TYPE_EVDO_A:
johnwang9f87cb22009-08-25 15:25:37 -07001050 mDataIconList = sDataNetType_3g;
Wink Saville04e71b32009-04-02 11:00:54 -07001051 break;
1052 default:
1053 mDataIconList = sDataNetType_g;
1054 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 }
1056 }
1057
1058 private final void updateDataIcon() {
1059 int iconId;
1060 boolean visible = true;
1061
Wink Savillee9b06d72009-05-18 21:47:50 -07001062 if (!isCdma()) {
1063 // GSM case, we have to check also the sim state
1064 if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
1065 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
1066 switch (mDataActivity) {
1067 case TelephonyManager.DATA_ACTIVITY_IN:
1068 iconId = mDataIconList[1];
1069 break;
1070 case TelephonyManager.DATA_ACTIVITY_OUT:
1071 iconId = mDataIconList[2];
1072 break;
1073 case TelephonyManager.DATA_ACTIVITY_INOUT:
1074 iconId = mDataIconList[3];
1075 break;
1076 default:
1077 iconId = mDataIconList[0];
1078 break;
1079 }
1080 mDataData.iconId = iconId;
1081 mService.updateIcon(mDataIcon, mDataData, null);
1082 } else {
1083 visible = false;
1084 }
1085 } else {
1086 mDataData.iconId = com.android.internal.R.drawable.stat_sys_no_sim;
1087 mService.updateIcon(mDataIcon, mDataData, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001089 } else {
1090 // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
1091 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 switch (mDataActivity) {
1093 case TelephonyManager.DATA_ACTIVITY_IN:
Wink Savillee9b06d72009-05-18 21:47:50 -07001094 iconId = mDataIconList[1];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 break;
1096 case TelephonyManager.DATA_ACTIVITY_OUT:
Wink Savillee9b06d72009-05-18 21:47:50 -07001097 iconId = mDataIconList[2];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 break;
1099 case TelephonyManager.DATA_ACTIVITY_INOUT:
Wink Savillee9b06d72009-05-18 21:47:50 -07001100 iconId = mDataIconList[3];
1101 break;
1102 case TelephonyManager.DATA_ACTIVITY_DORMANT:
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 default:
Wink Savillee9b06d72009-05-18 21:47:50 -07001104 iconId = mDataIconList[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 break;
1106 }
1107 mDataData.iconId = iconId;
1108 mService.updateIcon(mDataIcon, mDataData, null);
1109 } else {
1110 visible = false;
1111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001113
Dianne Hackborn4840e142009-03-24 22:40:29 -07001114 long ident = Binder.clearCallingIdentity();
1115 try {
Wink Saville04e71b32009-04-02 11:00:54 -07001116 mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
Dianne Hackborn4840e142009-03-24 22:40:29 -07001117 } catch (RemoteException e) {
1118 } finally {
1119 Binder.restoreCallingIdentity(ident);
1120 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 if (mDataIconVisible != visible) {
1123 mService.setIconVisibility(mDataIcon, visible);
1124 mDataIconVisible = visible;
1125 }
1126 }
1127
1128 private final void updateVolume() {
1129 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
1130 final int ringerMode = audioManager.getRingerMode();
1131 final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
Wink Savillee9b06d72009-05-18 21:47:50 -07001132 ringerMode == AudioManager.RINGER_MODE_VIBRATE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001133 final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
1134 ? com.android.internal.R.drawable.stat_sys_ringer_vibrate
1135 : com.android.internal.R.drawable.stat_sys_ringer_silent;
1136
1137 if (visible) {
1138 mVolumeData.iconId = iconId;
1139 mService.updateIcon(mVolumeIcon, mVolumeData, null);
1140 }
1141 if (visible != mVolumeVisible) {
1142 mService.setIconVisibility(mVolumeIcon, visible);
1143 mVolumeVisible = visible;
1144 }
1145 }
1146
1147 private final void updateBluetooth(Intent intent) {
1148 int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 String action = intent.getAction();
Nick Pellyde893f52009-09-08 13:15:33 -07001150 if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
Nick Pellyb24e11b2009-09-08 17:40:43 -07001151 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
Nick Pellyde893f52009-09-08 13:15:33 -07001152 mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
Nick Pelly005b2282009-09-10 10:21:56 -07001153 } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
1154 mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 BluetoothHeadset.STATE_ERROR);
Nick Pelly005b2282009-09-10 10:21:56 -07001156 } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
Jaikumar Ganesh084c6652009-12-07 10:58:18 -08001157 BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
1158 if (a2dp.getConnectedSinks().size() != 0) {
1159 mBluetoothA2dpConnected = true;
1160 } else {
1161 mBluetoothA2dpConnected = false;
1162 }
Jiafa Liu3f416732009-07-02 16:36:02 +08001163 } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
1164 mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
1165 BluetoothPbap.STATE_DISCONNECTED);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 } else {
1167 return;
1168 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001169
Jaikumar Ganesh084c6652009-12-07 10:58:18 -08001170 if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
Jiafa Liu3f416732009-07-02 16:36:02 +08001171 mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001172 iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth_connected;
1173 }
1174
1175 mBluetoothData.iconId = iconId;
1176 mService.updateIcon(mBluetoothIcon, mBluetoothData, null);
1177 mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled);
1178 }
1179
1180 private final void updateWifi(Intent intent) {
1181 final String action = intent.getAction();
1182 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
Wink Savillee9b06d72009-05-18 21:47:50 -07001183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
1185 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
Wink Savillee9b06d72009-05-18 21:47:50 -07001186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 if (!enabled) {
1188 // If disabled, hide the icon. (We show icon when connected.)
1189 mService.setIconVisibility(mWifiIcon, false);
1190 }
Wink Savillee9b06d72009-05-18 21:47:50 -07001191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
1193 final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED,
1194 false);
1195 if (!enabled) {
1196 mService.setIconVisibility(mWifiIcon, false);
1197 }
1198 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
1199
Wink Savillee9b06d72009-05-18 21:47:50 -07001200 final NetworkInfo networkInfo = (NetworkInfo)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
Wink Savillee9b06d72009-05-18 21:47:50 -07001202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 int iconId;
1204 if (networkInfo != null && networkInfo.isConnected()) {
1205 mIsWifiConnected = true;
1206 if (mLastWifiSignalLevel == -1) {
1207 iconId = sWifiSignalImages[0];
1208 } else {
1209 iconId = sWifiSignalImages[mLastWifiSignalLevel];
1210 }
Wink Saville04e71b32009-04-02 11:00:54 -07001211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001212 // Show the icon since wi-fi is connected
1213 mService.setIconVisibility(mWifiIcon, true);
Wink Saville04e71b32009-04-02 11:00:54 -07001214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 } else {
1216 mLastWifiSignalLevel = -1;
1217 mIsWifiConnected = false;
1218 iconId = sWifiSignalImages[0];
1219
1220 // Hide the icon since we're not connected
1221 mService.setIconVisibility(mWifiIcon, false);
1222 }
1223
1224 mWifiData.iconId = iconId;
1225 mService.updateIcon(mWifiIcon, mWifiData, null);
1226 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
1227 final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
1228 int newSignalLevel = WifiManager.calculateSignalLevel(newRssi,
1229 sWifiSignalImages.length);
1230 if (newSignalLevel != mLastWifiSignalLevel) {
1231 mLastWifiSignalLevel = newSignalLevel;
1232 if (mIsWifiConnected) {
1233 mWifiData.iconId = sWifiSignalImages[newSignalLevel];
1234 } else {
1235 mWifiData.iconId = sWifiTemporarilyNotConnectedImage;
1236 }
1237 mService.updateIcon(mWifiIcon, mWifiData, null);
1238 }
1239 }
1240 }
1241
1242 private final void updateGps(Intent intent) {
1243 final String action = intent.getAction();
1244 final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED, false);
1245
1246 if (action.equals(GpsLocationProvider.GPS_FIX_CHANGE_ACTION) && enabled) {
1247 // GPS is getting fixes
1248 mService.updateIcon(mGpsIcon, mGpsFixIconData, null);
Wink Savillee9b06d72009-05-18 21:47:50 -07001249 mService.setIconVisibility(mGpsIcon, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 } else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
1251 // GPS is off
Wink Savillee9b06d72009-05-18 21:47:50 -07001252 mService.setIconVisibility(mGpsIcon, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 } else {
1254 // GPS is on, but not receiving fixes
1255 mService.updateIcon(mGpsIcon, mGpsEnabledIconData, null);
Wink Savillee9b06d72009-05-18 21:47:50 -07001256 mService.setIconVisibility(mGpsIcon, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 }
1258 }
1259
Wink Savillee9b06d72009-05-18 21:47:50 -07001260 private final void updateTTY(Intent intent) {
Wink Saville04e71b32009-04-02 11:00:54 -07001261 final String action = intent.getAction();
1262 final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
1263
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -07001264 if (false) Log.v(TAG, "updateTTY: enabled: " + enabled);
Wink Saville04e71b32009-04-02 11:00:54 -07001265
1266 if (enabled) {
1267 // TTY is on
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -07001268 if (false) Log.v(TAG, "updateTTY: set TTY on");
Wink Saville04e71b32009-04-02 11:00:54 -07001269 mService.updateIcon(mTTYModeIcon, mTTYModeEnableIconData, null);
Wink Savillee9b06d72009-05-18 21:47:50 -07001270 mService.setIconVisibility(mTTYModeIcon, true);
Wink Saville04e71b32009-04-02 11:00:54 -07001271 } else {
1272 // TTY is off
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -07001273 if (false) Log.v(TAG, "updateTTY: set TTY off");
Wink Savillee9b06d72009-05-18 21:47:50 -07001274 mService.setIconVisibility(mTTYModeIcon, false);
Wink Saville04e71b32009-04-02 11:00:54 -07001275 }
1276 }
1277
Robert Greenwalt98e0b142009-10-08 21:15:52 -07001278 private final void updateCdmaRoamingIcon(ServiceState state) {
Wink Savillee9b06d72009-05-18 21:47:50 -07001279 if (!hasService()) {
1280 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
Wink Savillef3152382009-06-01 14:39:20 -07001281 return;
Wink Savillee9b06d72009-05-18 21:47:50 -07001282 }
1283
1284 if (!isCdma()) {
1285 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
Wink Savillef3152382009-06-01 14:39:20 -07001286 return;
Wink Savillee9b06d72009-05-18 21:47:50 -07001287 }
1288
1289 int[] iconList = sRoamingIndicatorImages_cdma;
Robert Greenwalt98e0b142009-10-08 21:15:52 -07001290 int iconIndex = state.getCdmaEriIconIndex();
1291 int iconMode = state.getCdmaEriIconMode();
Wink Savillee9b06d72009-05-18 21:47:50 -07001292
1293 if (iconIndex == -1) {
1294 Log.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update");
1295 return;
1296 }
1297
1298 if (iconMode == -1) {
1299 Log.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update");
1300 return;
1301 }
1302
1303 if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -07001304 if (false) Log.v(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon");
Wink Savillee9b06d72009-05-18 21:47:50 -07001305 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
1306 return;
1307 }
1308
1309 switch (iconMode) {
1310 case EriInfo.ROAMING_ICON_MODE_NORMAL:
1311 mCdmaRoamingIndicatorIconData.iconId = iconList[iconIndex];
1312 mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null);
1313 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true);
1314 break;
1315 case EriInfo.ROAMING_ICON_MODE_FLASH:
Wink Savillef3152382009-06-01 14:39:20 -07001316 mCdmaRoamingIndicatorIconData.iconId =
1317 com.android.internal.R.drawable.stat_sys_roaming_cdma_flash;
Wink Savillee9b06d72009-05-18 21:47:50 -07001318 mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null);
Wink Savillef3152382009-06-01 14:39:20 -07001319 mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true);
Wink Savillee9b06d72009-05-18 21:47:50 -07001320 break;
1321
1322 }
1323 mService.updateIcon(mPhoneIcon, mPhoneData, null);
1324 }
1325
1326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 private class StatusBarHandler extends Handler {
1328 @Override
1329 public void handleMessage(Message msg) {
1330 switch (msg.what) {
1331 case EVENT_BATTERY_CLOSE:
1332 if (msg.arg1 == mBatteryViewSequence) {
1333 closeLastBatteryView();
1334 }
1335 break;
1336 }
1337 }
1338 }
1339}